Patchwork D9257: commit, backout: warn the user when a commit already exists

login
register
mail settings
Submitter phabricator
Date Oct. 29, 2020, 7:05 a.m.
Message ID <differential-rev-PHID-DREV-sfyd3jid4b6aqoxk4c7h-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47528/
State Superseded
Headers show

Comments

phabricator - Oct. 29, 2020, 7:05 a.m.
danchr created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Sometimes, a commit will result in an exact match of a preexisting
  commit, and if that commit isn't a branch head, hg will incorrectly
  note that it created a new head. Instead, we should warn the user that
  commit already existed in the repository.
  
  In practice, this bug is rather uncommon, and will only occur when the
  usr explicitly sets the date.

REPOSITORY
  rHG Mercurial

BRANCH
  stable

REVISION DETAIL
  https://phab.mercurial-scm.org/D9257

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  tests/test-backout.t
  tests/test-unamend.t

CHANGE DETAILS




To: danchr, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-unamend.t b/tests/test-unamend.t
--- a/tests/test-unamend.t
+++ b/tests/test-unamend.t
@@ -405,8 +405,10 @@ 
   $ hg co -q 0
   $ hg mv a b
   $ hg ci -qm 'move to a b'
+  warning: commit already existed in the repository!
   $ hg mv b c
   $ hg amend
+  warning: commit already existed in the repository!
   $ hg mv c d
   $ hg unamend
   $ hg st --copies --change .
diff --git a/tests/test-backout.t b/tests/test-backout.t
--- a/tests/test-backout.t
+++ b/tests/test-backout.t
@@ -819,5 +819,5 @@ 
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg backout 2
   removing 3
-  created new head
+  warning: commit already existed in the repository!
   changeset 3:8f188de730d9 backs out changeset 2:cccc23d9d68f
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -850,11 +850,14 @@ 
             message, opts.get(b'user'), opts.get(b'date'), match, editor=e
         )
 
+    # save to detect changes
+    tip = repo.changelog.tip()
+
     newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
     if not newnode:
         ui.status(_(b"nothing changed\n"))
         return 1
-    cmdutil.commitstatus(repo, newnode, branch, bheads)
+    cmdutil.commitstatus(repo, newnode, branch, bheads, tip)
 
     def nice(node):
         return b'%d:%s' % (repo.changelog.rev(node), short(node))
@@ -2024,6 +2027,7 @@ 
 
     branch = repo[None].branch()
     bheads = repo.branchheads(branch)
+    tip = repo.changelog.tip()
 
     extra = {}
     if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
@@ -2113,7 +2117,7 @@ 
                 ui.status(_(b"nothing changed\n"))
             return 1
 
-    cmdutil.commitstatus(repo, node, branch, bheads, opts)
+    cmdutil.commitstatus(repo, node, branch, bheads, tip, opts)
 
     if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
         status(
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3089,13 +3089,20 @@ 
     return b"\n".join(edittext)
 
 
-def commitstatus(repo, node, branch, bheads=None, opts=None):
+def commitstatus(repo, node, branch, bheads=None, tip=None, opts=None):
     if opts is None:
         opts = {}
     ctx = repo[node]
     parents = ctx.parents()
 
-    if (
+    if tip is not None and repo.changelog.tip() == tip:
+        # avoid reporting something like "committed new head" when
+        # recommitting old changesets, and issue a helpful warning
+        # for most instances
+        repo.ui.warn(
+            _("warning: commit already existed in the repository!\n"),
+        )
+    elif (
         not opts.get(b'amend')
         and bheads
         and node not in bheads