changeset 4509:5875079f2ff5 stable

branching: merge stable into default
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 11 Apr 2019 21:43:37 +0200
parents fce8f5ca10d8 (current diff) 79de4e86d9a4 (diff)
children 0b86c05440e9 bea4c5c3b50c
files
diffstat 6 files changed, 83 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- 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