Patchwork [evolve-ext-V2] evolve: dedupe divergents when running evolve --all --any or evolve --rev

login
register
mail settings
Submitter Laurent Charignon
Date June 26, 2015, 8:24 p.m.
Message ID <c94b086806fff40e7f21.1435350278@lcharignon-mbp.dhcp.thefacebook.com>
Download mbox | patch
Permalink /patch/9792/
State Accepted
Headers show

Comments

Laurent Charignon - June 26, 2015, 8:24 p.m.
# HG changeset patch
# User Laurent Charignon <lcharignon@fb.com>
# Date 1435190063 25200
#      Wed Jun 24 16:54:23 2015 -0700
# Node ID c94b086806fff40e7f219259306a58ecd39ba43b
# Parent  5dfb18b98a5547ee1e4dced590d4e0151446e050
evolve: dedupe divergents when running evolve --all --any or evolve --rev

Before this patch, when running evolve --all --any or evolve --rev with the
--divergent flag, we were selecting all of the divergents. After solving the
first one, its counterparts would get pruned and potentially hidden which would
crash when trying to resolve them. This patch introduces logic to dedupe the
divergents to be resolved by keeping only one per group of divergent with the
lower revision number.

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -1415,6 +1415,24 @@  def builddependencies(repo, revs):
                 rdependencies[succ].add(r)
     return dependencies, rdependencies
 
+def _dedupedivergents(repo, revs):
+    """Dedupe the divergents revs in revs to get one from each group with the
+    lowest revision numbers
+    """
+    repo = repo.unfiltered()
+    res = set()
+    # To not reevaluate divergents of the same group once one is encountered
+    discarded = set()
+    for rev in revs:
+        if rev in discarded:
+            continue
+        divergent = repo[rev]
+        base, others = divergentdata(divergent)
+        othersrevs = [o.rev() for o in others]
+        res.add(min([divergent.rev()] + othersrevs))
+        discarded.update(othersrevs)
+    return res
+
 def _selectrevs(repo, allopt, revopt, anyopt, targetcat):
     """select troubles in repo matching according to given options"""
     revs = set()
@@ -1424,6 +1442,9 @@  def _selectrevs(repo, allopt, revopt, an
             revs = scmutil.revrange(repo, revopt) & revs
         elif not anyopt and targetcat == 'unstable':
             revs = set(_aspiringdescendant(repo, repo.revs('(.::) - obsolete()::')))
+        if targetcat == 'divergent':
+            # Pick one divergent per group of divergents
+            revs = _dedupedivergents(repo, revs)
     elif anyopt:
         revs = repo.revs('first(%s())' % (targetcat))
     elif targetcat == 'unstable':
diff --git a/tests/test-divergent.t b/tests/test-divergent.t
new file mode 100644
--- /dev/null
+++ b/tests/test-divergent.t
@@ -0,0 +1,70 @@ 
+Tests the resolution of divergence
+
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > fold=-d "0 0"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > [phases]
+  > publish = False
+  > [diff]
+  > git = 1
+  > unified = 0
+  > [ui]
+  > logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline} [{troubles}]\n
+  > [extensions]
+  > hgext.graphlog=
+  > EOF
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -m "add $1"
+  > }
+
+  $ mkcommits() {
+  >   for i in $@; do mkcommit $i ; done
+  > }
+
+Basic test of divergence: two divergent changesets with the same parents
+With --all --any we dedupe the divergent and solve the divergence once
+
+  $ hg init test1
+  $ cd test1
+  $ mkcommits _a _b
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent1
+  created new head
+  $ hg up "desc(_a)"
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit bdivergent2
+  created new head
+  $ hg prune -s "desc(bdivergent1)" "desc(_b)"
+  1 changesets pruned
+  $ hg prune -s "desc(bdivergent2)" "desc(_b)" --hidden
+  1 changesets pruned
+  2 new divergent changesets
+  $ hg log -G
+  @  3:e708fd28d5cf@default(draft) add bdivergent2 [divergent]
+  |
+  | o  2:c2f698071cba@default(draft) add bdivergent1 [divergent]
+  |/
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+  $ hg evolve --all --any --divergent
+  merge:[2] add bdivergent1
+  with: [3] add bdivergent2
+  base: [1] add _b
+  updating to "local" conflict
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at c26f1d3baed2
+  $ hg log -G
+  @  5:c26f1d3baed2@default(draft) add bdivergent1 []
+  |
+  o  0:135f39f4bd78@default(draft) add _a []
+  
+  $ cd ..