histedit: simplify computation of `newchildren` during --continue
We are now checking for any changesets between the previous `parentctx` and the
current working directory parent. If the current working directory parent is
inconsistent, we abort.
This change is useful as it simplifies the --continue process, easing upcoming
changes.
While working on this changeset, I spotted an unhandled corner case. This corner
case is now documented and have an appropriate issue in the tracker (
issue3655).
However, the corner case is still unhandled. handling this test case would
required some additional work:
- actually decide what the proper behavior should be:
- change content of "histedit-state" to add missing data necessary to detect
the situation
- add proper testcase,
But leaving the case unhandled is "okay":
- this is not a regression,
- this is not the purpose of the current series,
- the freeze was near and I had more critical stuff to attend to,
- this is a simple but non trivial, (see above)
--- a/hgext/histedit.py Wed Oct 03 19:43:10 2012 +0200
+++ b/hgext/histedit.py Wed Oct 10 06:20:14 2012 +0200
@@ -550,21 +550,20 @@
def bootstrapcontinue(ui, repo, parentctx, existing, replacemap, rules,
tmpnodes, created, replaced, opts):
- currentparent, wantnull = repo.dirstate.parents()
- # existing is the list of revisions initially considered by
- # histedit. Here we use it to list new changesets, descendants
- # of parentctx without an 'existing' changeset in-between. We
- # also have to exclude 'existing' changesets which were
- # previously dropped.
- descendants = set(c.node() for c in
- repo.set('(%d::) - %d', parentctx, parentctx))
- notdropped = set(n for n in existing if n in descendants and
- (n not in replacemap or replacemap[n] in descendants))
- # Discover any nodes the user has added in the interim. We can
- # miss changesets which were dropped and recreated the same.
- newchildren = list(c.node() for c in repo.set(
- 'sort(%ln - (%ln or %ln::))', descendants, existing, notdropped))
action, currentnode = rules.pop(0)
+ # is there any new commit between the expected parent and "."
+ #
+ # note: does not take non linear new change in account (but previous
+ # implementation didn't used them anyway (issue3655)
+ newchildren = [c.node() for c in repo.set('(%d::.)', parentctx)]
+ if not newchildren:
+ # `parentctxnode` should match but no result. This means that
+ # currentnode is not a descendant from parentctxnode.
+ msg = _('working directory parent is not a descendant of %s')
+ hint = _('update to %s or descendant and run "hg histedit '
+ '--continue" again') % parentctx
+ raise util.Abort(msg % parentctx, hint=hint)
+ newchildren.pop(0) # remove parentctxnode
if action in ('f', 'fold'):
tmpnodes.extend(newchildren)
else:
--- a/tests/test-histedit-edit.t Wed Oct 03 19:43:10 2012 +0200
+++ b/tests/test-histedit-edit.t Wed Oct 10 06:20:14 2012 +0200
@@ -66,6 +66,19 @@
abort: Make changes as needed, you may commit or record as needed now.
When you are finished, run hg histedit --continue to resume.
+Go at a random point and try to continue
+
+ $ hg id -n
+ 3+
+ $ hg up 0
+ 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+ $ HGEDITOR='echo foobaz > ' hg histedit --continue
+ abort: working directory parent is not a descendant of 055a42cdd887
+ (update to 055a42cdd887 or descendant and run "hg histedit --continue" again)
+ [255]
+ $ hg up 3
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
commit, then edit the revision
$ hg ci -m 'wat'
created new head