Patchwork [1,of,6,V2] scmutil: make cleanupnodes handle filtered node

login
register
mail settings
Submitter Jun Wu
Date July 8, 2017, 2:11 a.m.
Message ID <997d39aaaceb787983a8.1499479884@x1c>
Download mbox | patch
Permalink /patch/22118/
State Accepted
Headers show

Comments

Jun Wu - July 8, 2017, 2:11 a.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1498514917 25200
#      Mon Jun 26 15:08:37 2017 -0700
# Node ID 997d39aaaceb787983a8d61424d67ef178a7c02c
# Parent  e714159860fd0872ae0555bb07546aa7e9f700e0
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 997d39aaaceb
scmutil: make cleanupnodes handle filtered node

In some valid usecases, the "mapping" received by scmutil.cleanupnodes have
filtered nodes. Use unfiltered repo to access them correctly.

The added test case will fail with the old cleanupnodes code.

This is important to migrate histedit to use the cleanupnodes API.
via Mercurial-devel - July 8, 2017, 4:41 a.m.
On Fri, Jul 7, 2017 at 7:11 PM, Jun Wu <quark@fb.com> wrote:
> diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
> --- a/tests/test-obsolete-divergent.t
> +++ b/tests/test-obsolete-divergent.t
> @@ -618,2 +620,47 @@ successors-set. (report [A,B] not [A] +
>
>    $ cd ..
> +
> +Use scmutil.cleanupnodes API to create divergence
> +
> +  $ hg init cleanupnodes
> +  $ cd cleanupnodes
> +  $ hg debugdrawdag <<'EOS'
> +  >   B1  B3 B4
> +  >   |     \|
> +  >   A      Z
> +  > EOS
> +
> +  $ hg update -q B1
> +  $ echo 3 >> B
> +  $ hg commit --amend -m B2

Did you mean to use your new drawdag syntax (comments) to create this
obsmarker? Just checking; I'm fine with it as is.
Jun Wu - July 8, 2017, 4:59 a.m.
Excerpts from Martin von Zweigbergk's message of 2017-07-07 21:41:05 -0700:
> Did you mean to use your new drawdag syntax (comments) to create this
> obsmarker? Just checking; I'm fine with it as is.

Good catch. The test could be simplified a bit using the new syntax.

Drawdag change was intended to be used in multi-dest rebase series and I
forgot it could be used here too.

Patch

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -620,7 +620,10 @@  def cleanupnodes(repo, mapping, operatio
             # some obsstore logic.
             # NOTE: the filtering and sorting might belong to createmarkers.
-            isobs = repo.obsstore.successors.__contains__
-            sortfunc = lambda ns: repo.changelog.rev(ns[0])
-            rels = [(repo[n], (repo[m] for m in s))
+            # Unfiltered repo is needed since nodes in mapping might be hidden.
+            unfi = repo.unfiltered()
+            isobs = unfi.obsstore.successors.__contains__
+            torev = unfi.changelog.rev
+            sortfunc = lambda ns: torev(ns[0])
+            rels = [(unfi[n], (unfi[m] for m in s))
                     for n, s in sorted(mapping.items(), key=sortfunc)
                     if s or not isobs(n)]
diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
--- a/tests/test-obsolete-divergent.t
+++ b/tests/test-obsolete-divergent.t
@@ -11,4 +11,6 @@  Enable obsolete
   > [experimental]
   > evolution=createmarkers
+  > [extensions]
+  > drawdag=$TESTDIR/drawdag.py
   > [alias]
   > debugobsolete = debugobsolete -d '0 0'
@@ -618,2 +620,47 @@  successors-set. (report [A,B] not [A] + 
 
   $ cd ..
+
+Use scmutil.cleanupnodes API to create divergence
+
+  $ hg init cleanupnodes
+  $ cd cleanupnodes
+  $ hg debugdrawdag <<'EOS'
+  >   B1  B3 B4
+  >   |     \|
+  >   A      Z
+  > EOS
+
+  $ hg update -q B1
+  $ echo 3 >> B
+  $ hg commit --amend -m B2
+  $ cat > $TESTTMP/scmutilcleanup.py <<EOF
+  > from mercurial import registrar, scmutil
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > @command('cleanup')
+  > def cleanup(ui, repo):
+  >     def node(expr):
+  >         unfi = repo.unfiltered()
+  >         rev = unfi.revs(expr).first()
+  >         return unfi.changelog.node(rev)
+  >     with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
+  >         mapping = {node('desc(B1)'): [node('desc(B3)')],
+  >                    node('desc(B3)'): [node('desc(B4)')]}
+  >         scmutil.cleanupnodes(repo, mapping, 'test')
+  > EOF
+
+  $ rm .hg/localtags
+  $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
+  $ hg log -G -T '{rev}:{node|short} {desc} {troubles}' -r 'sort(all(), topo)'
+  @  5:1a2a9b5b0030 B2 divergent
+  |
+  | o  4:70d5a63ca112 B4 divergent
+  | |
+  | o  1:48b9aae0607f Z
+  |
+  o  0:426bada5c675 A
+  
+  $ hg debugobsolete
+  a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+  ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}