Patchwork D9253: commit: don't change phases for preexisting commits

login
register
mail settings
Submitter phabricator
Date Oct. 28, 2020, 3:19 p.m.
Message ID <differential-rev-PHID-DREV-kipp67kqc5x5nl7sw6dp-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47524/
State Superseded
Headers show

Comments

phabricator - Oct. 28, 2020, 3:19 p.m.
danchr created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  I noticed when pulling with hg-git in a repository that already had
  the changes, but pulled from another Mercurial repository. This meant
  that hg-git would re-create exact matches of the changesets, and
  if they were public, they'd get reverted to drafts.
  
  This change fixes that behaviour by avoiding phase changes when:
  
  - the result isn't tip
  - the result wasn't hidden
  
  The latter check addresses some issues with the shelve test. To help
  identify this issue, I added a message that reports to the user that a
  commit didn't change anything, should they actually trigger this.

REPOSITORY
  rHG Mercurial

BRANCH
  stable

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

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commit.py
  tests/test-phases.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-phases.t b/tests/test-phases.t
--- a/tests/test-phases.t
+++ b/tests/test-phases.t
@@ -999,3 +999,99 @@ 
      date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     A
   
+
+  $ cd ..
+
+Recommitting an exact match of a public commit shouldn't change it to
+draft:
+
+  $ cd initialrepo
+  $ hg log --style=phases --graph
+  @    changeset:   7:17a481b3bccb
+  |\   tag:         tip
+  | |  phase:       draft
+  | |  parent:      6:cf9fe039dfd6
+  | |  parent:      4:a603bfb5a83e
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     merge B' and E
+  | |
+  | o  changeset:   6:cf9fe039dfd6
+  | |  phase:       public
+  | |  parent:      1:27547f69f254
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     B'
+  | |
+  o |  changeset:   4:a603bfb5a83e
+  | |  phase:       draft
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     E
+  | |
+  o |  changeset:   3:b3325c91a4d9
+  | |  phase:       draft
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     D
+  | |
+  o |  changeset:   2:f838bfaca5c7
+  |/   phase:       public
+  |    user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     C
+  |
+  o  changeset:   1:27547f69f254
+  |  phase:       public
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     B
+  |
+  o  changeset:   0:4a2df7238c3b
+     phase:       public
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     A
+  
+  $ hg phase -r 2
+  2: public
+  $ hg up -C 1
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit C
+  warning: commit didn't add anything to the repository!
+  $ hg phase -r 2
+  2: public
+
+Same, but for secret:
+
+  $ hg up 7
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ mkcommit F -s
+  test-debug-phase: new rev 8:  x -> 2
+  test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a:   -> secret
+  $ hg up 7
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit F
+  $ hg phase -r tip
+  8: secret
+
+But what about obsoleted changesets?
+
+  $ hg up 4
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ mkcommit H
+  test-debug-phase: new rev 5:  x -> 2
+  warning: commit didn't add anything to the repository!
+  test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8:   -> secret
+  $ hg phase -r 5
+  5: secret
+  $ hg par
+  changeset:   5:a030c6be5127
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  obsolete:    pruned
+  summary:     H
+  
+  $ hg up tip
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ cd ..
diff --git a/mercurial/commit.py b/mercurial/commit.py
--- a/mercurial/commit.py
+++ b/mercurial/commit.py
@@ -79,6 +79,9 @@ 
         if repo.changelog._copiesstorage == b'extra':
             extra = _extra_with_copies(repo, extra, files)
 
+        # save the tip to check whether we actually committed anything
+        tip = repo.changelog.tip()
+
         # update changelog
         repo.ui.note(_(b"committing changelog\n"))
         repo.changelog.delayupdate(tr)
@@ -99,7 +102,7 @@ 
         )
         # set the new commit is proper phase
         targetphase = subrepoutil.newcommitphase(repo.ui, ctx)
-        if targetphase:
+        if targetphase and (tip != repo.changelog.tip() or repo[n].hidden()):
             # retract boundary do not alter parent changeset.
             # if a parent have higher the resulting phase will
             # be compliant anyway
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3095,7 +3095,13 @@ 
     ctx = repo[node]
     parents = ctx.parents()
 
-    if (
+    if repo.changelog.tip() != node:
+        # this check is two-fold: 1. avoid reporting something like
+        # "committed new head" when recommitting old changesets, and
+        # 2., issue a helpful warning for most instances -- excepting
+        # when recommitting tip
+        repo.ui.warn(_("warning: commit didn't add anything to the repository!\n"))
+    elif (
         not opts.get(b'amend')
         and bheads
         and node not in bheads