changeset 5520:b40c9ac8b540 mercurial-5.4

test-compat: merge stable into mercurial-5.4
author Anton Shestakov <av6@dwimlabs.net>
date Sun, 06 Sep 2020 05:36:04 +0800
parents 53d3c7a2265c (current diff) 13e589fb61f5 (diff)
children af0458d91d10 72d88e491a19
files
diffstat 14 files changed, 204 insertions(+), 196 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jul 31 18:09:18 2020 +0800
+++ b/.hgtags	Sun Sep 06 05:36:04 2020 +0800
@@ -87,3 +87,4 @@
 583dc6ef3eb21fbf6574021136f32b8a1163506c 9.3.0
 8d955635cf457aaa4810d77740721d4275001f74 9.3.1
 27d57ca8686590867e62e3d42c96bad84a5f56ef 10.0.0
+fb543438704b73b22023a493c9ef76fc8746b796 10.0.1
--- a/CHANGELOG	Fri Jul 31 18:09:18 2020 +0800
+++ b/CHANGELOG	Sun Sep 06 05:36:04 2020 +0800
@@ -1,7 +1,23 @@
 Changelog
 =========
 
-10.0.1 - in progress
+10.0.2 - in progress
+--------------------
+
+  * py3: use '%d' for formatting revision numbers in stable range cache warning
+    (issue6390)
+
+  * split: correctly handle discard action after previously splitting changes
+    into more than one commit
+
+  * uncommit: fix situation where added file would be left in a wrong state
+
+topic (0.19.2)
+
+  * revset: when processing `topic(REVSET)`, no longer return changesets
+    without topic from REVSET
+
+10.0.1 -- 2020-07-31
 --------------------
 
   * compatibility with Mercurial 5.5
