[PATCH] improved semantics for remove (issue438)
Dirkjan Ochtman
dirkjan at ochtman.nl
Fri Mar 21 09:21:09 CDT 2008
# HG changeset patch
# User Dirkjan Ochtman <dirkjan at ochtman.nl>
# Date 1206107862 -3600
# Node ID fadd63aa67b27c3a222ca73661c98a5cc64b1bdb
# Parent 0750f11152febd2ff4ca7439957b77111d99cc63
improved semantics for remove (issue438)
- Added files are never deleted (only removed with --force).
- Modified files can only be removed with --force.
- With --keep, removals never delete the file.
- With --after, only deleted files are removed.
diff -r 0750f11152fe -r fadd63aa67b2 mercurial/commands.py
--- a/mercurial/commands.py Fri Mar 21 14:52:24 2008 +0100
+++ b/mercurial/commands.py Fri Mar 21 14:57:42 2008 +0100
@@ -2129,49 +2129,61 @@
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.
+
+ --after can be used to remove files that have been deleted from disk.
+ --keep can be used to remove files from further revisions without deleting.
+
+ Added files can only be removed with the -f/--force option, and will never
+ be deleted. Modified files can only be removed with the -f/--force option.
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.
- """
- if not opts['after'] and not pats:
+ after, keep, force = opts.get('after'), opts.get('keep'), opts.get('force')
+ if not pats and not after:
raise util.Abort(_('no files specified'))
+
files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
- exact = dict.fromkeys(files)
mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
modified, added, removed, deleted, unknown = mardu
+
remove, forget = [], []
for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
+
reason = None
- if abs in modified and not opts['force']:
- reason = _('is modified (use -f to force removal)')
+ if abs in removed or abs in unknown:
+ continue
+
+ elif after and not keep and abs not in deleted:
+ reason = _('still exists (use without -A to remove)')
+
+ elif keep and not after and abs in deleted:
+ reason = _('already deleted (use without -k to remove)')
+
elif abs in added:
- if opts['force']:
+ if not force and not keep:
+ reason = _('has been marked for add (use -f to force removal)')
+ else:
forget.append(abs)
- continue
- reason = _('has been marked for add (use -f to force removal)')
- exact = 1 # force the message
- elif abs not in repo.dirstate:
- reason = _('is not managed')
- elif opts['after'] and not exact and abs not in deleted:
- continue
- elif abs in removed:
- continue
+
+ elif abs in modified:
+ if not force and not keep:
+ reason = _('is modified (use -f to force removal)')
+ else:
+ remove.append(abs)
+
+ elif not reason:
+ remove.append(abs)
+
if reason:
- if exact:
- ui.warn(_('not removing %s: file %s\n') % (rel, reason))
- else:
- if ui.verbose or not exact:
- ui.status(_('removing %s\n') % rel)
- remove.append(abs)
+ ui.warn(_('not removing %s: file %s\n') % (rel, reason))
+ elif ui.verbose or not exact:
+ ui.status(_('removing %s\n') % rel)
+
repo.forget(forget)
- repo.remove(remove, unlink=opts['force'] or not opts['after'])
+ repo.remove(remove, unlink=not keep and not after)
def rename(ui, repo, *pats, **opts):
"""rename files; equivalent of copy + remove
@@ -3125,8 +3137,10 @@
"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 delete for missing files')),
+ ('k', 'keep', None, _('record remove without deleting')),
+ ('f', 'force', None,
+ _('remove (and delete) file even if added or modified')),
] + walkopts,
_('hg remove [OPTION]... FILE...')),
"rename|mv":
diff -r 0750f11152fe -r fadd63aa67b2 tests/test-issue660
--- a/tests/test-issue660 Fri Mar 21 14:52:24 2008 +0100
+++ b/tests/test-issue660 Fri Mar 21 14:57:42 2008 +0100
@@ -19,7 +19,7 @@
hg add a/a
echo % removing shadow
-hg rm --after a
+hg rm -A a
echo % should succeed - shadow removed
hg add a/a
@@ -33,7 +33,7 @@
hg add b
echo % removing shadow
-hg rm --after b/b
+hg rm -A b/b
echo % should succeed - shadow removed
hg add b
@@ -76,7 +76,7 @@
hg add d
echo % removing shadow
-hg rm --after d/d/d
+hg rm -A d/d/d
echo % should succeed - shadow removed
hg add d
diff -r 0750f11152fe -r fadd63aa67b2 tests/test-remove
--- a/tests/test-remove Fri Mar 21 14:52:24 2008 +0100
+++ b/tests/test-remove Fri Mar 21 14:57:42 2008 +0100
@@ -3,16 +3,52 @@
hg init a
cd a
echo a > foo
+
+echo % file not managed
+hg rm foo
+
+hg add foo
+hg commit -m1
+
+echo % normal remove
hg rm foo
-hg add foo
-hg commit -m 1 -d "1000000 0"
+hg st
+test -f foo && echo NOK foo still exists || echo OK foo was removed
+
+hg up -C
+echo % normal remove with after
+hg rm -A foo
+hg st
+test -f foo && echo OK foo still exists || echo NOK foo was removed
+
+hg up -C
+echo % normal remove with after + missing
+rm foo
+hg rm -A foo
+hg st
+test -f foo && echo NOK foo still exists || echo OK foo was removed
+
+hg up -C
+echo % normal remove with keep
+hg rm -k foo
+hg st
+test -f foo && echo OK foo still exists || echo NOK foo was removed
+
+hg up -C
+echo % no file specified
hg remove
+
+echo % remove + revert
rm foo
hg remove foo
+hg st
hg revert --all
+test -f foo && echo OK foo still exists || echo NOK foo was removed
+
rm foo
-hg remove --after
-hg commit -m 2 -d "1000000 0"
+hg remove foo
+hg commit -m2
+
hg export --nodates 0
hg export --nodates 1
hg log -p -r 0
@@ -20,26 +56,99 @@
echo a > a
hg add a
+echo % added files are not removed
hg rm a
+test -f a && echo OK a still exists || echo NOK a was removed
+
+echo % no warning for added files if --keep
+hg rm -k a
+hg st
+
+echo % not even when --forced
hg rm -f a
+test -f a && echo OK a still exists || echo NOK a was removed
+hg st
+
echo b > b
mkdir c
echo d > c/d
-hg ci -A -m 3 -d "1000001 0"
-echo c >> b
-hg rm b
-hg rm -f b
-hg rm -A c/d
-hg st
-cat c/d
-hg revert c
-hg rm -A
-hg st
-hg rm -A c
-hg st
-rm c/d
+hg ci -Am3
+
+echo % rm -A without patterns
+rm b
hg rm -A
hg st
+hg up -C
+echo c >> b
+echo % modified files are not removed
+hg rm b
+test -f b && echo OK b still exists || echo NOK b was removed
+
+echo % no warning for modified files if --keep
+hg rm -k b
+hg st
+
+hg up -C
+echo c >> b
+echo % unless --forced
+hg rm -f b
+test -f b && echo NOK b still exists || echo OK b was removed
+
+echo % remove file without deleting it
+hg rm -k c/d
+test -f c/d && echo OK c/d still exists || echo NOK c/d was removed
+hg st
+cat c/d
+
+hg up -C
+echo % adding another file to dir
+echo e > c/e
+hg ci -Am4
+
+echo % rm on a dir
+hg rm c
+hg st
+
+hg up -C
+echo % rm -k on a dir
+hg rm -k c
+ls c
+hg st
+
+hg up -C
+echo % rm -A on a dir
+hg rm -A c
+ls c
+hg st
+
+hg up -C
+echo % rm -Ak on a dir
+hg rm -Ak c
+ls c
+hg st
+
+hg up -C
+echo % rm -A on a dir with missing
+rm c/e
+hg rm -A c
+ls c
+hg st
+
+hg up -C
+echo % rm -k on a dir with missing
+rm c/e
+hg rm -k c
+ls c
+hg st
+
+hg up -C
+echo % rm -Ak on a dir with missing
+rm c/e
+hg rm -Ak c
+ls c
+hg st
+
+echo % clone
cd ..
hg clone a b
diff -r 0750f11152fe -r fadd63aa67b2 tests/test-remove.out
--- a/tests/test-remove.out Fri Mar 21 14:52:24 2008 +0100
+++ b/tests/test-remove.out Fri Mar 21 14:57:42 2008 +0100
@@ -1,67 +1,153 @@
-not removing foo: file is not managed
+% file not managed
+% normal remove
+R foo
+OK foo was removed
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% normal remove with after
+not removing foo: file still exists (use without -A to remove)
+OK foo still exists
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% normal remove with after + missing
+R foo
+OK foo was removed
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% normal remove with keep
+R foo
+OK foo still exists
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% no file specified
abort: no files specified
+% remove + revert
+R foo
undeleting foo
-removing foo
+OK foo still exists
# HG changeset patch
# User test
-# Date 1000000 0
-# Node ID 8ba83d44753d6259db5ce6524974dd1174e90f47
+# Date 0 0
+# Node ID b51ca55c20354097ca299529d18b5cd356976ba2
# Parent 0000000000000000000000000000000000000000
1
-diff -r 000000000000 -r 8ba83d44753d foo
+diff -r 000000000000 -r b51ca55c2035 foo
--- /dev/null
+++ b/foo
@@ -0,0 +1,1 @@
+a
# HG changeset patch
# User test
-# Date 1000000 0
-# Node ID a1fce69c50d97881c5c014ab23f580f720c78678
-# Parent 8ba83d44753d6259db5ce6524974dd1174e90f47
+# Date 0 0
+# Node ID 451c12a24e5a7336921b8d93e280837d7c2b4fc1
+# Parent b51ca55c20354097ca299529d18b5cd356976ba2
2
-diff -r 8ba83d44753d -r a1fce69c50d9 foo
+diff -r b51ca55c2035 -r 451c12a24e5a foo
--- a/foo
+++ /dev/null
@@ -1,1 +0,0 @@
-a
-changeset: 0:8ba83d44753d
+changeset: 0:b51ca55c2035
user: test
-date: Mon Jan 12 13:46:40 1970 +0000
+date: Thu Jan 01 00:00:00 1970 +0000
summary: 1
-diff -r 000000000000 -r 8ba83d44753d foo
+diff -r 000000000000 -r b51ca55c2035 foo
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/foo Mon Jan 12 13:46:40 1970 +0000
++++ b/foo Thu Jan 01 00:00:00 1970 +0000
@@ -0,0 +1,1 @@
+a
-changeset: 1:a1fce69c50d9
+changeset: 1:451c12a24e5a
tag: tip
user: test
-date: Mon Jan 12 13:46:40 1970 +0000
+date: Thu Jan 01 00:00:00 1970 +0000
summary: 2
-diff -r 8ba83d44753d -r a1fce69c50d9 foo
---- a/foo Mon Jan 12 13:46:40 1970 +0000
+diff -r b51ca55c2035 -r 451c12a24e5a foo
+--- a/foo Thu Jan 01 00:00:00 1970 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-a
+% added files are not removed
not removing a: file has been marked for add (use -f to force removal)
+OK a still exists
+% no warning for added files if --keep
+? a
+% not even when --forced
+OK a still exists
+? a
adding a
adding b
adding c/d
+% rm -A without patterns
+not removing a: file still exists (use without -A to remove)
+not removing c/d: file still exists (use without -A to remove)
+removing b
+R b
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% modified files are not removed
not removing b: file is modified (use -f to force removal)
+OK b still exists
+% no warning for modified files if --keep
+R b
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% unless --forced
+OK b was removed
+% remove file without deleting it
+OK c/d still exists
R b
R c/d
d
-undeleting c/d
-R b
-R b
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% adding another file to dir
+adding c/e
+% rm on a dir
removing c/d
-R b
+removing c/e
R c/d
+R c/e
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -k on a dir
+removing c/d
+removing c/e
+d
+e
+R c/d
+R c/e
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -A on a dir
+not removing c/d: file still exists (use without -A to remove)
+not removing c/e: file still exists (use without -A to remove)
+d
+e
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -Ak on a dir
+removing c/d
+removing c/e
+d
+e
+R c/d
+R c/e
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -A on a dir with missing
+not removing c/d: file still exists (use without -A to remove)
+removing c/e
+d
+R c/e
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -k on a dir with missing
+removing c/d
+not removing c/e: file already deleted (use without -k to remove)
+d
+R c/d
+! c/e
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% rm -Ak on a dir with missing
+removing c/d
+removing c/e
+d
+R c/d
+R c/e
+% clone
updating working directory
-3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+4 files updated, 0 files merged, 0 files removed, 0 files unresolved
More information about the Mercurial-devel
mailing list