[PATCH 6 of 6 STABLE] amend: update .hgsubstate before committing a memctx (issue5677)

Yuya Nishihara yuya at tcha.org
Wed Nov 8 08:13:55 EST 2017


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1509793660 -32400
#      Sat Nov 04 20:07:40 2017 +0900
# Branch stable
# Node ID 17f13d94fbfb4f59bdae5e7a0deb04c3314a992e
# Parent  34c95aad895f0a96e3becbdfec61a073fbe759f3
amend: update .hgsubstate before committing a memctx (issue5677)

This is a minimal copy of localrepo.commit(). As the current amend() function
heavily depends on the wctx API, it wasn't easy to port it to use a separate
status tuple. So for now, wctx._status is updated in-place.

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3153,6 +3153,18 @@ def amend(ui, repo, old, extra, pats, op
             raise error.Abort(
                 _("failed to mark all new/missing files as added/removed"))
 
+        # Check subrepos. This depends on in-place wctx._status update in
+        # subrepo.precommit(). To minimize the risk of this hack, we do
+        # nothing if .hgsub does not exist.
+        if '.hgsub' in wctx or '.hgsub' in old:
+            from . import subrepo  # avoid cycle: cmdutil -> subrepo -> cmdutil
+            subs, commitsubs, newsubstate = subrepo.precommit(
+                ui, wctx, wctx._status, matcher)
+            # amend should abort if commitsubrepos is enabled
+            assert not commitsubs
+            if subs:
+                subrepo.writestate(repo, newsubstate)
+
         filestoamend = set(f for f in wctx.files() if matcher(f))
 
         changes = (len(filestoamend) > 0)
diff --git a/tests/test-amend-subrepo.t b/tests/test-amend-subrepo.t
--- a/tests/test-amend-subrepo.t
+++ b/tests/test-amend-subrepo.t
@@ -31,28 +31,18 @@ Link first subrepo
 
 amend without .hgsub
 
-BROKEN: should say "can't commit subrepos without .hgsub"
   $ hg amend s
-  nothing changed
-  [1]
+  abort: can't commit subrepos without .hgsub
+  [255]
 
 amend with subrepo
 
-BROKEN: should update .hgsubstate
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
   $ hg status --change .
   A .hgsub
+  A .hgsubstate
   A a
-
-FIX UP .hgsubstate
-
-  $ hg ci -mfix
-  $ hg rollback -q
-  $ hg add .hgsubstate
-  $ hg amend
-  saved backup bundle to * (glob) (obsstore-off !)
-
   $ cat .hgsubstate
   0000000000000000000000000000000000000000 s
 
@@ -69,46 +59,27 @@ amend with dirty subrepo
   $ echo a >> s/a
   $ hg add -R s
   adding s/a
-BROKEN: should say "uncommitted changes in subrepository"
   $ hg amend
-  nothing changed
-  [1]
+  abort: uncommitted changes in subrepository "s"
+  (use --subrepos for recursive commit)
+  [255]
 
 amend with modified subrepo
 
   $ hg ci -R s -m0
-BROKEN: should update .hgsubstate
-  $ hg amend
-  nothing changed
-  [1]
-  $ hg status --change .
-  M a
-
-FIX UP .hgsubstate
-
-  $ hg ci -mfix
-  $ hg rollback -q
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
-
+  $ hg status --change .
+  M .hgsubstate
+  M a
   $ cat .hgsubstate
   f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
 
 revert subrepo change
 
   $ hg up -R s -q null
-BROKEN: should update .hgsubstate
-  $ hg amend
-  nothing changed
-  [1]
-
-FIX UP .hgsubstate
-
-  $ hg ci -mfix
-  $ hg rollback -q
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
-
   $ hg status --change .
   M a
 
@@ -131,21 +102,13 @@ amend with another subrepo
   $ hg ci -R t -Am0
   adding b
   $ echo 't = t' >> .hgsub
-BROKEN: should update .hgsubstate
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
   $ hg status --change .
   M .hgsub
+  M .hgsubstate
   M a
   A b
-
-FIX UP .hgsubstate
-
-  $ hg ci -mfix
-  $ hg rollback -q
-  $ hg amend
-  saved backup bundle to * (glob) (obsstore-off !)
-
   $ cat .hgsubstate
   0000000000000000000000000000000000000000 s
   bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
@@ -161,23 +124,12 @@ add new commit to be amended
 amend with one subrepo dropped
 
   $ echo 't = t' > .hgsub
-BROKEN: should update .hgsubstate
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
   $ hg status --change .
   M .hgsub
+  M .hgsubstate
   M a
-
-FIX UP .hgsubstate
-
-  $ echo 's = s' > .hgsub
-  $ hg amend -q
-  $ echo 't = t' > .hgsub
-  $ hg ci -mfix
-  $ hg rollback -q
-  $ hg amend
-  saved backup bundle to * (glob) (obsstore-off !)
-
   $ cat .hgsubstate
   bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
 
@@ -192,22 +144,11 @@ add new commit to be amended
 amend with .hgsub removed
 
   $ hg rm .hgsub
-BROKEN: should update .hgsubstate
   $ hg amend
   saved backup bundle to * (glob) (obsstore-off !)
   $ hg status --change .
   M a
   R .hgsub
-
-FIX UP .hgsubstate
-
-  $ hg forget .hgsubstate
-  $ hg amend
-  saved backup bundle to * (glob) (obsstore-off !)
-
-  $ hg status --change .
-  M a
-  R .hgsub
   R .hgsubstate
 
   $ cd ..


More information about the Mercurial-devel mailing list