Merge lp:~jelmer/bzr/rmbranch-active into lp:bzr

Proposed by Jelmer Vernooij
Status: Superseded
Proposed branch: lp:~jelmer/bzr/rmbranch-active
Merge into: lp:bzr
Prerequisite: lp:~jelmer/bzr/rmbranch-colo
Diff against target: 129 lines (+46/-10) (has conflicts)
3 files modified
bzrlib/builtins.py (+12/-2)
bzrlib/tests/blackbox/test_rmbranch.py (+31/-8)
doc/en/release-notes/bzr-2.5.txt (+3/-0)
Text conflict in doc/en/release-notes/bzr-2.5.txt
To merge this branch: bzr merge lp:~jelmer/bzr/rmbranch-active
Reviewer Review Type Date Requested Status
Martin Packman (community) Needs Information
Review via email: mp+94555@code.launchpad.net

This proposal supersedes a proposal from 2012-02-23.

This proposal has been superseded by a proposal from 2012-02-28.

Description of the change

Refuse removing active branches (branches associated with a working tree) in 'bzr rmbranch'.

Users can force the removal of such branches with the new --force argument to 'bzr rmbranch'.

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

As per the prerequisite, if this should now be landing on dev as the targeting suggests, the release notes need moving. However, this seems like a colo ui issue that would be nice to fix on the 2.5 branch.

+ gettext("Use --force to remove active branch."))

This should probably state what it has (not) done, rather than just how to do the foot shooting.

Perhaps "Keeping active branch, use --force to really remove it." or something.

Code and tests look fine.