--- a/debian/changelog	Fri Jul 31 18:09:18 2020 +0800
+++ b/debian/changelog	Sun Sep 06 05:36:04 2020 +0800
@@ -1,3 +1,9 @@
+mercurial-evolve (10.0.1-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Anton Shestakov <av6@dwimlabs.net>  Fri, 31 Jul 2020 19:44:25 +0800
+
 mercurial-evolve (10.0.0-1) unstable; urgency=medium
 
   * new upstream release
--- a/hgext3rd/evolve/cmdrewrite.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/evolve/cmdrewrite.py	Sun Sep 06 05:36:04 2020 +0800
@@ -341,100 +341,49 @@
     newid = repo.commitctx(new)
     return newid
 
-def _uncommitdirstate(repo, oldctx, match, interactive):
-    """Fix the dirstate after switching the working directory from
-    oldctx to a copy of oldctx not containing changed files matched by
-    match.
+# TODO: call core's version once we've dropped support for hg <= 4.9
+def movedirstate(repo, newctx, match=None):
+    """Move the dirstate to newctx and adjust it as necessary.
+
+    A matcher can be provided as an optimization. It is probably a bug to pass
+    a matcher that doesn't match all the differences between the parent of the
+    working copy and newctx.
     """
-    ctx = repo[b'.']
+    oldctx = repo[b'.']
     ds = repo.dirstate
-    copies = dict(ds.copies())
-    if interactive:
-        # In interactive cases, we will find the status between oldctx and ctx
-        # and considering only the files which are changed between oldctx and
-        # ctx, and the status of what changed between oldctx and ctx will help
-        # us in defining the exact behavior
-        st = repo.status(oldctx, ctx, match=match)
-        for f in st.modified:
-            # These are files which are modified between oldctx and ctx which
-            # contains two cases: 1) Were modified in oldctx and some
-            # modifications are uncommitted
-            # 2) Were added in oldctx but some part is uncommitted (this cannot
-            # contain the case when added files are uncommitted completely as
-            # that will result in status as removed not modified.)
-            # Also any modifications to a removed file will result the status as
-            # added, so we have only two cases. So in either of the cases, the
-            # resulting status can be modified or clean.
-            if ds[f] == b'r':
-                # But the file is removed in the working directory, leaving that
-                # as removed
-                continue
+    dscopies = dict(ds.copies())
+    ds.setparents(newctx.node(), node.nullid)
+    s = newctx.status(oldctx, match=match)
+    for f in s.modified:
+        if ds[f] == b'r':
+            # modified + removed -> removed
+            continue
+        ds.normallookup(f)
+
+    for f in s.added:
+        if ds[f] == b'r':
+            # added + removed -> unknown
+            ds.drop(f)
+        elif ds[f] != b'a':
+            ds.add(f)
+
+    for f in s.removed:
+        if ds[f] == b'a':
+            # removed + added -> normal
             ds.normallookup(f)
-
-        for f in st.added:
-            # These are the files which are added between oldctx and ctx(new
-            # one), which means the files which were removed in oldctx
-            # but uncommitted completely while making the ctx
-            # This file should be marked as removed if the working directory
-            # does not adds it back. If it's adds it back, we do a normallookup.
-            # The file can't be removed in working directory, because it was
-            # removed in oldctx
-            if ds[f] == b'a':
-                ds.normallookup(f)
-                continue
+        elif ds[f] != b'r':
             ds.remove(f)
 
-        for f in st.removed:
-            # These are files which are removed between oldctx and ctx, which
-            # means the files which were added in oldctx and were completely
-            # uncommitted in ctx. If a added file is partially uncommitted, that
-            # would have resulted in modified status, not removed.
-            # So a file added in a commit, and uncommitting that addition must
-            # result in file being stated as unknown.
-            if ds[f] == b'r':
-                # The working directory say it's removed, so lets make the file
-                # unknown
-                ds.drop(f)
-                continue
-            ds.add(f)
-    else:
-        st = repo.status(oldctx.p1(), oldctx, match=match)
-        for f in st.modified:
-            if ds[f] == b'r':
-                # modified + removed -> removed
-                continue
-            ds.normallookup(f)
-
-        for f in st.added:
-            if ds[f] == b'r':
-                # added + removed -> unknown
-                ds.drop(f)
-            elif ds[f] != b'a':
-                ds.add(f)
-
-        for f in st.removed:
-            if ds[f] == b'a':
-                # removed + added -> normal
-                ds.normallookup(f)
-            elif ds[f] != b'r':
-                ds.remove(f)
-
     # Merge old parent and old working dir copies
-    oldcopies = {}
-    if interactive:
-        # Interactive had different meaning of the variables so restoring the
-        # original meaning to use them
-        st = repo.status(oldctx.p1(), oldctx, match=match)
-    for f in (st.modified + st.added):
-        src = oldctx[f].renamed()
-        if src:
-            oldcopies[f] = src[0]
-    oldcopies.update(copies)
-    copies = dict((dst, oldcopies.get(src, src))
-                  for dst, src in oldcopies.items())
+    oldcopies = copies.pathcopies(newctx, oldctx, match)
+    oldcopies.update(dscopies)
+    newcopies = {
+        dst: oldcopies.get(src, src)
+        for dst, src in oldcopies.items()
+    }
     # Adjust the dirstate copies
-    for dst, src in copies.items():
-        if (src not in ctx or dst in ctx or ds[dst] != b'a'):
+    for dst, src in newcopies.items():
+        if src not in newctx or dst in newctx or ds[dst] != b'a':
             src = None
         ds.copy(src, dst)
 
@@ -567,8 +516,7 @@
             hg.updaterepo(repo, newid, True)
         else:
             with repo.dirstate.parentchange(), compat.parentchange(repo):
-                repo.dirstate.setparents(newid, node.nullid)
-                _uncommitdirstate(repo, old, match, interactive)
+                movedirstate(repo, repo[newid], match)
         if not repo[newid].files():
             ui.warn(_(b"new changeset is empty\n"))
             ui.status(_(b"(use 'hg prune .' to remove it)\n"))
@@ -1307,7 +1255,13 @@
                         # diff action or by showing the remaining and
                         # prompting for confirmation
                         ui.status(_(b'discarding remaining changes\n'))
-                        target = newcommits[0]
+                        target = newcommits[-1]
+                        args = []
+                        kwargs = {}
+                        code = cmdutil.revert.__code__
+                        # hg <= 5.5 (8c466bcb0879)
+                        if r'parents' in code.co_varnames[:code.co_argcount]:
+                            args.append((target, node.nullid))
                         if pats:
                             status = repo.status(match=matcher)
                             dirty = set()
@@ -1315,12 +1269,10 @@
                             dirty.update(status.added)
                             dirty.update(status.removed)
                             dirty.update(status.deleted)
-                            dirty = sorted(dirty)
-                            cmdutil.revert(ui, repo, repo[target],
-                                           (target, node.nullid), *dirty)
+                            args += sorted(dirty)
                         else:
-                            cmdutil.revert(ui, repo, repo[target],
-                                           (target, node.nullid), all=True)
+                            kwargs[r'all'] = True
+                        cmdutil.revert(ui, repo, repo[target], *args, **kwargs)
                     elif nextaction == b'?':
                         nextaction = None
                         ui.write(_(b"y - yes, continue selection\n"))
--- a/hgext3rd/evolve/evolvecmd.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/evolve/evolvecmd.py	Sun Sep 06 05:36:04 2020 +0800
@@ -642,8 +642,7 @@
         otherdiv = repo[othernode]
 
         with repo.dirstate.parentchange(), compat.parentchange(repo):
-            repo.dirstate.setparents(publicnode, nodemod.nullid)
-            dirstatedance(repo, divergent, publicnode, None)
+            cmdrewrite.movedirstate(repo, repo[publicnode])
         # check if node to be committed has changes same as public one
         s = publicdiv.status()
         if not (s.added or s.removed or s.deleted or s.modified):
@@ -655,9 +654,7 @@
             return (True, publicnode)
 
     with repo.dirstate.parentchange(), compat.parentchange(repo):
-        repo.dirstate.setparents(resparent, nodemod.nullid)
-
-    dirstatedance(repo, divergent, resparent, None)
+        cmdrewrite.movedirstate(repo, repo[resparent])
 
     # merge the branches
     mergebranches(repo, divergent, other, base)
@@ -798,73 +795,6 @@
                              metadata=metadata, ui=repo.ui)
         repo.filteredrevcache.clear()
 
-def dirstatedance(repo, oldparent, newparent, match):
-    """utility function to fix the dirstate when we change parents from
-    oldparent to newparent with a dirty working directory using
-    repo.dirstate.setparents()
-
-    Lets refer oldparent as Pold
-               newparent as Pnew
-
-    Now when we are on oldparent with a dirty working directory, there are three
-    types of files which we are concerned about. They are files having modified,
-    added and removed status.
-
-    Lets refer modified files as Fm
-               added files as Fa
-               removed files as Fr
-
-    Now, between Pold and Pnew, files can be modified, files can be added, files
-    can be removed.
-
-    Lets refer modification of a file between Pold to Pnew as Cm
-               addition of a file between Pold to Pnew as Ca
-               removal of a file between Pold to Pnew as Cr
-
-    Now let's play combinations and permutations:
-
-    |---------------------------------------------------------------|
-    | Type of file |  Changes between |   End status with Pnew as   |
-    |   in wdir    |    Pold -> Pnew  |       wdir parent           |
-    |--------------|------------------|-----------------------------|
-    |              |                  |                             |
-    |   Fm         |      Cm          |       Modified or clean     |
-    |--------------|------------------|-----------------------------|
-    |   Fm         |      Cr          |           Added             |
-    |--------------|------------------|-----------------------------|
-    |   Fm         |      Ca          |       Not possible (1)      |
-    |--------------|------------------|-----------------------------|
-    |   Fa         |      Ca          |       Modified or clean     |
-    |--------------|------------------|-----------------------------|
-    |   Fa         |      Cm          |       Not possible (2)      |
-    |--------------|------------------|-----------------------------|
-    |   Fa         |      Cr          |       Not possible (2)      |
-    |--------------|------------------|-----------------------------|
-    |   Fr         |      Cr          | File should be untracked (3)|
-    |--------------|------------------|-----------------------------|
-    |   Fr         |      Ca          |       Not possible (4)      |
-    |--------------|------------------|-----------------------------|
-    |   Fr         |      Cm          |           Removed           |
-    |--------------|------------------|-----------------------------|
-
-    (1): File is modified in wdir, it means file was present in Pold, so
-         addition of that file between Pold to Pnew is not possible
-
-    (2): File was added in wdir, it means file was not present in Pold, so
-         deletion or modification of that file from Pold to Pnew is not possible
-
-    (3): File should be dropped from the dirstate, Pnew has it removed, so no
-         need to mark that removed again
-
-    (4): File was removed in wdir, it means file was present in Pold, so
-         addition of that file between Pold to Pnew is not possible
-
-    """
-
-    # falling back to an existing function, in future we should have logic in
-    # this function only
-    cmdrewrite._uncommitdirstate(repo, oldparent, match, True)
-
 def mergehook(repo, base, divergent, other):
     """function which extensions can wrap and merge data introduced by them
     while resolving content-divergence"""
--- a/hgext3rd/evolve/metadata.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/evolve/metadata.py	Sun Sep 06 05:36:04 2020 +0800
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-__version__ = b'10.0.1.dev'
-testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4'
+__version__ = b'10.0.2.dev'
+testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5'
 minimumhgversion = b'4.6'
 buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/rewind.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/evolve/rewind.py	Sun Sep 06 05:36:04 2020 +0800
@@ -151,8 +151,14 @@
                     revertopts = {'no_backup': True, 'all': True,
                                   'rev': oldctx.node()}
                     with ui.configoverride({(b'ui', b'quiet'): True}):
-                        cmdutil.revert(repo.ui, repo, oldctx,
-                                       repo.dirstate.parents(), **revertopts)
+                        code = cmdutil.revert.__code__
+                        # hg <= 5.5 (8c466bcb0879)
+                        if r'parents' in code.co_varnames[:code.co_argcount]:
+                            cmdutil.revert(repo.ui, repo, oldctx,
+                                           repo.dirstate.parents(),
+                                           **revertopts)
+                        else:
+                            cmdutil.revert(repo.ui, repo, oldctx, **revertopts)
                 else:
                     hg.updaterepo(repo, update_target, False)
 
--- a/hgext3rd/evolve/stablerangecache.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/evolve/stablerangecache.py	Sun Sep 06 05:36:04 2020 +0800
@@ -335,7 +335,7 @@
                 # to add. This will confuse sqlite
                 msg = _(b'stable-range cache: skipping write, '
                         b'database drifted under my feet\n')
-                hint = _(b'(disk: %s-%s vs mem: %s-%s)\n')
+                hint = _(b'(disk: %s-%d vs mem: %s-%d)\n')
                 data = (nodemod.hex(meta[2]), meta[1],
                         nodemod.hex(self._ondisktipnode), self._ondisktiprev)
                 repo.ui.warn(msg)
--- a/hgext3rd/pullbundle.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/pullbundle.py	Sun Sep 06 05:36:04 2020 +0800
@@ -93,9 +93,9 @@
 
 from mercurial.i18n import _
 
-__version__ = b'0.1.1'
-testedwith = b'4.4 4.5 4.6 4.7.1'
-minimumhgversion = b'4.4'
+__version__ = b'0.1.3.dev'
+testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5'
+minimumhgversion = b'4.6'
 buglink = b'https://bz.mercurial-scm.org/'
 
 cmdtable = {}
--- a/hgext3rd/topic/__init__.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/topic/__init__.py	Sun Sep 06 05:36:04 2020 +0800
@@ -202,9 +202,9 @@
               b'topic.active': b'green',
               }
 
-__version__ = b'0.19.1.dev'
+__version__ = b'0.19.2.dev'
 
-testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4'
+testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5'
 minimumhgversion = b'4.6'
 buglink = b'https://bz.mercurial-scm.org/'
 
--- a/hgext3rd/topic/revset.py	Fri Jul 31 18:09:18 2020 +0800
+++ b/hgext3rd/topic/revset.py	Sun Sep 06 05:36:04 2020 +0800
@@ -67,8 +67,6 @@
     topics.discard(b'')
 
     def matches(r):
-        if r in s:
-            return True
         topic = repo[r].topic()
         if not topic:
             return False
--- a/tests/test-split.t	Fri Jul 31 18:09:18 2020 +0800
+++ b/tests/test-split.t	Sun Sep 06 05:36:04 2020 +0800
@@ -1285,3 +1285,85 @@
      @@ -0,0 +1,1 @@
      +a
   
+  $ cd ..
+
+Discard after splitting into more than one changeset
+
+  $ hg init discard-after-many
+  $ cd discard-after-many
+
+  $ echo 0 > num
+  $ cat > editor.sh << '__EOF__'
+  > NUM=$(cat num)
+  > NUM=`expr "$NUM" + 1`
+  > echo "$NUM" > num
+  > echo "split$NUM" > "$1"
+  > __EOF__
+  $ export HGEDITOR="\"sh\" \"editor.sh\""
+
+  $ echo a > a
+  $ echo b > b
+  $ echo c > c
+  $ hg add a b c
+  $ hg ci -m 'a b c'
+
+XXX: this shouldn't ask to re-examine changes in b and definitely shouldn't revert b
+
+  $ hg split << EOF
+  > f
+  > d
+  > y
+  > f
+  > d
+  > d
+  > EOF
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  adding a
+  adding b
+  adding c
+  diff --git a/a b/a
+  new file mode 100644
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] f
+  
+  diff --git a/b b/b
+  new file mode 100644
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] d
+  
+  created new head
+  (consider using topic for lightweight branches. See 'hg help topic')
+  continue splitting? [Ycdq?] y
+  diff --git a/b b/b
+  new file mode 100644
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] f
+  
+  diff --git a/c b/c
+  new file mode 100644
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] d
+  
+  continue splitting? [Ycdq?] d
+  discarding remaining changes
+  forgetting c
+
+  $ hg glog -p
+  @  2:c2c6f4d8c766 split2 (draft)
+  |  diff --git a/b b/b
+  |  new file mode 100644
+  |  --- /dev/null
+  |  +++ b/b
+  |  @@ -0,0 +1,1 @@
+  |  +b
+  |
+  o  1:fb91c6249a20 split1 (draft)
+     diff --git a/a b/a
+     new file mode 100644
+     --- /dev/null
+     +++ b/a
+     @@ -0,0 +1,1 @@
+     +a
+  
+
+  $ cd ..
--- a/tests/test-topic.t	Fri Jul 31 18:09:18 2020 +0800
+++ b/tests/test-topic.t	Sun Sep 06 05:36:04 2020 +0800
@@ -750,12 +750,18 @@
      fran (1 changesets)
   $ hg log -r 'topic(.)'
 (no output is expected)
+
+  $ hg up 8
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo test > gamma
+  $ hg ci -m non-topic
+  $ hg log -r 'topic(.)'
+
   $ hg co fran
   switching to topic fran
-  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg log -r 'topic(.)'
   changeset:   9:0469d521db49
-  tag:         tip
   topic:       fran
   parent:      3:a53952faf762
   user:        test
@@ -801,19 +807,26 @@
   created new head
   (consider using topic for lightweight branches. See 'hg help topic')
   $ hg log -Gr 'draft()'
-  @  changeset:   10:4073470c35e1
+  @  changeset:   11:4073470c35e1
   |  tag:         tip
+  |  parent:      9:0469d521db49
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     fran?
   |
-  o  changeset:   9:0469d521db49
-  |  topic:       fran
-  |  parent:      3:a53952faf762
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     start on fran
-  |
+  | o  changeset:   10:de75ec1bdbe8
+  | |  parent:      8:ae074045b7a7
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     non-topic
+  | |
+  o |  changeset:   9:0469d521db49
+  | |  topic:       fran
+  | |  parent:      3:a53952faf762
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     start on fran
+  | |
 
   $ hg topics
      fran (1 changesets)
--- a/tests/test-uncommit.t	Fri Jul 31 18:09:18 2020 +0800
+++ b/tests/test-uncommit.t	Sun Sep 06 05:36:04 2020 +0800
@@ -355,6 +355,8 @@
   $ hg cat b --rev 0
   b: no such file in rev 07f494440405
   [1]
+  $ hg status
+  A aa
   $ hg uncommit --rev . b
   abort: cannot uncommit to parent changeset
   [255]
@@ -362,6 +364,9 @@
   $ hg cat b --rev .
   b: no such file in rev 5b27f6b17da2
   [1]
+  $ hg status
+  A aa
+  A b
 
 Test uncommiting predecessors
 
@@ -421,9 +426,9 @@
   R m
   R n
   $ hg status
+  M b
   M d
   A aa
-  R b
   $ hg amend --extract j
   $ hg status --change .
   M o
@@ -438,10 +443,10 @@
   R m
   R n
   $ hg status
+  M b
   M d
   M j
   A aa
-  R b
 
 (with all)
 
@@ -450,6 +455,7 @@
   (use 'hg prune .' to remove it)
   $ hg status --change .
   $ hg status
+  M b
   M d
   M j
   M o
@@ -459,7 +465,6 @@
   A h
   A k
   A l
-  R b
   R c
   R f
   R g
@@ -472,11 +477,10 @@
 
   $ hg amend
   $ hg status
-  ? b
 
   $ hg diff -c . --stat
    aa |  1 +
-   b  |  1 -
+   b  |  1 +
    c  |  1 -
    d  |  1 +
    e  |  1 +
@@ -490,7 +494,7 @@
    m  |  1 -
    n  |  1 -
    o  |  1 +
-   15 files changed, 9 insertions(+), 6 deletions(-)
+   15 files changed, 10 insertions(+), 5 deletions(-)
   $ hg uncommit --revert --all
   new changeset is empty
   (use 'hg prune .' to remove it)