[PATCH evolve-ext V2] uncommit: abort if an explicitly given file cannot be uncommitted (BC)

Matt Harbison mharbison72 at gmail.com
Wed Apr 10 22:36:53 EDT 2019


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1554259321 14400
#      Tue Apr 02 22:42:01 2019 -0400
# Node ID 893eedfb73d327928cfbdfa2250fd89b34998045
# Parent  99dbe605fda59aa673023043a0b14235bbef0dfc
uncommit: abort if an explicitly given file cannot be uncommitted (BC)

This corresponds to f4147ca63d39 in the core uncommit extension.

diff --git a/hgext3rd/evolve/cmdrewrite.py b/hgext3rd/evolve/cmdrewrite.py
--- a/hgext3rd/evolve/cmdrewrite.py
+++ b/hgext3rd/evolve/cmdrewrite.py
@@ -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)
diff --git a/tests/test-uncommit.t b/tests/test-uncommit.t
--- a/tests/test-uncommit.t
+++ b/tests/test-uncommit.t
@@ -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


More information about the Mercurial-devel mailing list