issue-6028: resolves 6028 - return (False, ".") instead of (False, '') stable
authorJames Reynolds <james.glenn.reynolds@gmail.com>
Thu, 13 Dec 2018 17:41:06 +0100
branchstable
changeset 4297 699e25687cc5
parent 4290 09337aae08d4
child 4301 5cbaf5d25443
child 4304 604732387e33
issue-6028: resolves 6028 - return (False, ".") instead of (False, '') Since 4.8, repo[] no longer takes an empty string, so we update to a valid with similar semantic. This value is strange and we should probably use an actual node ID here, however, this is an independent issue.
CHANGELOG
hgext3rd/evolve/evolvecmd.py
tests/test-issue-6028.t
--- a/CHANGELOG	Wed Dec 05 23:15:29 2018 +0800
+++ b/CHANGELOG	Thu Dec 13 17:41:06 2018 +0100
@@ -4,6 +4,7 @@
 8.3.3 - in progress
 -------------------
 
+  * evolve: fix possible crash when the repo changes during evolve (issue-6028)
   * test: avoid leaking `hg serve` process
   * topic: fix error message for the `ngtip` revset
 
--- a/hgext3rd/evolve/evolvecmd.py	Wed Dec 05 23:15:29 2018 +0800
+++ b/hgext3rd/evolve/evolvecmd.py	Thu Dec 13 17:41:06 2018 +0100
@@ -61,7 +61,7 @@
         bool: a boolean value indicating whether the instability was solved
         newnode: if bool is True, then the newnode of the resultant commit
                  formed. newnode can be node, when resolution led to no new
-                 commit. If bool is False, this is ''.
+                 commit. If bool is False, this is ".".
     """
     displayer = None
     if stacktmplt:
@@ -101,7 +101,7 @@
         bool: a boolean value indicating whether the instability was solved
         newnode: if bool is True, then the newnode of the resultant commit
                  formed. newnode can be node, when resolution led to no new
-                 commit. If bool is False, this is ''.
+                 commit. If bool is False, this is ".".
     """
     pctx = orig.p1()
     keepbranch = orig.p1().branch() != orig.branch()
@@ -125,7 +125,7 @@
 
     if not pctx.obsolete():
         ui.warn(_("cannot solve instability of %s, skipping\n") % orig)
-        return (False, '')
+        return (False, ".")
     obs = pctx
     newer = obsutil.successorssets(repo, obs.node())
     # search of a parent which is not killed
@@ -139,7 +139,7 @@
         msg = _("skipping %s: divergent rewriting. can't choose "
                 "destination\n") % obs
         ui.write_err(msg)
-        return (False, '')
+        return (False, ".")
     targets = newer[0]
     assert targets
     if len(targets) > 1:
@@ -157,7 +157,7 @@
                         "ambiguous destination: "
                         "parent split across two branches\n")
                 ui.write_err(msg)
-                return (False, '')
+                return (False, ".")
             target = repo[selectedrev]
         else:
             target = repo[heads.first()]
@@ -177,7 +177,7 @@
     todo = 'hg rebase -r %s -d %s\n' % (orig, target)
     if dryrun:
         repo.ui.write(todo)
-        return (False, '')
+        return (False, ".")
     else:
         repo.ui.note(todo)
         if progresscb:
@@ -201,7 +201,7 @@
         bool: a boolean value indicating whether the instability was solved
         newnode: if bool is True, then the newnode of the resultant commit
                  formed. newnode can be node, when resolution led to no new
-                 commit. If bool is False, this is ''.
+                 commit. If bool is False, this is ".".
     """
     repo = repo.unfiltered()
     bumped = repo[bumped.rev()]
@@ -209,14 +209,14 @@
     if len(bumped.parents()) > 1:
         msg = _('skipping %s : we do not handle merge yet\n') % bumped
         ui.write_err(msg)
-        return (False, '')
+        return (False, ".")
     prec = repo.set('last(allprecursors(%d) and public())', bumped.rev()).next()
     # For now we deny target merge
     if len(prec.parents()) > 1:
         msg = _('skipping: %s: public version is a merge, '
                 'this is not handled yet\n') % prec
         ui.write_err(msg)
-        return (False, '')
+        return (False, ".")
 
     if not ui.quiet or confirm:
         repo.ui.write(_('recreate:'), label='evolve.operation')
@@ -232,7 +232,7 @@
         repo.ui.write(('hg revert --all --rev %s;\n' % bumped))
         repo.ui.write(('hg commit --msg "%s update to %s"\n' %
                        (TROUBLES['PHASEDIVERGENT'], bumped)))
-        return (False, '')
+        return (False, ".")
     if progresscb:
         progresscb()
     tmpctx = bumped
@@ -343,7 +343,7 @@
         bool: a boolean value indicating whether the instability was solved
         newnode: if bool is True, then the newnode of the resultant commit
                  formed. newnode can be node, when resolution led to no new
-                 commit. If bool is False, this is ''.
+                 commit. If bool is False, this is ".".
     """
     repo = repo.unfiltered()
     divergent = repo[divergent.rev()]
