Rev 3621: * ``bzr rm`` will now scan for files that are missing and remove just in http://people.ubuntu.com/~robertc/baz2.0/rm
Robert Collins
robertc at robertcollins.net
Wed Aug 13 05:01:51 BST 2008
At http://people.ubuntu.com/~robertc/baz2.0/rm
------------------------------------------------------------
revno: 3621
revision-id: robertc at robertcollins.net-20080813035223-i9sxgq2rp5477oc5
parent: robertc at robertcollins.net-20080813032119-09pl9q0t9gxng5t6
committer: Robert Collins <robertc at robertcollins.net>
branch nick: rm
timestamp: Wed 2008-08-13 13:52:23 +1000
message:
* ``bzr rm`` will now scan for files that are missing and remove just
them automatically, much as ``bzr add`` scans for new files that
are not ignored and adds them automatically. (Robert Collins)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/tests/blackbox/test_remove.py test_remove.py-20060530011439-fika5rm84lon0goe-1
=== modified file 'NEWS'
--- a/NEWS 2008-08-13 03:21:19 +0000
+++ b/NEWS 2008-08-13 03:52:23 +0000
@@ -14,6 +14,10 @@
* ``bzr export`` can now export a subdirectory of a project.
(Robert Collins)
+ * ``bzr rm`` will now scan for files that are missing and remove just
+ them automatically, much as ``bzr add`` scans for new files that
+ are not ignored and adds them automatically. (Robert Collins)
+
BUG FIXES:
* ``bzr upgrade`` on remote branches accessed via bzr:// and
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2008-08-11 03:39:25 +0000
+++ b/bzrlib/builtins.py 2008-08-13 03:52:23 +0000
@@ -1066,17 +1066,14 @@
class cmd_remove(Command):
"""Remove files or directories.
- This makes bzr stop tracking changes to the specified files and
- delete them if they can easily be recovered using revert.
-
- You can specify one or more files, and/or --new. If you specify --new,
- only 'added' files will be removed. If you specify both, then new files
- in the specified directories will be removed. If the directories are
- also new, they will also be removed.
+ This makes bzr stop tracking changes to the specified files and delete them
+ if they can easily be recovered using revert. If no options or parameters
+ are given bzr will scan for files that are versioned by bzr but missing in
+ your tree and unversion them for you.
"""
takes_args = ['file*']
takes_options = ['verbose',
- Option('new', help='Remove newly-added files.'),
+ Option('new', help='Only remove files that have never been committed.'),
RegistryOption.from_kwargs('file-deletion-strategy',
'The file deletion mode to be used.',
title='Deletion Strategy', value_switches=True, enum_switch=False,
@@ -1094,19 +1091,31 @@
if file_list is not None:
file_list = [f for f in file_list]
- elif not new:
- raise errors.BzrCommandError('Specify one or more files to'
- ' remove, or use --new.')
- if new:
- added = tree.changes_from(tree.basis_tree(),
- specific_files=file_list).added
- file_list = sorted([f[0] for f in added], reverse=True)
- if len(file_list) == 0:
- raise errors.BzrCommandError('No matching files.')
- tree.remove(file_list, verbose=verbose, to_file=self.outf,
- keep_files=file_deletion_strategy=='keep',
- force=file_deletion_strategy=='force')
+ tree.lock_write()
+ try:
+ # Heuristics should probably all move into tree.remove_smart or
+ # some such?
+ if new:
+ added = tree.changes_from(tree.basis_tree(),
+ specific_files=file_list).added
+ file_list = sorted([f[0] for f in added], reverse=True)
+ if len(file_list) == 0:
+ raise errors.BzrCommandError('No matching files.')
+ elif file_list is None:
+ # missing files show up in iter_changes(basis) as
+ # versioned-with-no-kind.
+ missing = []
+ for change in tree.iter_changes(tree.basis_tree()):
+ if change[6][1] is None:
+ missing.append(change[1][1])
+ file_list = sorted(missing, reverse=True)
+ file_deletion_strategy = 'keep'
+ tree.remove(file_list, verbose=verbose, to_file=self.outf,
+ keep_files=file_deletion_strategy=='keep',
+ force=file_deletion_strategy=='force')
+ finally:
+ tree.unlock()
class cmd_file_id(Command):
=== modified file 'bzrlib/tests/blackbox/test_remove.py'
--- a/bzrlib/tests/blackbox/test_remove.py 2007-11-28 17:02:05 +0000
+++ b/bzrlib/tests/blackbox/test_remove.py 2008-08-13 03:52:23 +0000
@@ -18,7 +18,7 @@
import os
import sys
-from bzrlib.tests import TestSkipped
+from bzrlib.tests import SymlinkFeature, TestSkipped
from bzrlib.tests.blackbox import ExternalBase
from bzrlib.workingtree import WorkingTree
from bzrlib import osutils
@@ -33,15 +33,16 @@
class TestRemove(ExternalBase):
- def _make_add_and_assert_tree(self, files):
+ def _make_add_and_assert_tree(self, paths):
tree = self.make_branch_and_tree('.')
- self.build_tree(files)
- for f in files:
- id=str(f).replace('/', '_') + _id
- tree.add(f, id)
- self.assertEqual(tree.path2id(f), id)
- self.failUnlessExists(f)
- self.assertInWorkingTree(f)
+ tree.lock_write()
+ try:
+ self.build_tree(paths)
+ for path in paths:
+ file_id=str(path).replace('/', '_') + _id
+ tree.add(path, file_id)
+ finally:
+ tree.unlock()
return tree
def assertFilesDeleted(self, files):
@@ -71,14 +72,58 @@
self.run_bzr(['remove', '--force'] + list(files_to_remove))
def test_remove_no_files_specified(self):
- tree = self._make_add_and_assert_tree([])
- self.run_bzr_error(["bzr: ERROR: Specify one or more files to remove, "
- "or use --new."], 'remove')
-
- self.run_bzr_error(["bzr: ERROR: No matching files."], 'remove --new')
-
- self.run_bzr_error(["bzr: ERROR: No matching files."],
- 'remove --new .')
+ tree = self._make_add_and_assert_tree(['foo'])
+ out, err = self.run_bzr(['rm'])
+ self.assertEqual('', err)
+ self.assertEqual('', out)
+ self.assertInWorkingTree('foo', tree=tree)
+ self.failUnlessExists('foo')
+
+ def test_remove_no_files_specified_missing_dir_and_contents(self):
+ tree = self._make_add_and_assert_tree(
+ ['foo', 'dir/', 'dir/missing/', 'dir/missing/child'])
+ self.get_transport('.').delete_tree('dir/missing')
+ out, err = self.run_bzr(['rm'])
+ self.assertEqual('', out)
+ self.assertEqual(
+ 'removed dir/missing/child\n'
+ 'removed dir/missing\n',
+ err)
+ # non-missing paths not touched:
+ self.assertInWorkingTree('foo', tree=tree)
+ self.failUnlessExists('foo')
+ self.assertInWorkingTree('dir', tree=tree)
+ self.failUnlessExists('dir')
+ # missing files unversioned
+ self.assertNotInWorkingTree('dir/missing', tree=tree)
+ self.assertNotInWorkingTree('dir/missing/child', tree=tree)
+
+ def test_remove_no_files_specified_missing_file(self):
+ tree = self._make_add_and_assert_tree(['foo', 'bar'])
+ os.unlink('bar')
+ out, err = self.run_bzr(['rm'])
+ self.assertEqual('', out)
+ self.assertEqual('removed bar\n', err)
+ # non-missing files not touched:
+ self.assertInWorkingTree('foo', tree=tree)
+ self.failUnlessExists('foo')
+ # missing files unversioned
+ self.assertNotInWorkingTree('bar', tree=tree)
+
+ def test_remove_no_files_specified_missing_link(self):
+ self.requireFeature(SymlinkFeature)
+ tree = self._make_add_and_assert_tree(['foo'])
+ os.symlink('foo', 'linkname')
+ tree.add(['linkname'])
+ os.unlink('linkname')
+ out, err = self.run_bzr(['rm'])
+ self.assertEqual('', out)
+ self.assertEqual('removed linkname\n', err)
+ # non-missing files not touched:
+ self.assertInWorkingTree('foo', tree=tree)
+ self.failUnlessExists('foo')
+ # missing files unversioned
+ self.assertNotInWorkingTree('linkname', tree=tree)
def test_rm_one_file(self):
tree = self._make_add_and_assert_tree([a])
More information about the bazaar-commits
mailing list