[PATCH 2 of 2] Cleaner semantic for remove --after by adding a --keep option

mathieu.clabaut at gmail.com mathieu.clabaut at gmail.com
Sat Dec 8 08:40:47 CST 2007


# HG changeset patch
# User Mathieu Clabaut <mathieu.clabaut at gmail.com>
# Date 1197124620 -3600
# Node ID b79453994f7ce7376ef7ff13dd56ad4a7c93ca04
# Parent  b76d9044a0e5751faa8a6b0b5e931ac53246315f
Cleaner semantic for remove --after by adding a --keep option.
hg remove has now 3 options : --after, --keep and --force
--after only removes file already deleted
--keep always prevent the removed files to be deleted
--force forces removing and deletion of file otherwise not removed
Note that --keep has precedence over --force
Before, --after was used either for keeping or for removing after, and it didn't allow to keep locally modified files.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2002,16 +2002,18 @@ def remove(ui, repo, *pats, **opts):
 
     This only removes files from the current branch, not from the
     entire project history.  If the files still exist in the working
-    directory, they will be deleted from it.  If invoked with --after,
-    files are marked as removed, but not actually unlinked unless --force
-    is also given. Without exact file names, --after will only mark
-    files as removed if they are no longer in the working directory.
+    directory, they will be deleted from it unless invoked with --keep.
+    Modified files are marked as removed, but not actually unlinked unless
+    --force is also given. 
+    
+    Without exact file names, --after will only mark files as removed if they
+    are no longer in the working directory.
 
     This command schedules the files to be removed at the next commit.
     To undo a remove before that, see hg revert.
 
-    Modified files and added files are not removed by default.  To
-    remove them, use the -f/--force option.
+    Modified and added files are not removed by default.  To remove them, use
+    the -f/--force option (notethat keep as precedence over force).
     """
     if not opts['after'] and not pats:
         raise util.Abort(_('no files specified'))
@@ -2022,7 +2024,7 @@ def remove(ui, repo, *pats, **opts):
     remove, forget = [], []
     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
         reason = None
-        if abs in modified and not opts['force']:
+        if abs in modified and not opts['keep'] and not opts['force']:
             reason = _('is modified (use -f to force removal)')
         elif abs in added:
             if opts['force']:
@@ -2043,7 +2045,7 @@ def remove(ui, repo, *pats, **opts):
                 ui.status(_('removing %s\n') % rel)
             remove.append(abs)
     repo.forget(forget)
-    repo.remove(remove, unlink=opts['force'] or not opts['after'])
+    repo.remove(remove, unlink=not opts['keep'])
 
 def rename(ui, repo, *pats, **opts):
     """rename files; equivalent of copy + remove
@@ -2867,8 +2869,9 @@ table = {
     "recover": (recover, [], _('hg recover')),
     "^remove|rm":
         (remove,
-         [('A', 'after', None, _('record remove without deleting')),
-          ('f', 'force', None, _('remove file even if modified')),
+         [('A', 'after', None, _('record a remove that has already occurred')),
+          ('k', 'keep', None, _('record a remove without deleting')),
+          ('f', 'force', None, _('remove and delete file even if modified')),
          ] + walkopts,
          _('hg remove [OPTION]... FILE...')),
     "rename|mv":
diff --git a/tests/test-issue660 b/tests/test-issue660
--- a/tests/test-issue660
+++ b/tests/test-issue660
@@ -19,7 +19,7 @@ hg add a/a
 hg add a/a 
 
 echo % removing shadow
-hg rm --after a
+hg rm --keep a
 
 echo % should succeed - shadow removed
 hg add a/a
@@ -33,7 +33,7 @@ hg add b
 hg add b
 
 echo % removing shadow
-hg rm --after b/b
+hg rm --keep b/b
 
 echo % should succeed - shadow removed
 hg add b
@@ -76,7 +76,7 @@ hg add d
 hg add d
 
 echo % removing shadow
-hg rm --after d/d/d
+hg rm --keep d/d/d
 
 echo % should succeed - shadow removed
 hg add d
diff --git a/tests/test-remove b/tests/test-remove
--- a/tests/test-remove
+++ b/tests/test-remove
@@ -37,7 +37,7 @@ echo c >> b
 echo c >> b
 hg rm b
 hg rm -f b
-hg rm -A c/d
+hg rm -k c/d
 hg st
 cat c/d
 hg revert c
diff --git a/tests/test-remove-keep b/tests/test-remove-keep
new file mode 100755
--- /dev/null
+++ b/tests/test-remove-keep
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Test that a modified file is keeped  with -k option
+# (Before rev 1db1c7c1eb5e, hg rm -A -f of a modified file unlinked the file
+# and hg rm -A didn't remove the file)
+echo % init
+hg init
+
+echo % commit
+echo 'a' > a
+hg ci -A -m test -u nobody -d '1 0'
+
+echo % altering
+echo 'foo' >> a
+
+# -A has no effect on files still present
+echo % removing with -A
+hg rm -A a
+test -f a && echo OK a still exists || echo NOK a was removed
+
+# prevent file deletion
+echo % removing
+hg rm -k a
+test -f a && echo OK a still exists || echo NOK a was removed
+
+# -k has precedence over -f
+echo % removing with -f
+hg rm -k -f a
+test -f a && echo OK a still exists || echo NOK a was removed
diff --git a/tests/test-remove-keep.out b/tests/test-remove-keep.out
new file mode 100644
--- /dev/null
+++ b/tests/test-remove-keep.out
@@ -0,0 +1,11 @@
+% init
+% commit
+adding a
+% altering
+% removing with -A
+not removing a: file is modified (use -f to force removal)
+OK a still exists
+% removing
+OK a still exists
+% removing with -f
+OK a still exists


More information about the Mercurial-devel mailing list