review: Needs Information
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Error message updated and branch retargeted against bzr.dev.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py 2012-02-24 14:50:50 +0000
+++ bzrlib/builtins.py 2012-02-24 14:50:52 +0000
@@ -6477,12 +6477,22 @@
64776477
6478 takes_args = ["location?"]6478 takes_args = ["location?"]
64796479
6480 takes_options = ['directory']6480 takes_options = ['directory',
6481 Option('force', help='Remove branch even if it is the active branch.')]
64816482
6482 aliases = ["rmbranch"]6483 aliases = ["rmbranch"]
64836484
6484 def run(self, directory=None, location=None):6485 def run(self, directory=None, location=None, force=False):
6485 br = open_nearby_branch(near=directory, location=location)6486 br = open_nearby_branch(near=directory, location=location)
6487 if not force and br.bzrdir.has_workingtree():
6488 try:
6489 active_branch = br.bzrdir.open_branch(name="")
6490 except errors.NotBranchError:
6491 active_branch = None
6492 if (active_branch is not None and
6493 br.control_url == active_branch.control_url):
6494 raise errors.BzrCommandError(
6495 gettext("Use --force to remove active branch."))
6486 br.bzrdir.destroy_branch(br.name)6496 br.bzrdir.destroy_branch(br.name)
64876497
64886498
64896499
=== modified file 'bzrlib/tests/blackbox/test_rmbranch.py'
--- bzrlib/tests/blackbox/test_rmbranch.py 2012-02-24 14:50:50 +0000
+++ bzrlib/tests/blackbox/test_rmbranch.py 2012-02-24 14:50:52 +0000
@@ -28,7 +28,7 @@
2828
29class TestRemoveBranch(TestCaseWithTransport):29class TestRemoveBranch(TestCaseWithTransport):
3030
31 def example_branch(self, path='.', format=None):31 def example_tree(self, path='.', format=None):
32 tree = self.make_branch_and_tree(path, format=format)32 tree = self.make_branch_and_tree(path, format=format)
33 self.build_tree_contents([(path + '/hello', 'foo')])33 self.build_tree_contents([(path + '/hello', 'foo')])
34 tree.add('hello')34 tree.add('hello')
@@ -40,29 +40,41 @@
4040
41 def test_remove_local(self):41 def test_remove_local(self):
42 # Remove a local branch.42 # Remove a local branch.
43 self.example_branch('a')43 tree = self.example_tree('a')
44 self.run_bzr('rmbranch a')44 self.run_bzr_error(['Use --force to remove active branch.\n'],
45 'rmbranch a')
46 self.run_bzr('rmbranch --force a')
45 dir = bzrdir.BzrDir.open('a')47 dir = bzrdir.BzrDir.open('a')
46 self.assertFalse(dir.has_branch())48 self.assertFalse(dir.has_branch())
47 self.assertPathExists('a/hello')49 self.assertPathExists('a/hello')
48 self.assertPathExists('a/goodbye')50 self.assertPathExists('a/goodbye')
4951
50 def test_no_branch(self):52 def test_no_branch(self):
51 # No branch in the current directory. 53 # No branch in the current directory.
52 self.make_repository('a')54 self.make_repository('a')
53 self.run_bzr_error(['Not a branch'],55 self.run_bzr_error(['Not a branch'],
54 'rmbranch a')56 'rmbranch a')
5557
58 def test_no_tree(self):
59 # removing the active branch is possible if there is no tree
60 tree = self.example_tree('a')
61 tree.bzrdir.destroy_workingtree()
62 self.run_bzr('rmbranch', working_dir='a')
63 dir = bzrdir.BzrDir.open('a')
64 self.assertFalse(dir.has_branch())
65
56 def test_no_arg(self):66 def test_no_arg(self):
57 # location argument defaults to current directory67 # location argument defaults to current directory
58 self.example_branch('a')68 self.example_tree('a')
59 self.run_bzr('rmbranch', working_dir='a')69 self.run_bzr_error(['Use --force to remove active branch.\n'],
70 'rmbranch a')
71 self.run_bzr('rmbranch --force', working_dir='a')
60 dir = bzrdir.BzrDir.open('a')72 dir = bzrdir.BzrDir.open('a')
61 self.assertFalse(dir.has_branch())73 self.assertFalse(dir.has_branch())
6274
63 def test_remove_colo(self):75 def test_remove_colo(self):
64 # Remove a colocated branch.76 # Remove a colocated branch.
65 tree = self.example_branch('a')77 tree = self.example_tree('a')
66 tree.bzrdir.create_branch(name="otherbranch")78 tree.bzrdir.create_branch(name="otherbranch")
67 self.assertTrue(tree.bzrdir.has_branch('otherbranch'))79 self.assertTrue(tree.bzrdir.has_branch('otherbranch'))
68 self.run_bzr('rmbranch %s,branch=otherbranch' % tree.bzrdir.user_url)80 self.run_bzr('rmbranch %s,branch=otherbranch' % tree.bzrdir.user_url)
@@ -72,7 +84,7 @@
7284
73 def test_remove_colo_directory(self):85 def test_remove_colo_directory(self):
74 # Remove a colocated branch.86 # Remove a colocated branch.
75 tree = self.example_branch('a')87 tree = self.example_tree('a')
76 tree.bzrdir.create_branch(name="otherbranch")88 tree.bzrdir.create_branch(name="otherbranch")
77 self.assertTrue(tree.bzrdir.has_branch('otherbranch'))89 self.assertTrue(tree.bzrdir.has_branch('otherbranch'))
78 self.run_bzr('rmbranch otherbranch -d %s' % tree.bzrdir.user_url)90 self.run_bzr('rmbranch otherbranch -d %s' % tree.bzrdir.user_url)
@@ -80,6 +92,17 @@
80 self.assertFalse(dir.has_branch('otherbranch'))92 self.assertFalse(dir.has_branch('otherbranch'))
81 self.assertTrue(dir.has_branch())93 self.assertTrue(dir.has_branch())
8294
95 def test_remove_active_colo_branch(self):
96 # Remove a colocated branch.
97 dir = self.make_repository('a').bzrdir
98 branch = dir.create_branch('otherbranch')
99 branch.create_checkout('a')
100 self.run_bzr_error(['Use --force to remove active branch.\n'],
101 'rmbranch otherbranch -d %s' % branch.bzrdir.user_url)
102 self.assertTrue(dir.has_branch('otherbranch'))
103 self.run_bzr('rmbranch --force otherbranch -d %s' % branch.bzrdir.user_url)
104 self.assertFalse(dir.has_branch('otherbranch'))
105
83106
84class TestSmartServerRemoveBranch(TestCaseWithTransport):107class TestSmartServerRemoveBranch(TestCaseWithTransport):
85108
86109
=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- doc/en/release-notes/bzr-2.5.txt 2012-02-24 14:50:50 +0000
+++ doc/en/release-notes/bzr-2.5.txt 2012-02-24 14:50:52 +0000
@@ -37,6 +37,9 @@
37* ``bzr rmbranch`` now supports removing colocated branches.37* ``bzr rmbranch`` now supports removing colocated branches.
38 (Jelmer Vernooij, #920653)38 (Jelmer Vernooij, #920653)
3939
40* ``bzr rmbranch`` no longer removes active branches unless ``--force``
41 is specified. (Jelmer Vernooij, #922953)
42
40* Show locks in ``bzr info`` on control directories without a43* Show locks in ``bzr info`` on control directories without a
41 repository. (Jelmer Vernooij, #936767)44 repository. (Jelmer Vernooij, #936767)
4245