@@ -376,7 +376,7 @@
                 "| You should contact your local evolution Guru for help.\n"
                 ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
         ui.write_err(msg)
-        return (False, '')
+        return (False, ".")
     other = others[0]
     evolvestate['other-divergent'] = other.node()
     evolvestate['base'] = base.node()
@@ -390,7 +390,7 @@
                  "| This probably means redoing the merge and using \n"
                  "| `hg prune` to kill older version.\n")
         ui.write_err(hint)
-        return (False, '')
+        return (False, ".")
 
     otherp1 = other.p1().rev()
     divp1 = divergent.p1().rev()
@@ -450,7 +450,7 @@
                  ) % {'d': divergent, 'o': other}
         ui.write_err(msg)
         ui.write_err(hint)
-        return (False, '')
+        return (False, ".")
 
     if not ui.quiet or confirm:
         ui.write(_('merge:'), label='evolve.operation')
@@ -470,7 +470,7 @@
         ui.write(('hg revert --all --rev tip &&\n'))
         ui.write(('hg commit -m "`hg log -r %s --template={desc}`";\n'
                  % divergent))
-        return (False, '')
+        return (False, ".")
 
     evolvestate['resolutionparent'] = resolutionparent
     # relocate the other divergent if required
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-issue-6028.t	Thu Dec 13 17:41:06 2018 +0100
@@ -0,0 +1,123 @@
+This test file test the #6028 issue
+
+evolve fails with mercurial.error.ProgrammingError: unsupported changeid '' of type <type 'str'>
+
+https://bz.mercurial-scm.org/show_bug.cgi?id=6028
+
+Global setup
+============
+
+  $ . $TESTDIR/testlib/common.sh
+  $ cat >> $HGRCPATH <<EOF
+  > [ui]
+  > interactive = true
+  > [phases]
+  > publish=False
+  > [extensions]
+  > evolve =
+  > topic =
+  > EOF
+
+Test
+====
+
+  $ hg init $TESTTMP/issue-6028
+  $ cd $TESTTMP/issue-6028
+
+create initial commit
+  $ echo "0" > 0
+  $ hg ci -Am 0
+  adding 0
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg topics a
+  marked working directory as topic: a
+  $ echo "a" > a
+  $ hg ci -Am a
+  adding a
+  active topic 'a' grew its first changeset
+  (see 'hg help topics' for more information)
+
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg topics b
+  marked working directory as topic: b
+  $ echo "b" > b
+  $ hg ci -Am b
+  adding b
+  active topic 'b' grew its first changeset
+  (see 'hg help topics' for more information)
+
+  $ hg up default
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg branch integration
+  marked working directory as branch integration
+
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a"
+
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged b"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "a bad commit" >> a_bad_commit
+  $ hg add a_bad_commit
+  $ hg ci -m "a bad commit"
+  $ hg up integration
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged a bad commit"
+
+  $ hg up a
+  switching to topic a
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo "aa" >> a
+  $ hg ci -m "aa"
+  $ hg up integration
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge a
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged aa"
+
+  $ hg up b
+  switching to topic b
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo "bb" >> b
+  $ hg ci -m "bb"
+  $ hg up integration
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge b
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "merged bb"
+
+create instability by pruning two changesets, one in a topic, one in a merge
+  $ hg prune -r 5:6
+  2 changesets pruned
+  3 new orphan changesets
+
+  $ hg up 4
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+start the evolve
+  $ hg evolve
+  move:[8] merged aa
+  atop:[4] merged b
+  working directory is now at c920dd828523
+
+evolve creates an obsolete changeset above as 11
+  $ hg evolve -r .
+  cannot solve instability of c920dd828523, skipping
+  cannot solve instability of c920dd828523, skipping