# HG changeset patch # User Pierre-Yves David # Date 2012-10-18 20:12:15 # Node ID a8aba292145681a23cee77f85b4376cc9b9cf0cc # Parent 2894d180afa1851d896368fab2edaa7123a5d920 amend: add noise in extra to avoid creating obsolescence cycle (issue3664) Obsolescence cycle are bad and should be avoided as much as possible. The current amend implemented touch changeset meta data as few as possible. This make is easy for amend to result in the same node than a precursors. We add some deterministic noise in extra to avoid this. In practice, the hex of the amended changeset is stored in 'amend_source' extra key. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -11,6 +11,7 @@ import os, sys, errno, re, tempfile import util, scmutil, templater, patch, error, templatekw, revlog, copies import match as matchmod import subrepo, context, repair, bookmarks, graphmod, revset, phases, obsolete +import changelog import lock as lockmod def parsealiases(cmd): @@ -1696,6 +1697,9 @@ def amend(ui, repo, commitfunc, old, ext if not message: message = old.description() + pureextra = extra.copy() + extra['amend_source'] = old.hex() + new = context.memctx(repo, parents=[base.node(), nullid], text=message, @@ -1705,6 +1709,19 @@ def amend(ui, repo, commitfunc, old, ext date=date, extra=extra) new._text = commitforceeditor(repo, new, []) + + newdesc = changelog.stripdesc(new.description()) + if ((not node) + and newdesc == old.description() + and user == old.user() + and date == old.date() + and pureextra == old.extra()): + # nothing changed. continuing here would create a new node + # anyway because of the amend_source noise. + # + # This not what we expect from amend. + return old.node() + ph = repo.ui.config('phases', 'new-commit', phases.draft) try: repo.ui.setconfig('phases', 'new-commit', old.phase()) diff --git a/tests/test-commit-amend.t b/tests/test-commit-amend.t --- a/tests/test-commit-amend.t +++ b/tests/test-commit-amend.t @@ -32,12 +32,12 @@ Amending changeset with changes in worki $ echo a >> a $ hg ci --amend -m 'amend base1' - pretxncommit 9cd25b479c51be2f4ed2c38e7abdf7ce67d8e0dc - 9cd25b479c51 tip + pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149 + 43f1ba15f28a tip saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-amend-backup.hg (glob) $ echo 'pretxncommit.foo = ' >> $HGRCPATH $ hg diff -c . - diff -r ad120869acf0 -r 9cd25b479c51 a + diff -r ad120869acf0 -r 43f1ba15f28a a --- a/a Thu Jan 01 00:00:00 1970 +0000 +++ b/a Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +1,3 @@ @@ -45,7 +45,7 @@ Amending changeset with changes in worki +a +a $ hg log - changeset: 1:9cd25b479c51 + changeset: 1:43f1ba15f28a tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -62,36 +62,36 @@ Add new file: $ echo b > b $ hg ci --amend -Am 'amend base1 new file' adding b - saved backup bundle to $TESTTMP/.hg/strip-backup/9cd25b479c51-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-amend-backup.hg (glob) Remove file that was added in amended commit: $ hg rm b $ hg ci --amend -m 'amend base1 remove new file' - saved backup bundle to $TESTTMP/.hg/strip-backup/e2bb3ecffd2f-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/b8e3cb2b3882-amend-backup.hg (glob) $ hg cat b - b: no such file in rev 664a9b2d60cd + b: no such file in rev 74609c7f506e [1] No changes, just a different message: $ hg ci -v --amend -m 'no changes, new message' - amending changeset 664a9b2d60cd - copying changeset 664a9b2d60cd to ad120869acf0 + amending changeset 74609c7f506e + copying changeset 74609c7f506e to ad120869acf0 a - stripping amended changeset 664a9b2d60cd + stripping amended changeset 74609c7f506e 1 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/664a9b2d60cd-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-amend-backup.hg (glob) 1 changesets found adding branch adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files - committed changeset 1:ea6e356ff2ad + committed changeset 1:1cd866679df8 $ hg diff -c . - diff -r ad120869acf0 -r ea6e356ff2ad a + diff -r ad120869acf0 -r 1cd866679df8 a --- a/a Thu Jan 01 00:00:00 1970 +0000 +++ b/a Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +1,3 @@ @@ -99,7 +99,7 @@ No changes, just a different message: +a +a $ hg log - changeset: 1:ea6e356ff2ad + changeset: 1:1cd866679df8 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 @@ -119,12 +119,12 @@ Disable default date on commit so when - Test -u/-d: $ hg ci --amend -u foo -d '1 0' - saved backup bundle to $TESTTMP/.hg/strip-backup/ea6e356ff2ad-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-amend-backup.hg (glob) $ echo a >> a $ hg ci --amend -u foo -d '1 0' - saved backup bundle to $TESTTMP/.hg/strip-backup/377b91ce8b56-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/780e6f23e03d-amend-backup.hg (glob) $ hg log -r . - changeset: 1:2c94e4a5756f + changeset: 1:5f357c7560ab tag: tip user: foo date: Thu Jan 01 00:00:01 1970 +0000 @@ -139,8 +139,8 @@ Open editor with old commit message if a > echo "another precious commit message" > "$1" > __EOF__ $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v - amending changeset 2c94e4a5756f - copying changeset 2c94e4a5756f to ad120869acf0 + amending changeset 5f357c7560ab + copying changeset 5f357c7560ab to ad120869acf0 no changes, new message @@ -151,24 +151,24 @@ Open editor with old commit message if a HG: branch 'default' HG: changed a a - stripping amended changeset 2c94e4a5756f + stripping amended changeset 5f357c7560ab 1 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/2c94e4a5756f-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-amend-backup.hg (glob) 1 changesets found adding branch adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files - committed changeset 1:ffb49186f961 + committed changeset 1:7ab3bf440b54 Same, but with changes in working dir (different code path): $ echo a >> a $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v - amending changeset ffb49186f961 + amending changeset 7ab3bf440b54 a - copying changeset a4f8a65b7c6a to ad120869acf0 + copying changeset a0ea9b1a4c8c to ad120869acf0 another precious commit message @@ -179,21 +179,21 @@ Same, but with changes in working dir (d HG: branch 'default' HG: changed a a - stripping intermediate changeset a4f8a65b7c6a - stripping amended changeset ffb49186f961 + stripping intermediate changeset a0ea9b1a4c8c + stripping amended changeset 7ab3bf440b54 2 changesets found - saved backup bundle to $TESTTMP/.hg/strip-backup/ffb49186f961-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-amend-backup.hg (glob) 1 changesets found adding branch adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files - committed changeset 1:fb6cca43446f + committed changeset 1:ea22a388757c $ rm editor.sh $ hg log -r . - changeset: 1:fb6cca43446f + changeset: 1:ea22a388757c tag: tip user: foo date: Thu Jan 01 00:00:01 1970 +0000 @@ -205,16 +205,16 @@ Moving bookmarks, preserve active bookma $ hg book book1 $ hg book book2 $ hg ci --amend -m 'move bookmarks' - saved backup bundle to $TESTTMP/.hg/strip-backup/fb6cca43446f-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/ea22a388757c-amend-backup.hg (glob) $ hg book - book1 1:0cf1c7a51bcf - * book2 1:0cf1c7a51bcf + book1 1:6cec5aa930e2 + * book2 1:6cec5aa930e2 $ echo a >> a $ hg ci --amend -m 'move bookmarks' - saved backup bundle to $TESTTMP/.hg/strip-backup/0cf1c7a51bcf-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/6cec5aa930e2-amend-backup.hg (glob) $ hg book - book1 1:7344472bd951 - * book2 1:7344472bd951 + book1 1:48bb6e53a15f + * book2 1:48bb6e53a15f $ echo '[defaults]' >> $HGRCPATH $ echo "commit=-d '0 0'" >> $HGRCPATH @@ -230,9 +230,9 @@ Moving branches: marked working directory as branch default (branches are permanent and global, did you want a bookmark?) $ hg ci --amend -m 'back to default' - saved backup bundle to $TESTTMP/.hg/strip-backup/1661ca36a2db-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/8ac881fbf49d-amend-backup.hg (glob) $ hg branches - default 2:f24ee5961967 + default 2:ce12b0b57d46 Close branch: @@ -255,9 +255,9 @@ Same thing, different code path: reopening closed branch head 4 $ echo b >> b $ hg ci --amend --close-branch - saved backup bundle to $TESTTMP/.hg/strip-backup/5e302dcc12b8-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-amend-backup.hg (glob) $ hg branches - default 2:f24ee5961967 + default 2:ce12b0b57d46 Refuse to amend merges: @@ -279,7 +279,7 @@ Follow copies/renames: $ hg ci -m 'b -> c' $ hg mv c d $ hg ci --amend -m 'b -> d' - saved backup bundle to $TESTTMP/.hg/strip-backup/9c207120aa98-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/b8c6eac7f12e-amend-backup.hg (glob) $ hg st --rev '.^' --copies d A d b @@ -287,7 +287,7 @@ Follow copies/renames: $ hg ci -m 'e = d' $ hg cp e f $ hg ci --amend -m 'f = d' - saved backup bundle to $TESTTMP/.hg/strip-backup/fda2b3b27b22-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/7f9761d65613-amend-backup.hg (glob) $ hg st --rev '.^' --copies f A f d @@ -298,7 +298,7 @@ Follow copies/renames: $ hg cp a f $ mv f.orig f $ hg ci --amend -m replacef - saved backup bundle to $TESTTMP/.hg/strip-backup/20a7413547f9-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/9e8c5f7e3d95-amend-backup.hg (glob) $ hg st --change . --copies $ hg log -r . --template "{file_copies}\n" @@ -310,7 +310,7 @@ Move added file (issue3410): adding g $ hg mv g h $ hg ci --amend - saved backup bundle to $TESTTMP/.hg/strip-backup/5daa77a5d616-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/24aa8eacce2b-amend-backup.hg (glob) $ hg st --change . --copies h A h $ hg log -r . --template "{file_copies}\n" @@ -330,11 +330,11 @@ Preserve extra dict (issue3430): $ echo a >> a $ hg ci -ma $ hg ci --amend -m "a'" - saved backup bundle to $TESTTMP/.hg/strip-backup/167f8e3031df-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/3837aa2a2fdb-amend-backup.hg (glob) $ hg log -r . --template "{branch}\n" a $ hg ci --amend -m "a''" - saved backup bundle to $TESTTMP/.hg/strip-backup/ceac1a44c806-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/c05c06be7514-amend-backup.hg (glob) $ hg log -r . --template "{branch}\n" a @@ -351,8 +351,9 @@ first graft something so there's an addi $ hg graft 12 grafting revision 12 $ hg ci --amend -m 'graft amend' - saved backup bundle to $TESTTMP/.hg/strip-backup/18a5124daf7a-amend-backup.hg (glob) + saved backup bundle to $TESTTMP/.hg/strip-backup/bd010aea3f39-amend-backup.hg (glob) $ hg log -r . --debug | grep extra + extra: amend_source=bd010aea3f39f3fb2a2f884b9ccb0471cd77398e extra: branch=a extra: source=2647734878ef0236dda712fae9c1651cf694ea8a @@ -391,26 +392,26 @@ Amend with no files changes $ hg id -n 14 $ hg log -Gl 3 --style=compact - @ 14[tip]:11 43df5a5434ad 1970-01-01 00:00 +0000 test + @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test | babar | | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test | | fork | | - o | 11 7e09f708a0e9 1970-01-01 00:00 +0000 test + o | 11 3334b7925910 1970-01-01 00:00 +0000 test | | a'' | | $ hg log -Gl 4 --hidden --style=compact - @ 14[tip]:11 43df5a5434ad 1970-01-01 00:00 +0000 test + @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test | babar | - | x 13:11 175fafee6f44 1970-01-01 00:00 +0000 test + | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test |/ amend for phase | | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test | | fork | | - o | 11 7e09f708a0e9 1970-01-01 00:00 +0000 test + o | 11 3334b7925910 1970-01-01 00:00 +0000 test | | a'' | | @@ -422,23 +423,34 @@ ride of) $ echo 'babar' >> a $ hg commit --amend $ hg log -Gl 6 --hidden --style=compact - @ 16[tip]:11 31e0a4a1b04a 1970-01-01 00:00 +0000 test + @ 16[tip]:11 9f9e9bccf56c 1970-01-01 00:00 +0000 test | babar | - | x 15 053c696ada75 1970-01-01 00:00 +0000 test - | | temporary amend commit for 43df5a5434ad + | x 15 90fef497c56f 1970-01-01 00:00 +0000 test + | | temporary amend commit for b650e6ee8614 | | - | x 14:11 43df5a5434ad 1970-01-01 00:00 +0000 test + | x 14:11 b650e6ee8614 1970-01-01 00:00 +0000 test |/ babar | - | x 13:11 175fafee6f44 1970-01-01 00:00 +0000 test + | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test |/ amend for phase | | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test | | fork | | - o | 11 7e09f708a0e9 1970-01-01 00:00 +0000 test + o | 11 3334b7925910 1970-01-01 00:00 +0000 test | | a'' | | +Test that amend does not make it easy to create obsoletescence cycle +--------------------------------------------------------------------- + + + $ hg id -r 14 + b650e6ee8614 (a) + $ hg revert -ar 14 + reverting a + $ hg commit --amend + $ hg id + b99e5df575f7 (a) tip diff --git a/tests/test-keyword.t b/tests/test-keyword.t --- a/tests/test-keyword.t +++ b/tests/test-keyword.t @@ -509,9 +509,9 @@ amend $ hg --debug commit --amend -d '15 1' -m 'amend without changes' | grep keywords overwriting a expanding keywords $ hg -q id - 577e60613a88 + 67d8c481a6be $ head -1 a - expand $Id: a,v 577e60613a88 1970/01/01 00:00:15 test $ + expand $Id: a,v 67d8c481a6be 1970/01/01 00:00:15 test $ $ hg -q strip -n tip