Mercurial > evolve
view tests/test-userguide.t @ 3846:f9dad99a90d5
evolve: create a new commit instead of amending one of the divergents
This patch changes the behavior of evolve command while resolving
content-divergence to create a new commit instead of amending one of the
divergent ones.
In past, I have made this change, backed out this change and now today again I
am doing this change, so let's dive in some history.
Using cmdrewrite.amend() was never a good option as that requires hack to delete
the evolvestate and also gives us less control over things. We can't make the
commit on top of different parents as that of content-divergent ones. Due to all
these, I first made this change to create a new commit instead of amending one.
But, after few days, there was flakiness observed in the tests and turned out
that we need to do some dirstate dance as repo.dirstate.setparents() does not
always fix the dirstate. That flakiness was a blocker for progress at that time
and we decided to switch to amend back so that we can have things working with
some hacks and we can later fix the implementation part.
Now, yesterday while tackling resolving content-divergence of a stack which is
as follows:
C1 C2
| |
B1 B2
| |
A1 A2
\/
base
where, A1-A2, B1-B2, C1-C2 are content-divergent with each other. Now we can
resolve A1-A2 very well because they have the same parent and let's say that
resolution leads to A3.
Now, we want to resolve B1-B2 and make the new resolution commit on top of A3 so
that we can end up something like:
C3
|
B3
|
A3
|
base
however, amending one of the divergent changesets, it's not possible to create a
commit on a different parent like A3 here without some relocation. We should
prevent relocation as that may leads to some conflicts and should change the
parent before committing.
So, looking ahead, we can't move with using amend as still using that we will
need some relocation hacks making code ugly and prone to bad behaviors, bugs.
Let's change back to creating a new commit so that we can move forward in a good
way.
About repo.dirstate.setparents() not setting the dirstate, I have researched
yesterday night about how we can do that and found out that we can use
cmdrewrite._uncommitdirstate() here. Expect upcoming patches to improve the
documentation of that function.
There are lot of test changes because of change in hash but there is no behavior
change. The only behavior change is in test-evolve-abort-contentdiv.t which is
nice because creating a new commit helps us in stripping that while aborting.
We have a lot of testing of content-divergence and no behavior change gives
enough confidence for making this change.
I reviewed the patch carefully to make sure there is no behavior change and I
suggest reviewer to do the same.
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Wed, 13 Jun 2018 17:15:10 +0530 |
parents | 54a469cd5b26 |
children | fbcf9e92097e 96ce1030d2fb |
line wrap: on
line source
ensure that all the scenarios in the user guide work as documented basic repo $ hg init t $ cd t $ touch file1.c file2.c $ hg -q commit -A -m init example 1: commit creates a changeset in draft phase (this is nothing to do with evolve, but it's mentioned in the user guide) $ echo 'feature Y' >> file1.c $ hg commit -u alice -d '0 0' -m 'implement feature X' $ hg phase -r . 1: draft $ hg identify -in 6e725fd2be6f 1 example 2: unsafe amend with plain vanilla Mercurial: the original commit is stripped $ hg commit --amend -u alice -d '1 0' -m 'implement feature Y' saved backup bundle to $TESTTMP/t/.hg/strip-backup/6e725fd2be6f-42cc74d4-amend.hg (glob) $ hg log -r 23fe4ac6d3f1 abort: unknown revision '23fe4ac6d3f1'! [255] $ hg identify -in fe0ecd3bd2a4 1 enable evolve for safe history modification $ cat >> $HGRCPATH <<EOF > [alias] > shortlog = log --template '{rev}:{node|short} {phase} {desc|firstline}\n' > [extensions] > rebase = > EOF $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH example 3: safe amend with "hg commit --amend" (figure 2) $ echo 'tweak feature Y' >> file1.c $ hg commit --amend -u alice -d '2 0' -m 'implement feature Y' $ hg shortlog -q -r fe0ecd3bd2a4 abort: hidden revision 'fe0ecd3bd2a4' was rewritten as: 934359450037! (use --hidden to access hidden revisions) [255] $ hg --hidden shortlog -G @ 2:934359450037 draft implement feature Y | | x 1:fe0ecd3bd2a4 draft implement feature Y |/ o 0:08c4b6f4efc8 draft init example 3 redux: repeat safe amend, this time with "hg amend" $ hg rollback -q $ hg amend -u alice -d '2 0' -m 'implement feature Y' $ hg --hidden shortlog -G @ 2:934359450037 draft implement feature Y | | x 1:fe0ecd3bd2a4 draft implement feature Y |/ o 0:08c4b6f4efc8 draft init example 4: prune at head (figure 3) $ echo 'debug hack' >> file1.c $ hg commit -m 'debug hack' $ hg prune . 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory now at 934359450037 1 changesets pruned $ hg parents --template '{rev}:{node|short} {desc|firstline}\n' 2:934359450037 implement feature Y $ hg --hidden shortlog -G -r 934359450037: x 3:a3e0ef24aaf0 draft debug hack | @ 2:934359450037 draft implement feature Y | ~ example 5: uncommit files at head (figure 4) $ echo 'relevant' >> file1.c $ echo 'irrelevant' >> file2.c $ hg commit -u dan -d '10 0' -m 'fix bug 234' $ hg uncommit file2.c $ hg status M file2.c $ hg --hidden shortlog -G -r 'descendants(934359450037) - a3e0ef24aaf0' @ 5:c8defeecf7a4 draft fix bug 234 | | x 4:da4331967f5f draft fix bug 234 |/ o 2:934359450037 draft implement feature Y | ~ $ hg parents --template '{rev}:{node|short} {desc|firstline}\n{files}\n' 5:c8defeecf7a4 fix bug 234 file1.c $ hg revert --no-backup file2.c example 6: fold multiple changesets together into one (figure 5) $ echo step1 >> file1.c $ hg commit -m 'step 1' $ echo step2 >> file1.c $ hg commit -m 'step 2' $ echo step3 >> file2.c $ hg commit -m 'step 3' $ hg log --template '{rev}:{node|short} {desc|firstline}\n' -r 05e61aab8294:: 6:05e61aab8294 step 1 7:be6d5bc8e4cc step 2 8:35f432d9f7c1 step 3 $ hg fold -d '0 0' -m 'fix bug 64' --from -r 05e61aab8294:: 3 changesets folded 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg --hidden shortlog -G -r c8defeecf7a4:: @ 9:171c6a79a27b draft fix bug 64 | | x 8:35f432d9f7c1 draft step 3 | | | x 7:be6d5bc8e4cc draft step 2 | | | x 6:05e61aab8294 draft step 1 |/ o 5:c8defeecf7a4 draft fix bug 234 | ~ $ hg --hidden log -q -r 'successors(05e61aab8294) | successors(be6d5bc8e4cc) | successors(35f432d9f7c1)' 9:171c6a79a27b $ hg --hidden log -q -r 'precursors(171c6a79a27b)' 6:05e61aab8294 7:be6d5bc8e4cc 8:35f432d9f7c1 $ hg diff -c 171c6a79a27b -U 0 diff -r c8defeecf7a4 -r 171c6a79a27b file1.c --- a/file1.c Thu Jan 01 00:00:10 1970 +0000 +++ b/file1.c Thu Jan 01 00:00:00 1970 +0000 @@ -3,0 +4,2 @@ +step1 +step2 diff -r c8defeecf7a4 -r 171c6a79a27b file2.c --- a/file2.c Thu Jan 01 00:00:10 1970 +0000 +++ b/file2.c Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@ +step3 setup for example 7: amend an older changeset $ echo 'fix fix oops fix' > file2.c $ hg commit -u bob -d '3 0' -m 'fix bug 17' $ echo 'cleanup' >> file1.c $ hg commit -u bob -d '4 0' -m 'cleanup' $ echo 'new feature' >> file1.c $ hg commit -u bob -d '5 0' -m 'feature 23' $ hg --hidden shortlog -G -r 171c6a79a27b:: @ 12:dadcbba2d606 draft feature 23 | o 11:debd46bb29dc draft cleanup | o 10:3e1cb8f70c02 draft fix bug 17 | o 9:171c6a79a27b draft fix bug 64 | ~ example 7: amend an older changeset (figures 6, 7) $ hg update -q -r 3e1cb8f70c02 $ echo 'fix fix fix fix' > file2.c $ hg amend -u bob -d '6 0' 2 new orphan changesets $ hg shortlog -r 'obsolete()' 10:3e1cb8f70c02 draft fix bug 17 $ hg shortlog -r "orphan()" 11:debd46bb29dc draft cleanup 12:dadcbba2d606 draft feature 23 $ hg --hidden shortlog -G -r 171c6a79a27b:: @ 13:395cbeda3a06 draft fix bug 17 | | * 12:dadcbba2d606 draft feature 23 | | | * 11:debd46bb29dc draft cleanup | | | x 10:3e1cb8f70c02 draft fix bug 17 |/ o 9:171c6a79a27b draft fix bug 64 | ~ $ hg evolve -q --all $ hg shortlog -G -r 171c6a79a27b:: @ 15:91b4b0f8b5c5 draft feature 23 | o 14:fe8858bd9bc2 draft cleanup | o 13:395cbeda3a06 draft fix bug 17 | o 9:171c6a79a27b draft fix bug 64 | ~ setup for example 8: prune an older changeset (figure 8) $ echo 'useful' >> file1.c $ hg commit -u carl -d '7 0' -m 'useful work' $ echo 'debug' >> file2.c $ hg commit -u carl -d '8 0' -m 'debug hack' $ echo 'more useful' >> file1.c $ hg commit -u carl -d '9 0' -m 'more work' $ hg shortlog -G -r 91b4b0f8b5c5:: @ 18:ea8fafca914b draft more work | o 17:b23d06b457a8 draft debug hack | o 16:1f33e68b18b9 draft useful work | o 15:91b4b0f8b5c5 draft feature 23 | ~ example 8: prune an older changeset (figures 8, 9) $ hg prune b23d06b457a8 1 changesets pruned 1 new orphan changesets $ hg --hidden shortlog -G -r b23d06b457a8:: @ 18:ea8fafca914b draft more work | x 17:b23d06b457a8 draft debug hack | ~ $ hg evolve -q --all --any $ hg --hidden shortlog -G -r 1f33e68b18b9:: @ 19:4393e5877437 draft more work | | x 18:ea8fafca914b draft more work | | | x 17:b23d06b457a8 draft debug hack |/ o 16:1f33e68b18b9 draft useful work | ~ example 9: uncommit files from an older changeset (discard changes) (figure 10) $ echo 'this fixes bug 53' >> file1.c $ echo 'debug hack' >> file2.c $ hg commit -u dan -d '11 0' -m 'fix bug 53' $ echo 'and this handles bug 67' >> file1.c $ hg commit -u dan -d '12 0' -m 'fix bug 67' $ hg update -r f84357446753 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg shortlog -G -r 4393e5877437:: o 21:4db2428c8ae3 draft fix bug 67 | @ 20:f84357446753 draft fix bug 53 | o 19:4393e5877437 draft more work | ~ $ hg uncommit file2.c 1 new orphan changesets $ hg status M file2.c $ hg revert file2.c $ hg evolve --all --any move:[21] fix bug 67 atop:[22] fix bug 53 working directory is now at 0d972d6888e6 $ hg --hidden shortlog -G -r 4393e5877437:: @ 23:0d972d6888e6 draft fix bug 67 | o 22:71bb83d674c5 draft fix bug 53 | | x 21:4db2428c8ae3 draft fix bug 67 | | | x 20:f84357446753 draft fix bug 53 |/ o 19:4393e5877437 draft more work | ~ $ rm file2.c.orig example 10: uncommit files from an older changeset (keep changes) (figures 11, 12) $ echo 'fix a bug' >> file1.c $ echo 'useful but unrelated' >> file2.c $ hg commit -u dan -d '11 0' -m 'fix a bug' $ echo 'new feature' >> file1.c $ hg commit -u dan -d '12 0' -m 'new feature' $ hg update 5b31a1239ab9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg --hidden shortlog -G -r 0d972d6888e6:: o 25:fbb3c6d50427 draft new feature | @ 24:5b31a1239ab9 draft fix a bug | o 23:0d972d6888e6 draft fix bug 67 | ~ $ hg uncommit file2.c 1 new orphan changesets $ hg status M file2.c $ hg commit -m 'useful tweak' $ hg --hidden shortlog -G -r 0d972d6888e6:: @ 27:51e0d8c0a922 draft useful tweak | o 26:2594e98553a9 draft fix a bug | | * 25:fbb3c6d50427 draft new feature | | | x 24:5b31a1239ab9 draft fix a bug |/ o 23:0d972d6888e6 draft fix bug 67 | ~ $ hg evolve --all --any move:[25] new feature atop:[26] fix a bug working directory is now at 166c1c368ab6 $ hg --hidden shortlog -G -r 0d972d6888e6:: @ 28:166c1c368ab6 draft new feature | | o 27:51e0d8c0a922 draft useful tweak |/ o 26:2594e98553a9 draft fix a bug | | x 25:fbb3c6d50427 draft new feature | | | x 24:5b31a1239ab9 draft fix a bug |/ o 23:0d972d6888e6 draft fix bug 67 | ~