Mercurial > evolve
diff docs/sharing.rst @ 1265:14f91037d2f6 stable
docs: revive the explanation of divergent changesets in the sharing guide
author | Greg Ward <greg@gerg.ca> |
---|---|
date | Tue, 14 Apr 2015 12:58:13 -0400 |
parents | 33ed6119a0be |
children | 160968654581 |
line wrap: on
line diff
--- a/docs/sharing.rst Fri Jun 20 08:19:04 2014 -0400 +++ b/docs/sharing.rst Tue Apr 14 12:58:13 2015 -0400 @@ -500,10 +500,6 @@ [figure SG08: review shows v1 and v2 of Alice's fix, then v1, v2, v3 of Bob's feature, finally Alice's fix rebased onto Bob's. public just shows the final public version of each changeset] - -** STOP HERE: WORK IN PROGRESS ** - - Getting into trouble with shared mutable history ------------------------------------------------ @@ -516,10 +512,119 @@ the most common type of troubled changeset. (Recall that a non-obsolete changeset with obsolete ancestors is unstable.) -Two other types of trouble can crop up: *bumped* and *divergent* +Two other types of trouble can happen: *divergent* and *bumped* changesets. Both are more likely with shared mutable history, especially mutable history shared by multiple developers. +Setting up +========== + +For these examples, we're going to use a slightly different workflow: +as before, Alice and Bob share a ``public`` repository. But this time +there is no ``review`` repository. Instead, Alice and Bob put on their +cowboy hats, throw good practice to the wind, and pull directly from +each other's working repositories. + +So we throw away everything except ``public`` and reclone:: + + $ rm -rf review alice bob + $ hg clone public alice + updating to branch default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg clone public bob + updating to branch default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Once again we have to configure their repositories: enable ``evolve`` +and (since Alice and Bob will be pulling directly from each other) +make their repositories non-publishing. Edit Alice's configuration:: + + $ hg -R alice config --edit --local + +and add :: + + [extensions] + rebase = + evolve = /path/to/mutable-history/hgext/evolve.py + + [phases] + publish = false + +Then edit Bob's repository configuration:: + + $ hg -R bob config --edit --local + +and add the same text. + +Example 6: Divergent changesets +=============================== + +When an obsolete changeset has two successors, those successors are +*divergent*. One way to get into such a situation is by failing to +communicate with your teammates. Let's see how that might happen. + +First, we'll have Bob commit a bug fix that could still be improved:: + + $ cd bob + $ echo 'pretty good fix' >> file1 + $ hg commit -u bob -m 'fix bug 24 (v1)' # rev 4:2fe6 + +Since Alice and Bob are now in cowboy mode, Alice pulls Bob's draft +changeset and amends it herself. :: + + $ cd ../alice + $ hg pull -u ../bob + [...] + added 1 changesets with 1 changes to 1 files + $ echo 'better fix (alice)' >> file1 + $ hg amend -u alice -m 'fix bug 24 (v2 by alice)' + +But Bob has no idea that Alice just did this. (See how important good +communication is?) So he implements a better fix of his own:: + + $ cd ../bob + $ echo 'better fix (bob)' >> file1 + $ hg amend -u bob -m 'fix bug 24 (v2 by bob)' # rev 6:a360 + +At this point, the divergence exists, but only in theory: Bob's +original changeset, 4:2fe6, is obsolete and has two successors. But +those successors are in different repositories, so the trouble is not +visible to anyone yet. It will be as soon as Bob pulls from Alice's +repository (or vice-versa). :: + + $ hg pull ../alice + [...] + added 1 changesets with 1 changes to 2 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + 2 new divergent changesets + +Figure 9 shows the situation in Bob's repository. + + [figure SG09: Bob's repo with 2 heads for the 2 divergent changesets, 6:a360 and 7:e3f9; wc is at 6:a360; both are successors of obsolete 4:2fe6, hence divergence] + +Now we need to get out of trouble. As usual, the answer is to evolve +history. :: + + $ HGMERGE=internal:other hg evolve + merge:[6] fix bug 24 (v2 by bob) + with: [7] fix bug 24 (v2 by alice) + base: [4] fix bug 24 (v1) + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + +Figure 10 shows how Bob's repository looks now. + + [figure SG10: only one visible head, 9:5ad6, successor to hidden 6:a360 and 7:e3f9] + +We carefully dodged a merge conflict by specifying a merge tool +(``internal:other``) that will take Alice's changes over Bob's. (You +might wonder why Bob wouldn't prefer his own changes by using +``internal:local``. He's avoiding a `bug`_ in ``evolve`` that occurs +when evolving divergent changesets using ``internal:local``.) + +.. _`bug`: https://bitbucket.org/marmoute/mutable-history/issue/48/ + +** STOP HERE: WORK IN PROGRESS ** + Bumped changesets: only one gets on the plane ============================================= @@ -604,84 +709,6 @@ [figure SG08: 5:227d is new, formerly bumped changeset 4:fe88 now hidden] -Divergent changesets -==================== - -In addition to *unstable* and *bumped*, there is a third kind of -troubled changeset: *divergent*. When an obsolete changeset has two -successors, those successors are divergent. - -To illustrate, let's start Alice and Bob at the same -point—specifically, the point where Alice's repository currently -stands. Bob's repository is a bit of a mess, so we'll throw it away -and start him off with a copy of Alice's repository:: - - $ cd .. - $ rm -rf bob - $ cp -rp alice bob - -Now we'll have Bob commit a bug fix that could still be improved:: - - $ cd bob - $ echo 'pretty good fix' >> file1 - $ hg commit -u bob -m 'fix bug 24 (v1)' - -This time, Alice meddles with her colleague's work (still a bad -idea):: - - $ cd ../alice - $ hg pull -u ../bob - [...] - added 1 changesets with 1 changes to 1 files - $ echo 'better (alice)' >> file1 - $ hg amend -u alice -m 'fix bug 24 (v2 by alice)' - -Here's where things change from the "bumped" scenario above: this -time, the original author (Bob) decides to amend his changeset too. :: - - $ cd ../bob - $ echo 'better (bob)' >> file1 - $ hg amend -u bob -m 'fix bug 24 (v2 by bob)' - -At this point, the divergence exists, but only in theory: Bob's -original changeset, 3:fe81, is obsolete and has two successors. But -those successors are in different repositories, so the trouble is not -visible to anyone yet. It will be as soon as one of our players pulls -from the other's repository. Let's make Bob the victim again:: - - $ hg pull -q -u ../alice - not updating: not a linear update - (merge or update --check to force update) - 2 new divergent changesets - -The “not a linear update” is our first hint that something is wrong, -but of course “2 new divergent changesets” is the real problem. Figure -9 shows both problems. - - [figure SG09: Bob's repo with 2 heads for the 2 divergent changesets, 5:fc16 and 6:694f; wc is at 5:fc16, hence update refused; both are successors of obsolete 3:fe81, hence divergence] - -Now we need to get out of trouble. Unfortunately, a `bug`_ in -``evolve`` means that the usual answer (run ``hg evolve --all``) does -not work. Bob has to figure out the solution on his own: in this case, -merge. To avoid distractions, we'll set ``HGMERGE`` to make Mercurial -resolve any conflicts in favour of Bob. :: - - $ HGMERGE=internal:local hg merge - $ hg commit -m merge - -.. _`bug`: https://bitbucket.org/marmoute/mutable-history/issue/48/ - -This is approximately what ``hg evolve`` would do in this -circumstance, if not for that bug. One annoying difference is that -Mercurial thinks the two divergent changesets are still divergent, -which you can see with a simple revset query:: - - $ hg log -q -r 'divergent()' - 5:fc16901f4d7a - 6:694fd0f6b503 - -(That annoyance should go away when the bug is fixed.) - Conclusion ----------