diff mercurial/cmdutil.py @ 17811:a8aba2921456

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.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Thu, 18 Oct 2012 22:12:15 +0200
parents 9912baaae7df
children 578fcc22b469
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Thu Oct 18 22:04:49 2012 +0200
+++ b/mercurial/cmdutil.py	Thu Oct 18 22:12:15 2012 +0200
@@ -11,6 +11,7 @@
 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 @@
             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 @@
                                  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())