978
+ − 1
.. Copyright © 2014 Greg Ward <greg@gerg.ca>
+ − 2
+ − 3
------------------
+ − 4
Evolve: User Guide
+ − 5
------------------
+ − 6
+ − 7
.. contents ::
+ − 8
+ − 9
Life without ``evolve``
+ − 10
-----------------------
+ − 11
+ − 12
Before we dive into learning about ``evolve`` , let's look into some
+ − 13
features of core Mercurial that interact with ``evolve`` . ``commit``
+ − 14
affects ``evolve`` , and ``evolve`` modifies how ``commit --amend``
+ − 15
works.
+ − 16
+ − 17
Example 1: Commit a new changeset
+ − 18
=================================
+ − 19
+ − 20
To create a new changeset, simply run ``hg commit`` as usual.
+ − 21
``evolve`` does not change the behaviour of ``commit`` at all.
+ − 22
+ − 23
However, it's important to understand that new changesets are in the
+ − 24
*draft* phase by default: they are mutable. This means that they can
+ − 25
be modified by Mercurial's existing history-editing commands
+ − 26
(``rebase`` , ``histedit`` , etc.), and also by the ``evolve``
+ − 27
extension. Specifically, ``evolve`` adds a number of commands that can
+ − 28
be used to modify history: ``amend`` , ``uncommit`` , ``prune`` ,
+ − 29
``fold`` , and ``evolve`` . Generally speaking, changesets remain in
+ − 30
*draft* phase until they are pushed to another repository, at which
+ − 31
point they enter *public* phase. ::
+ − 32
+ − 33
$ hg commit -m 'implement feature X'
+ − 34
$ hg phase -r .
+ − 35
1: draft
+ − 36
+ − 37
(Strictly speaking, changesets only become public when they are pushed
+ − 38
to a *publishing* repository. But all repositories are publishing by
+ − 39
default; you have to explicitly configure repositories to be
+ − 40
*non-publishing* . Non-publishing repositories are an advanced topic
+ − 41
which we'll see when we get to `sharing mutable history`_ .)
+ − 42
+ − 43
.. _`sharing mutable history`: sharing.html
+ − 44
+ − 45
Example 2: Amend a changeset (traditional)
+ − 46
==========================================
+ − 47
+ − 48
Imagine you've just committed a new changeset, and then you discover a
+ − 49
mistake. Maybe you forgot to run the tests and a failure slipped in.
+ − 50
You want to modify history so that you push one perfect changeset,
+ − 51
rather than one flawed changeset followed by an "oops" commit. (Or
+ − 52
perhaps you made a typo in the commit message—this is really feature
+ − 53
*Y* , not feature X. You can't fix that with a followup commit.)
+ − 54
+ − 55
This is actually trivial with plain vanilla Mercurial since 2.2: fix
+ − 56
your mistake and run ::
+ − 57
+ − 58
$ hg commit --amend -m 'implement feature Y'
+ − 59
+ − 60
to create a new, amended changeset. The drawback of doing this with
+ − 61
vanilla Mercurial is that your original, flawed, changeset is removed
+ − 62
from the repository. This is *unsafe* history editing. It's probably
+ − 63
not too serious if all you did was fix a syntax error, but still.
+ − 64
+ − 65
.. figure :: figures/figure-ug01.svg
+ − 66
+ − 67
Figure 1: unsafe history modification with core Mercurial (not
+ − 68
using ``evolve`` ): the original revision 1 is destroyed.
+ − 69
+ − 70
(Incidentally, Mercurial's traditional history modification mechanism
+ − 71
isn't *really* unsafe: any changeset(s) removed from the repository
+ − 72
are kept in a backup directory, so you can manually restore them later
+ − 73
if you change your mind. But it's awkward and inconvenient compared to
+ − 74
the features provided by ``evolve`` and changeset obsolescence.)
+ − 75
+ − 76
Life with ``evolve`` (basic usage)
+ − 77
----------------------------------
+ − 78
+ − 79
Once you enable the ``evolve`` extension, a number of features are
+ − 80
available to you. First, we're going to explore several examples of
+ − 81
painless, trouble-free history modification.
+ − 82
+ − 83
Example 3: Amend a changeset (with ``evolve``)
+ − 84
==============================================
+ − 85
+ − 86
Outwardly, amending a changeset with ``evolve`` can look exactly the
+ − 87
same as it does with core Mercurial (example 2)::
+ − 88
+ − 89
$ hg commit --amend -m 'implement feature Y'
+ − 90
+ − 91
Alternately, you can use the new ``amend`` command added by
+ − 92
``evolve`` ::
+ − 93
+ − 94
$ hg amend -m 'implement feature Y'
+ − 95
+ − 96
(``hg amend`` is nearly synonymous with ``hg commit --amend`` . The
+ − 97
difference is that ``hg amend`` reuses the existing commit message by
+ − 98
default, whereas ``hg commit --amend`` runs your editor if you don't
+ − 99
pass ``-m`` or ``-l`` .)
+ − 100
+ − 101
Under the hood, though, things are quite different. Mercurial has
+ − 102
simply marked the old changeset *obsolete* , replacing it with a new
+ − 103
one. We'll explore what this means in detail later, after working
+ − 104
through a few more examples.
+ − 105
+ − 106
Example 4: Prune an unwanted changeset
+ − 107
======================================
+ − 108
+ − 109
Sometimes you make a change, and then decide it was such a bad idea
+ − 110
that you don't want anyone to know about it. Or maybe it was a
+ − 111
debugging hack that you needed to keep around for a while, but do not
+ − 112
intend to ever push publicly. ::
+ − 113
+ − 114
$ echo 'debug hack' >> file1.c
+ − 115
$ hg commit -m 'debug hack'
+ − 116
+ − 117
In either case, ``hg prune`` is the answer. ``prune`` simply marks
+ − 118
changesets obsolete without creating any new changesets to replace
+ − 119
them::
+ − 120
+ − 121
$ hg prune .
+ − 122
1 changesets pruned
+ − 123
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ − 124
working directory now at 934359450037
+ − 125
+ − 126
Outwardly, it appears that your “debug hack” commit never happened;
+ − 127
we're right back where we started::
+ − 128
+ − 129
$ hg parents --template '{rev}:{node|short} {desc|firstline}\n'
+ − 130
3:934359450037 implement feature Y
+ − 131
+ − 132
In reality, though, the “debug hack” is still there, obsolete and hidden.
+ − 133
+ − 134
Example 5: Uncommit changes to certain files
+ − 135
============================================
+ − 136
+ − 137
Occasionally you commit more than you intended: perhaps you made
+ − 138
unrelated changes to different files, and thus intend to commit
+ − 139
different files separately. ::
+ − 140
+ − 141
$ echo 'relevant' >> file1.c
+ − 142
$ echo 'irrelevant' >> file2.c
+ − 143
+ − 144
If you forget to specify filenames on the ``commit`` command line,
+ − 145
Mercurial commits all those changes together::
+ − 146
+ − 147
$ hg commit -m 'fix bug 234' # oops: too many files
+ − 148
+ − 149
Luckily, this mistake is easy to fix with ``uncommit`` ::
+ − 150
+ − 151
$ hg uncommit file2.c
+ − 152
$ hg status
+ − 153
M file2.c
+ − 154
+ − 155
Let's verify that the replacement changeset looks right (i.e.,
+ − 156
modifies only ``file1.c`` )::
+ − 157
+ − 158
$ hg parents --template '{rev}:{node|short} {desc|firstline}\n{files}\n'
+ − 159
6:c8defeecf7a4 fix bug 234
+ − 160
file1.c
+ − 161
+ − 162
As before, the original flawed changeset is still there, but obsolete
+ − 163
and hidden. It won't be exchanged with other repositories by ``push`` ,
+ − 164
``pull`` , or ``clone`` .
+ − 165
+ − 166
Example 6: Fold multiple changesets together into one
+ − 167
=====================================================
+ − 168
+ − 169
If you're making extensive changes to fragile source code, you might
+ − 170
commit more frequently than normal so that you can fallback on a
+ − 171
known good state if one step goes badly. ::
+ − 172
+ − 173
$ echo step1 >> file1.c
+ − 174
$ hg commit -m 'step 1' # revision 7
+ − 175
$ echo step2 >> file1.c
+ − 176
$ hg commit -m 'step 2' # revision 8
+ − 177
$ echo step3 >> file2.c
+ − 178
$ hg commit -m 'step 3' # revision 9
+ − 179
+ − 180
At the end of such a sequence, you often end up with a series of small
+ − 181
changesets that are tedious to review individually. It might make more
+ − 182
sense to combine them into a single changeset using the ``fold``
+ − 183
command.
+ − 184
+ − 185
To make sure we pass the right revisions to ``fold`` , let's review the
+ − 186
changesets we just created, from revision 7::
+ − 187
+ − 188
$ hg log --template '{rev}:{node|short} {desc|firstline}\n' -r 7::
+ − 189
7:05e61aab8294 step 1
+ − 190
8:be6d5bc8e4cc step 2
+ − 191
9:35f432d9f7c1 step 3
+ − 192
+ − 193
and fold them::
+ − 194
+ − 195
$ hg fold -m 'fix bug 64' -r 7::
+ − 196
3 changesets folded
+ − 197
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ − 198
+ − 199
This time, Mercurial marks three changesets obsolete, replacing them
+ − 200
all with a single *successor* .
+ − 201
+ − 202
(You might be familiar with this operation under other names, like
+ − 203
*squash* or *collapse* .)
+ − 204
+ − 205
Changeset obsolescence under the hood
+ − 206
-------------------------------------
+ − 207
+ − 208
So far, everything has gone just fine. We haven't run into merge
+ − 209
conflicts or other trouble. Before we start exploring advanced usage
+ − 210
that can run into trouble, let's step back and see what happens when
+ − 211
Mercurial marks changesets obsolete. That will make it much easier to
+ − 212
understand the more advanced use cases we'll see later.
+ − 213
+ − 214
When you have the ``evolve`` extension enabled, all history
+ − 215
modification uses the same underlying mechanism: the original
+ − 216
changesets are marked *obsolete* and replaced by zero or more
+ − 217
*successors* . The obsolete changesets are the *precursors* of their
+ − 218
successors. This applies equally to built-in commands (``commit
+ − 219
--amend`` ), commands added by ``evolve`` (``amend`` , ``prune`` ,
+ − 220
``uncommit`` , ``fold`` ), and even commands provided by other
+ − 221
extensions (``rebase`` , ``histedit`` ).
+ − 222
+ − 223
Another way of looking at it is that obsolescence is second-order
+ − 224
version control, i.e. the history of your history. We'll cover this in
+ − 225
more detail (and mathematical precision) in the `concepts`_ guide.
+ − 226
+ − 227
.. _`concepts`: concepts.html
+ − 228
+ − 229
Under the hood: Amend a changeset
+ − 230
=================================
+ − 231
+ − 232
Consider Example 2, amending a changeset with ``evolve`` . We saw above
+ − 233
that you can do this using the exact same command-line syntax as core
+ − 234
Mercurial, namely ``hg commit --amend`` . But the implementation is
+ − 235
quite different, and Figure 2 shows how.
+ − 236
+ − 237
.. figure :: figures/figure-ug02.svg
+ − 238
+ − 239
Figure 2: safe history modification using ``evolve`` : the original
+ − 240
revision 1 is preserved as an obsolete changeset. (The "temporary
+ − 241
amend commit", marked with T, is an implementation detail stemming
+ − 242
from limitations in Mercurial's current merge machinery. Future
+ − 243
versions of Mercurial will not create them.)
+ − 244
+ − 245
In this case, the obsolete changesets are also *hidden* . That is the
+ − 246
usual end state for obsolete changesets. But many scenarios result in
+ − 247
obsolete changesets that are still visible, which indicates your
+ − 248
history modification work is not yet done. We'll see examples of that
+ − 249
later, when we cover advanced usage.
+ − 250
+ − 251
Seeing hidden changesets
+ − 252
========================
+ − 253
+ − 254
TODO
+ − 255
+ − 256
Under the hood: Prune an unwanted changeset
+ − 257
===========================================
+ − 258
+ − 259
``prune`` (example 4 above) is the simplest history modification
+ − 260
command provided by ``evolve`` . All it does is mark the specified
+ − 261
changeset(s) obsolete, with no successor/precursor relationships
+ − 262
involved. (If the working directory parent was one of the obsolete
+ − 263
changesets, ``prune`` updates back to a suitable ancestor.)
+ − 264
+ − 265
.. figure :: figures/figure-ug03.svg
+ − 266
+ − 267
Figure 3: pruning a changeset marks it obsolete with no successors.
+ − 268
+ − 269
Under the hood: Uncommit changes to certain files
+ − 270
=================================================
+ − 271
+ − 272
In one sense, ``uncommit`` is a simplified version of ``amend`` . Like
+ − 273
``amend`` , it obsoletes one changeset and leaves it with a single
+ − 274
successor. Unlike ``amend`` , there is no ugly "temporary amend commit"
+ − 275
cluttering up the repository.
+ − 276
+ − 277
In another sense, ``uncommit`` is the inverse of ``amend`` : ``amend``
+ − 278
takes any uncommitted changes in the working dir and “adds”
+ − 279
them to the working directory's parent changeset. (In reality, of
+ − 280
course, it creates a successor changeset, marking the original
+ − 281
obsolete.) In contrast, ``uncommit`` takes some changes in the working
+ − 282
directory's parent and moves them to the working dir, creating a new
+ − 283
successor changeset in the process. Figure 4 illustrates.
+ − 284
+ − 285
.. figure :: figures/figure-ug04.svg
+ − 286
+ − 287
Figure 4: uncommit moves some of the changes from the working
+ − 288
directory parent into the working dir, preserving the remaining
+ − 289
changes as a new successor changeset. (N.B. revision 4 is not shown
+ − 290
here because it was marked obsolete in the previous example.)
+ − 291
+ − 292
+ − 293
Under the hood: Fold multiple changesets together into one
+ − 294
==========================================================
+ − 295
+ − 296
The last basic example is folding multiple changesets into one, which
+ − 297
marks multiple changesets obsolete, replacing them all with a single
+ − 298
successor.
+ − 299
+ − 300
.. figure :: figures/figure-ug05.svg
+ − 301
+ − 302
Figure 5: fold combines multiple changesets into a single
+ − 303
successor, marking the original (folded) changesets obsolete.
+ − 304
+ − 305
+ − 306
Obsolete is not hidden
+ − 307
======================
+ − 308
+ − 309
TODO
+ − 310
+ − 311
+ − 312
Understanding revision numbers
+ − 313
==============================
+ − 314
+ − 315
If you're trying these examples on your own, especially using ``hg
+ − 316
log`` without ``--hidden`` , you have probably noticed some funny
+ − 317
business going on with revision numbers: there are now gaps in the
+ − 318
sequence. That's something you don't see with plain vanilla Mercurial;
+ − 319
normally, revision N is always followed by revision N+1.
+ − 320
+ − 321
This is just the visible manifestation of hidden changesets. If
+ − 322
revision 95 is followed by revision 98, that means there are two
+ − 323
hidden changesets, 96 and 97, in between.
+ − 324
+ − 325
Note that changeset IDs are still the permanent, immutable identifier
+ − 326
for changesets. Revision numbers are, as ever, a handy shorthand that
+ − 327
work in your local repository, but cannot be used across repositories.
+ − 328
They also have the useful property of showing when there are hidden
+ − 329
changesets lurking under the covers, which is why this document uses
+ − 330
revision numbers.
+ − 331
+ − 332
+ − 333
Life with ``evolve`` (advanced usage)
+ − 334
-------------------------------------
+ − 335
+ − 336
Now that you've got a solid understanding of how ``evolve`` works in
+ − 337
concert with changeset obsolescence, let's explore some more advanced
+ − 338
scenarios. All of these scenarios will involve *unstable* changesets,
+ − 339
which is an unavoidable consequence of obsolescence. What really sets
+ − 340
``evolve`` apart from other history modification mechanisms is the
+ − 341
fact that it recognizes troubles like unstable changesets and provides
+ − 342
a consistent way for you to get out of trouble.
+ − 343
+ − 344
(Incidentally, there are two other types of trouble that changesets
+ − 345
can get into with ``evolve`` : they may be *divergent* or *bumped* .
+ − 346
Both of those states are more likely to occur when `sharing mutable
+ − 347
history`_, so we won't see them in this user guide.)
+ − 348
+ − 349
.. _`sharing mutable history`: sharing.html
+ − 350
+ − 351
+ − 352
Example 7: Amend an older changeset
+ − 353
===================================
+ − 354
+ − 355
Sometimes you don't notice your mistakes until after you have
+ − 356
committed some new changesets on top of them. ::
+ − 357
+ − 358
$ hg commit -m 'fix bug 17' # rev 11 (mistake here)
+ − 359
$ hg commit -m 'cleanup' # rev 12
+ − 360
$ hg commit -m 'feature 23' # rev 13
+ − 361
+ − 362
Traditionally, your only option is to commit an "oops" changeset that
+ − 363
fixes your mistake. That works, of course, but it makes you look bad:
+ − 364
you made a mistake, and the record of that mistake is recorded in
+ − 365
history for all eternity. (If the mistake was in the commit message,
+ − 366
too bad.)
+ − 367
+ − 368
More subtly, there now exist changesets that are *worse* than what
+ − 369
came before—the code no longer builds, the tests don't pass, or
+ − 370
similar. Anyone reviewing these patches will waste time noticing the
+ − 371
error in the earlier patch, and then the correction later on.
+ − 372
+ − 373
You can avoid all this by amending the bad changeset and *evolving*
+ − 374
subsequent history. Here's how it works, assuming you have just
+ − 375
committed revision 13 and noticed the mistake in revision 11::
+ − 376
+ − 377
$ hg update 11
+ − 378
[...fix mistake...]
+ − 379
$ hg amend
+ − 380
+ − 381
At this point, revision 11 is *obsolete* and revisions 12 and 13—the
+ − 382
descendants of 11—are in a funny state: they are *unstable* .
+ − 383
+ − 384
.. figure :: figures/figure-ug06.svg
+ − 385
+ − 386
Figure 6: amending a changeset with descendants means the amended
+ − 387
changeset is obsolete but remains visible; its non-obsolete
+ − 388
descendants are *unstable* . The temporary amend commit, revision
+ − 389
14, is hidden because it has no non-obsolete descendants.
+ − 390
+ − 391
All non-obsolete descendants of an obsolete changeset are unstable. An
+ − 392
interesting consequence of this is that revision 11 is still visible,
+ − 393
even though it is obsolete. Obsolete changesets with non-obsolete
+ − 394
descendants are not hidden.
+ − 395
+ − 396
The fix is to *evolve* history::
+ − 397
+ − 398
$ hg evolve --all
+ − 399
+ − 400
This is a separate step, not automatically part of ``hg amend`` ,
+ − 401
because there might be conflicts. If your amended changeset modifies a
+ − 402
file that one of its descendants also modified, Mercurial has to fire
+ − 403
up your merge tool to resolve the conflict. More importantly, you have
+ − 404
to switch contexts from "writing code" to "resolving conflicts". That
+ − 405
can be an expensive context switch, so Mercurial lets you decide when
+ − 406
to do it.
+ − 407
+ − 408
The end state, after ``evolve`` finishes, is that the original
+ − 409
revisions (11-13) are obsolete and hidden. Their successor revisions
+ − 410
(15-17) replace them.
+ − 411
+ − 412
.. figure :: figures/figure-ug07.svg
+ − 413
+ − 414
Figure 7: evolve your repository (``hg evolve --all`` ) to take care
+ − 415
of instability. Unstable changesets become obsolete, and are
+ − 416
replaced by successors just like the amended changeset was.
+ − 417
+ − 418
Example 8: Prune an older changeset
+ − 419
===================================
+ − 420
+ − 421
Let's say you've just committed the following changesets::
+ − 422
+ − 423
$ hg commit -m 'useful work' # rev 18
+ − 424
$ hg commit -m 'debug hack' # rev 19
+ − 425
$ hg commit -m 'more work' # rev 20
+ − 426
+ − 427
You want to drop revision 19, but keep 18 and 20. No problem::
+ − 428
+ − 429
$ hg prune 19
+ − 430
1 changesets pruned
+ − 431
1 new unstable changesets
+ − 432
+ − 433
As above, this leaves your repository in a funny intermediate state:
+ − 434
revision 20 is the non-obsolete descendant of obsolete revision 19.
+ − 435
That is, revision 20 is unstable.
+ − 436
+ − 437
.. figure :: figures/figure-ug08.svg
+ − 438
+ − 439
Figure 8: ``hg prune`` marks a changeset obsolete without creating
+ − 440
a successor. Just like with ``hg amend`` , non-obsolete descendants
+ − 441
of the pruned changeset are now unstable.
+ − 442
+ − 443
As before, the solution to unstable changesets is to evolve your
+ − 444
repository::
+ − 445
+ − 446
$ hg evolve --all
+ − 447
+ − 448
This rebases revision 20 on top of 18 as the new revision 21, leaving
+ − 449
19 and 20 obsolete and hidden:
+ − 450
+ − 451
.. figure :: figures/figure-ug09.svg
+ − 452
+ − 453
Figure 9: once again, ``hg evolve --all`` takes care of instability.
+ − 454
+ − 455
Example 9: Uncommit files from an older changeset (discard changes)
+ − 456
=======================================================================
+ − 457
+ − 458
As in example 5, let's say you accidentally commit some unrelated
+ − 459
changes together. Unlike example 5, you don't notice your mistake
+ − 460
immediately, but commit a new changeset on top of the bad one. ::
+ − 461
+ − 462
$ echo 'this fixes bug 53' >> file1.c
+ − 463
$ echo 'debug hack' >> file2.c
+ − 464
$ hg commit -m 'fix bug 53' # rev 22 (oops)
+ − 465
$ echo 'and this handles bug 67' >> file1.c
+ − 466
$ hg commit -m 'fix bug 67' # rev 23 (fine)
+ − 467
+ − 468
As with ``amend`` , you need to travel back in time and repair revision
+ − 469
22, leaving your changes to ``file2.c`` back in the working
+ − 470
directory::
+ − 471
+ − 472
$ hg update 22
+ − 473
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ − 474
$ hg uncommit file2.c
+ − 475
1 new unstable changesets
+ − 476
$ hg status
+ − 477
M file2.c
+ − 478
+ − 479
Now your repository has unstable changesets, so you need to evolve it.
+ − 480
But ``hg evolve`` requires a clean working directory to resolve merge
+ − 481
conflicts, so you need to decide what to do with ``file2.c`` .
+ − 482
+ − 483
In this case, the change to ``file2.c`` was a temporary debugging
+ − 484
hack, so we can discard it and immediately evolve the instability away::
+ − 485
+ − 486
$ hg revert file2.c
+ − 487
$ hg evolve --all
+ − 488
move:[23] fix bug 67
+ − 489
atop:[24] fix bug 53
+ − 490
+ − 491
Figure 10 illustrates the whole process.
+ − 492
+ − 493
.. figure :: figures/figure-ug10.svg
+ − 494
+ − 495
Figure 10: ``hg uncommit`` of a changeset with descendants results
+ − 496
in instability *and* a dirty working directory, both of which must
+ − 497
be dealt with.
+ − 498
+ − 499
+ − 500
Example 10: Uncommit files to an older changeset (keep changes)
+ − 501
===================================================================
+ − 502
+ − 503
This is very similar to example 9. The difference that this time, our
+ − 504
change to ``file2.c`` is valuable enough to commit, making things a
+ − 505
bit more complicated. The setup is nearly identical::
+ − 506
+ − 507
$ echo 'fix a bug' >> file1.c
+ − 508
$ echo 'useful but unrelated' >> file2.c
+ − 509
$ hg commit -u dan -d '11 0' -m 'fix a bug' # rev 26 (oops)
+ − 510
$ echo 'new feature' >> file1.c
+ − 511
$ hg commit -u dan -d '12 0' -m 'new feature' # rev 27 (fine)
+ − 512
+ − 513
As before, we update back to the flawed changeset (this time,
+ − 514
revision 26) and ``uncommit`` , leaving uncommitted changes to
+ − 515
``file2.c`` in the working dir::
+ − 516
+ − 517
$ hg update -q 26
+ − 518
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ − 519
$ hg uncommit -q file2.c # obsoletes rev 26, creates rev 28
+ − 520
1 new unstable changesets
+ − 521
$ hg status
+ − 522
M file2.c
+ − 523
+ − 524
This time, let's save that useful change before evolving::
+ − 525
+ − 526
$ hg commit -m 'useful tweak' # rev 29
+ − 527
+ − 528
Figure 11 shows the story so far: ``uncommit`` obsoleted revision 26
+ − 529
and created revision 28, the successor of 26. Then we committed
+ − 530
revision 29, a child of 28. We still have to deal with the unstable
+ − 531
revision 27.
+ − 532
+ − 533
.. figure :: figures/figure-ug11.svg
+ − 534
+ − 535
Figure 11: Uncommitting a file and then committing that change
+ − 536
separately will soon result in a two-headed repository.
+ − 537
+ − 538
This is where things get tricky. As usual when a repository has
+ − 539
unstable changesets, we want to evolve it::
+ − 540
+ − 541
$ hg evolve --all
+ − 542
+ − 543
The problem is that ``hg evolve`` rebases revision 27 onto revision
+ − 544
28, creating 30 (the successor of 27). This is entirely logical: 27
+ − 545
was the child of 26, and 26's successor is 28. So of course 27's
+ − 546
successor (30) should be the child of 26's successor (28).
+ − 547
Unfortunately, that leaves us with a two-headed repository:
+ − 548
+ − 549
.. figure :: figures/figure-ug12.svg
+ − 550
+ − 551
Figure 12: ``evolve`` takes care of unstable changesets; it does
+ − 552
not solve all the world's problems.
+ − 553
+ − 554
As usual when faced with a two-headed repository, you can either merge
+ − 555
or rebase. It's up to you.
+ − 556
+ − 557
+ − 558
Example 11: Recover an obsolete changeset
+ − 559
=========================================
+ − 560
+ − 561
TODO