--- a/CHANGELOG Thu Apr 11 21:12:09 2019 +0200
+++ b/CHANGELOG Thu Apr 11 21:43:37 2019 +0200
@@ -10,6 +10,9 @@
* stack: improved and speed --children flag up,
* stack: mention all divergences too.
* evolve: share evolve related cache between `shares`
+ * evolve: improved compatibility with narrow repositories,
+ * evolve: preserve --[no-]update value over --continue,
+ * uncommit: abort if an explicitly given file cannot be uncommitted
8.4.1 - in progress
-------------------
--- a/hgext3rd/evolve/cmdrewrite.py Thu Apr 11 21:12:09 2019 +0200
+++ b/hgext3rd/evolve/cmdrewrite.py Thu Apr 11 21:43:37 2019 +0200
@@ -520,17 +520,47 @@
if disallowunstable and not onahead:
raise error.Abort(_("cannot uncommit in the middle of a stack"))
+ match = scmutil.match(old, pats, opts)
+
+ # Check all explicitly given files; abort if there's a problem.
+ if match.files():
+ s = old.status(old.p1(), match, listclean=True)
+ eligible = set(s.added) | set(s.modified) | set(s.removed)
+
+ badfiles = set(match.files()) - eligible
+
+ # Naming a parent directory of an eligible file is OK, even
+ # if not everything tracked in that directory can be
+ # uncommitted.
+ if badfiles:
+ badfiles -= set([f for f in util.dirs(eligible)])
+
+ try:
+ uipathfn = scmutil.getuipathfn(repo)
+ except AttributeError:
+ uipathfn = match.rel # <= 4.9
+
+ for f in sorted(badfiles):
+ if f in s.clean:
+ hint = _(b"file was not changed in working directory "
+ b"parent")
+ elif repo.wvfs.exists(f):
+ hint = _(b"file was untracked in working directory parent")
+ else:
+ hint = _(b"file does not exist")
+
+ raise error.Abort(_(b'cannot uncommit "%s"')
+ % uipathfn(f), hint=hint)
+
# Recommit the filtered changeset
tr = repo.transaction('uncommit')
if interactive:
opts['all'] = True
- match = scmutil.match(old, pats, opts)
newid = _interactiveuncommit(ui, repo, old, match)
else:
newid = None
includeorexclude = opts.get('include') or opts.get('exclude')
if (pats or includeorexclude or opts.get('all')):
- match = scmutil.match(old, pats, opts)
if not (opts['message'] or opts['logfile']):
opts['message'] = old.description()
message = cmdutil.logmessage(ui, opts)
--- a/hgext3rd/evolve/evolvecmd.py Thu Apr 11 21:12:09 2019 +0200
+++ b/hgext3rd/evolve/evolvecmd.py Thu Apr 11 21:43:37 2019 +0200
@@ -276,43 +276,22 @@
newid = None
replacementnode = None
- # Create the new commit context
- files = set()
- copied = copies.pathcopies(prec, bumped)
- precmanifest = prec.manifest().copy()
- # 3.3.2 needs a list.
- # future 3.4 don't detect the size change during iteration
- # this is fishy
- for key, val in list(bumped.manifest().iteritems()):
- precvalue = precmanifest.get(key, None)
- if precvalue is not None:
- del precmanifest[key]
- if precvalue != val:
- files.add(key)
- files.update(precmanifest) # add missing files
-
- # commit it
- if files: # something to commit!
- def filectxfn(repo, ctx, path):
- if path in bumped:
- fctx = bumped[path]
- flags = fctx.flags()
- mctx = compat.memfilectx(repo, ctx, fctx, flags, copied, path)
- return mctx
- return None
+ # Create the new commit context. This is done by applying the changes from
+ # the precursor to the bumped node onto the precursor. This is effectively
+ # like reverting to the bumped node.
+ wctx = context.overlayworkingctx(repo)
+ wctx.setbase(prec)
+ merge.update(repo, bumped.node(), ancestor=prec, mergeancestor=True,
+ branchmerge=True, force=False, wc=wctx)
+ if not wctx.isempty():
text = '%s update to %s:\n\n' % (TROUBLES['PHASEDIVERGENT'], prec)
text += bumped.description()
-
- new = context.memctx(repo,
- parents=[prec.node(), nodemod.nullid],
- text=text,
- files=files,
- filectxfn=filectxfn,
- user=bumped.user(),
- date=bumped.date(),
- extra=bumped.extra())
-
- newid = repo.commitctx(new)
+ memctx = wctx.tomemctx(text,
+ parents=(prec.node(), nodemod.nullid),
+ date=bumped.date(),
+ extra=bumped.extra(),
+ user=bumped.user())
+ newid = repo.commitctx(memctx)
replacementnode = newid
if newid is None:
repo.ui.status(_('no changes to commit\n'))
@@ -1652,6 +1631,8 @@
evolvestate.delete()
return
startnode = repo.unfiltered()[evolvestate['startnode']]
+ if 'update' in evolvestate:
+ shouldupdate = evolvestate['update']
evolvestate.delete()
elif stopopt:
if not evolvestate:
@@ -1701,7 +1682,8 @@
'revs': list(revs), 'confirm': confirmopt,
'startnode': startnode, 'skippedrevs': [],
'command': 'evolve', 'orphanmerge': False,
- 'bookmarkchanges': [], 'temprevs': [], 'obsmarkers': []}
+ 'bookmarkchanges': [], 'temprevs': [], 'obsmarkers': [],
+ 'update': shouldupdate}
evolvestate.addopts(stateopts)
# lastsolved: keep track of successor of last troubled cset we evolved
# to confirm that if atop msg should be suppressed to remove redundancy
--- a/hgext3rd/evolve/state.py Thu Apr 11 21:12:09 2019 +0200
+++ b/hgext3rd/evolve/state.py Thu Apr 11 21:43:37 2019 +0200
@@ -45,6 +45,9 @@
def __nonzero__(self):
return self.exists()
+ def __contains__(self, key):
+ return key in self.opts
+
def __getitem__(self, key):
return self.opts[key]
--- a/tests/test-evolve-continue.t Thu Apr 11 21:12:09 2019 +0200
+++ b/tests/test-evolve-continue.t Thu Apr 11 21:43:37 2019 +0200
@@ -31,7 +31,7 @@
o 0:8fa14d15e168 added hgignore
() draft
-Simple case of evolve --continue
+Simple case of evolve --continue (with --[no-]update flag)
$ hg up ca1b80f7960a
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -53,7 +53,7 @@
o 0:8fa14d15e168 added hgignore
() draft
- $ hg evolve --all
+ $ hg evolve --all --no-update
move:[4] added d
atop:[5] added c
merging d
@@ -68,12 +68,12 @@
$ hg evolve --continue
evolving 4:c41c793e0ef1 "added d"
- working directory is now at 2a4e03d422e2
+ working directory is now at cb6a2ab625bb
$ hg glog
- @ 6:2a4e03d422e2 added d
+ o 6:2a4e03d422e2 added d
| () draft
- o 5:cb6a2ab625bb added c
+ @ 5:cb6a2ab625bb added c
| () draft
o 2:b1661037fa25 added b
| () draft
@@ -82,6 +82,9 @@
o 0:8fa14d15e168 added hgignore
() draft
+ $ hg up
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
Case when conflicts resolution lead to empty wdir in evolve --continue
$ echo foo > e
@@ -307,8 +310,6 @@
(no more unresolved files)
continue: hg evolve --continue
-XXX: this should have asked for confirmation
-
$ hg evolve --continue<<EOF
> y
> EOF
--- a/tests/test-uncommit.t Thu Apr 11 21:12:09 2019 +0200
+++ b/tests/test-uncommit.t Thu Apr 11 21:43:37 2019 +0200
@@ -514,3 +514,22 @@
(use 'hg prune .' to remove it)
$ hg status
? foo
+
+Bad explicit paths abort, like the bundled commit extension
+
+ $ hg uncommit foo
+ abort: cannot uncommit "foo"
+ (file was untracked in working directory parent)
+ [255]
+
+ $ hg ci -Aqm 'add foo'
+ $ hg uncommit bar
+ abort: cannot uncommit "bar"
+ (file does not exist)
+ [255]
+ $ hg uncommit d
+ abort: cannot uncommit "d"
+ (file was not changed in working directory parent)
+ [255]
+
+ $ hg status