--- a/CHANGELOG Thu Dec 13 17:40:41 2018 +0000
+++ b/CHANGELOG Thu Dec 13 18:57:49 2018 +0100
@@ -19,6 +19,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 Thu Dec 13 17:40:41 2018 +0000
+++ b/hgext3rd/evolve/evolvecmd.py Thu Dec 13 18:57:49 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 18:57:49 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