Merge lp:~zyga/tarmac/git-support into lp:tarmac
- git-support
- Merge into main
Status: | Needs review |
---|---|
Proposed branch: | lp:~zyga/tarmac/git-support |
Merge into: | lp:tarmac |
Diff against target: |
235 lines (+31/-30) 6 files modified
.bzrignore (+1/-0) tarmac/bin/commands.py (+5/-5) tarmac/branch.py (+2/-2) tarmac/tests/__init__.py (+3/-3) tarmac/tests/test_branch.py (+11/-11) tarmac/tests/test_commands.py (+9/-9) |
To merge this branch: | bzr merge lp:~zyga/tarmac/git-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
dobey | Needs Information | ||
Review via email: mp+261528@code.launchpad.net |
Commit message
Description of the change
aa97679 Rename Branch to BzrBranch
fb93a53 Ignore .pyc files
This branch is meant to get started with adding git support to tarmac. I'd like to see how conductive upstream is with this move and start making the necessary changes.
Zygmunt Krynicki (zyga) wrote : | # |
Thanks for the feedback!
I'll continue working on this and I'll be pushing more branches as I
make progress. I'll focus on separating the bzr bits so that git can
co-exist. As for testing, do you intend to have a single set of tests
that work for git and bzr together?
Thanks
ZK
On Tue, Jul 7, 2015 at 7:14 PM, Rodney Dawes <email address hidden> wrote:
> Review: Needs Information
>
> This specific change looks OK to me, but it implies there is an idea about how to get to the end goal. I'd like to know what the ideas of how to get to the end goal of this are, before landing this change, though.
>
> There's a lot of ugliness in the current tests that I think could/should be cleaned up first, for example. Abstracting the bzr integration away and switching to use mocking in the tests, instead of creating actual branches and performing actions in them, will make things more reliable, and easy to repeat across VCS implementations.
> --
> https:/
> You are the owner of lp:~zyga/tarmac/git-support.
dobey (dobey) wrote : | # |
I think for the tests, each layer will need to be tested separately. The
abstraction would have tests, the underlying bzrlib back-end with its
own tests, and the git back-end with its tests.
On Tue, 2015-07-07 at 17:27 +0000, Zygmunt Krynicki wrote:
> Thanks for the feedback!
>
> I'll continue working on this and I'll be pushing more branches as I
> make progress. I'll focus on separating the bzr bits so that git can
> co-exist. As for testing, do you intend to have a single set of tests
> that work for git and bzr together?
>
> Thanks
> ZK
>
> On Tue, Jul 7, 2015 at 7:14 PM, Rodney Dawes <email address hidden> wrote:
> > Review: Needs Information
> >
> > This specific change looks OK to me, but it implies there is an idea about how to get to the end goal. I'd like to know what the ideas of how to get to the end goal of this are, before landing this change, though.
> >
> > There's a lot of ugliness in the current tests that I think could/should be cleaned up first, for example. Abstracting the bzr integration away and switching to use mocking in the tests, instead of creating actual branches and performing actions in them, will make things more reliable, and easy to repeat across VCS implementations.
> > --
> > https:/
> > You are the owner of lp:~zyga/tarmac/git-support.
>
Unmerged revisions
- 434. By Zygmunt Krynicki
-
Ignore .pyc files
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 433. By Zygmunt Krynicki
-
Rename Branch to BzrBranch
This patch is meant to test the waters. My goal is to add git support to
tarmac. This change is a harmless change of tarmac.branch. Branch to
tarmac.branch. BzrBranch, this is in anticipation of subsequent add to
GitBranch and subsequent changes as they show up.Signed-off-by: Zygmunt Krynicki <email address hidden>
Preview Diff
1 | === modified file '.bzrignore' | |||
2 | --- .bzrignore 2013-12-05 22:28:15 +0000 | |||
3 | +++ .bzrignore 2015-06-09 15:08:40 +0000 | |||
4 | @@ -5,3 +5,4 @@ | |||
5 | 5 | TODO | 5 | TODO |
6 | 6 | debug* | 6 | debug* |
7 | 7 | tarmac.egg-info | 7 | tarmac.egg-info |
8 | 8 | *.pyc | ||
9 | 8 | 9 | ||
10 | === modified file 'tarmac/bin/commands.py' | |||
11 | --- tarmac/bin/commands.py 2014-02-24 23:38:37 +0000 | |||
12 | +++ tarmac/bin/commands.py 2015-06-09 15:08:40 +0000 | |||
13 | @@ -27,7 +27,7 @@ | |||
14 | 27 | STAGING_SERVICE_ROOT) | 27 | STAGING_SERVICE_ROOT) |
15 | 28 | 28 | ||
16 | 29 | from tarmac.bin import options | 29 | from tarmac.bin import options |
18 | 30 | from tarmac.branch import Branch | 30 | from tarmac.branch import BzrBranch |
19 | 31 | from tarmac.hooks import tarmac_hooks | 31 | from tarmac.hooks import tarmac_hooks |
20 | 32 | from tarmac.log import set_up_debug_logging, set_up_logging | 32 | from tarmac.log import set_up_debug_logging, set_up_logging |
21 | 33 | from tarmac.exceptions import ( | 33 | from tarmac.exceptions import ( |
22 | @@ -226,8 +226,8 @@ | |||
23 | 226 | return | 226 | return |
24 | 227 | 227 | ||
25 | 228 | try: | 228 | try: |
28 | 229 | target = Branch.create(lp_branch, self.config, create_tree=True, | 229 | target = BzrBranch.create(lp_branch, self.config, create_tree=True, |
29 | 230 | launchpad=self.launchpad) | 230 | launchpad=self.launchpad) |
30 | 231 | except TarmacMergeError as failure: | 231 | except TarmacMergeError as failure: |
31 | 232 | self._handle_merge_error(proposals[0], failure) | 232 | self._handle_merge_error(proposals[0], failure) |
32 | 233 | return | 233 | return |
33 | @@ -267,7 +267,7 @@ | |||
34 | 267 | u'No approved revision specified.') | 267 | u'No approved revision specified.') |
35 | 268 | 268 | ||
36 | 269 | 269 | ||
38 | 270 | source = Branch.create( | 270 | source = BzrBranch.create( |
39 | 271 | proposal.source_branch, self.config, target=target) | 271 | proposal.source_branch, self.config, target=target) |
40 | 272 | 272 | ||
41 | 273 | approved = source.bzr_branch.revision_id_to_revno( | 273 | approved = source.bzr_branch.revision_id_to_revno( |
42 | @@ -449,7 +449,7 @@ | |||
43 | 449 | self.logger.debug('%(branch_url)s specified as branch_url' % { | 449 | self.logger.debug('%(branch_url)s specified as branch_url' % { |
44 | 450 | 'branch_url': branch_url}) | 450 | 'branch_url': branch_url}) |
45 | 451 | if not branch_url.startswith('lp:'): | 451 | if not branch_url.startswith('lp:'): |
47 | 452 | raise TarmacCommandError('Branch urls must start with lp:') | 452 | raise TarmacCommandError('Bzr branch urls must start with lp:') |
48 | 453 | self._do_merges(branch_url, source_mp=proposal) | 453 | self._do_merges(branch_url, source_mp=proposal) |
49 | 454 | 454 | ||
50 | 455 | else: | 455 | else: |
51 | 456 | 456 | ||
52 | === modified file 'tarmac/branch.py' | |||
53 | --- tarmac/branch.py 2013-11-07 17:28:53 +0000 | |||
54 | +++ tarmac/branch.py 2015-06-09 15:08:40 +0000 | |||
55 | @@ -32,7 +32,7 @@ | |||
56 | 32 | ) | 32 | ) |
57 | 33 | 33 | ||
58 | 34 | 34 | ||
60 | 35 | class Branch(object): | 35 | class BzrBranch(object): |
61 | 36 | 36 | ||
62 | 37 | def __init__(self, lp_branch, config=False, target=None, launchpad=None): | 37 | def __init__(self, lp_branch, config=False, target=None, launchpad=None): |
63 | 38 | self.lp_branch = lp_branch | 38 | self.lp_branch = lp_branch |
64 | @@ -112,7 +112,7 @@ | |||
65 | 112 | self.tree.update() | 112 | self.tree.update() |
66 | 113 | 113 | ||
67 | 114 | def merge(self, branch, revid=None): | 114 | def merge(self, branch, revid=None): |
69 | 115 | '''Merge from another tarmac.branch.Branch instance.''' | 115 | '''Merge from another tarmac.branch.BzrBranch instance.''' |
70 | 116 | assert self.tree | 116 | assert self.tree |
71 | 117 | conflict_list = self.tree.merge_from_branch( | 117 | conflict_list = self.tree.merge_from_branch( |
72 | 118 | branch.bzr_branch, to_revision=revid) | 118 | branch.bzr_branch, to_revision=revid) |
73 | 119 | 119 | ||
74 | === modified file 'tarmac/tests/__init__.py' | |||
75 | --- tarmac/tests/__init__.py 2013-12-05 22:28:15 +0000 | |||
76 | +++ tarmac/tests/__init__.py 2015-06-09 15:08:40 +0000 | |||
77 | @@ -203,13 +203,13 @@ | |||
78 | 203 | self.add_branch_config(branch2_dir) | 203 | self.add_branch_config(branch2_dir) |
79 | 204 | 204 | ||
80 | 205 | mock1 = MockLPBranch(branch1_dir) | 205 | mock1 = MockLPBranch(branch1_dir) |
82 | 206 | branch1 = branch.Branch.create(mock1, self.config, create_tree=True) | 206 | branch1 = branch.BzrBranch.create(mock1, self.config, create_tree=True) |
83 | 207 | branch1.commit("Reading, 'riting, 'rithmetic") | 207 | branch1.commit("Reading, 'riting, 'rithmetic") |
84 | 208 | branch1.lp_branch.revision_count += 1 | 208 | branch1.lp_branch.revision_count += 1 |
85 | 209 | 209 | ||
86 | 210 | mock2 = MockLPBranch(branch2_dir, source_branch=branch1.lp_branch) | 210 | mock2 = MockLPBranch(branch2_dir, source_branch=branch1.lp_branch) |
89 | 211 | branch2 = branch.Branch.create(mock2, self.config, create_tree=True, | 211 | branch2 = branch.BzrBranch.create(mock2, self.config, create_tree=True, |
90 | 212 | target=branch1) | 212 | target=branch1) |
91 | 213 | branch2.commit('ABC...') | 213 | branch2.commit('ABC...') |
92 | 214 | 214 | ||
93 | 215 | added_file = os.path.join(branch2.lp_branch.tree_dir, 'README') | 215 | added_file = os.path.join(branch2.lp_branch.tree_dir, 'README') |
94 | 216 | 216 | ||
95 | === modified file 'tarmac/tests/test_branch.py' | |||
96 | --- tarmac/tests/test_branch.py 2013-11-07 17:28:53 +0000 | |||
97 | +++ tarmac/tests/test_branch.py 2015-06-09 15:08:40 +0000 | |||
98 | @@ -33,15 +33,15 @@ | |||
99 | 33 | 33 | ||
100 | 34 | 34 | ||
101 | 35 | class TestBranch(BranchTestCase): | 35 | class TestBranch(BranchTestCase): |
103 | 36 | '''Test for Tarmac.branch.Branch.''' | 36 | '''Test for Tarmac.branch.BzrBranch.''' |
104 | 37 | 37 | ||
105 | 38 | def test_create(self): | 38 | def test_create(self): |
106 | 39 | '''Test the creation of a TarmacBranch instance.''' | 39 | '''Test the creation of a TarmacBranch instance.''' |
107 | 40 | tree_dir = os.path.join(self.TEST_ROOT, 'test_create') | 40 | tree_dir = os.path.join(self.TEST_ROOT, 'test_create') |
108 | 41 | self.add_branch_config(tree_dir) | 41 | self.add_branch_config(tree_dir) |
109 | 42 | 42 | ||
112 | 43 | a_branch = branch.Branch.create(MockLPBranch(tree_dir), self.config) | 43 | a_branch = branch.BzrBranch.create(MockLPBranch(tree_dir), self.config) |
113 | 44 | self.assertTrue(isinstance(a_branch, branch.Branch)) | 44 | self.assertTrue(isinstance(a_branch, branch.BzrBranch)) |
114 | 45 | self.assertTrue(a_branch.lp_branch.bzr_identity is not None) | 45 | self.assertTrue(a_branch.lp_branch.bzr_identity is not None) |
115 | 46 | self.assertFalse(hasattr(a_branch, 'tree')) | 46 | self.assertFalse(hasattr(a_branch, 'tree')) |
116 | 47 | self.remove_branch_config(tree_dir) | 47 | self.remove_branch_config(tree_dir) |
117 | @@ -58,16 +58,16 @@ | |||
118 | 58 | # TarmacDirectoryFactory mocking will work. | 58 | # TarmacDirectoryFactory mocking will work. |
119 | 59 | mock = MockLPBranch(os.path.join(self.TEST_ROOT, branch_name)) | 59 | mock = MockLPBranch(os.path.join(self.TEST_ROOT, branch_name)) |
120 | 60 | self.assertFalse(os.path.exists(parent_dir)) | 60 | self.assertFalse(os.path.exists(parent_dir)) |
122 | 61 | a_branch = branch.Branch.create(mock, self.config, create_tree=True) | 61 | a_branch = branch.BzrBranch.create(mock, self.config, create_tree=True) |
123 | 62 | self.assertTrue(os.path.exists(parent_dir)) | 62 | self.assertTrue(os.path.exists(parent_dir)) |
125 | 63 | self.assertTrue(isinstance(a_branch, branch.Branch)) | 63 | self.assertTrue(isinstance(a_branch, branch.BzrBranch)) |
126 | 64 | self.assertTrue(a_branch.lp_branch.bzr_identity is not None) | 64 | self.assertTrue(a_branch.lp_branch.bzr_identity is not None) |
127 | 65 | self.assertTrue(hasattr(a_branch, 'tree')) | 65 | self.assertTrue(hasattr(a_branch, 'tree')) |
128 | 66 | self.remove_branch_config(tree_dir) | 66 | self.remove_branch_config(tree_dir) |
129 | 67 | 67 | ||
130 | 68 | def test_create_with_tree(self): | 68 | def test_create_with_tree(self): |
131 | 69 | '''Test the creation of a TarmacBranch with a created tree.''' | 69 | '''Test the creation of a TarmacBranch with a created tree.''' |
133 | 70 | self.assertTrue(isinstance(self.branch1, branch.Branch)) | 70 | self.assertTrue(isinstance(self.branch1, branch.BzrBranch)) |
134 | 71 | self.assertTrue(self.branch1.lp_branch.bzr_identity is not None) | 71 | self.assertTrue(self.branch1.lp_branch.bzr_identity is not None) |
135 | 72 | self.assertTrue(hasattr(self.branch1, 'tree')) | 72 | self.assertTrue(hasattr(self.branch1, 'tree')) |
136 | 73 | 73 | ||
137 | @@ -75,7 +75,7 @@ | |||
138 | 75 | '''A merge on a branch with no tree will raise an exception.''' | 75 | '''A merge on a branch with no tree will raise an exception.''' |
139 | 76 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') | 76 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') |
140 | 77 | self.add_branch_config(branch3_dir) | 77 | self.add_branch_config(branch3_dir) |
142 | 78 | branch3 = branch.Branch.create(MockLPBranch( | 78 | branch3 = branch.BzrBranch.create(MockLPBranch( |
143 | 79 | branch3_dir, source_branch=self.branch1.lp_branch), | 79 | branch3_dir, source_branch=self.branch1.lp_branch), |
144 | 80 | self.config) | 80 | self.config) |
145 | 81 | 81 | ||
146 | @@ -89,7 +89,7 @@ | |||
147 | 89 | changes are present.''' | 89 | changes are present.''' |
148 | 90 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') | 90 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') |
149 | 91 | self.add_branch_config(branch3_dir) | 91 | self.add_branch_config(branch3_dir) |
151 | 92 | branch3 = branch.Branch.create(MockLPBranch( | 92 | branch3 = branch.BzrBranch.create(MockLPBranch( |
152 | 93 | branch3_dir, source_branch=self.branch1.lp_branch), | 93 | branch3_dir, source_branch=self.branch1.lp_branch), |
153 | 94 | self.config) | 94 | self.config) |
154 | 95 | 95 | ||
155 | @@ -214,13 +214,13 @@ | |||
156 | 214 | self.branch2.commit, | 214 | self.branch2.commit, |
157 | 215 | 'Authors Merge test', authors=['\n'.join(authors)]) | 215 | 'Authors Merge test', authors=['\n'.join(authors)]) |
158 | 216 | 216 | ||
160 | 217 | @patch('tarmac.branch.bzr_branch.Branch.user_url') | 217 | @patch('tarmac.branch.bzr_branch.BzrBranch.user_url') |
161 | 218 | def test_create_tree_invalid_workingtree(self, mocked): | 218 | def test_create_tree_invalid_workingtree(self, mocked): |
162 | 219 | """Test that InvalidWorkingTree is raised when it should be.""" | 219 | """Test that InvalidWorkingTree is raised when it should be.""" |
163 | 220 | tree_dir = os.path.join(self.TEST_ROOT, 'test_invalid_workingtree') | 220 | tree_dir = os.path.join(self.TEST_ROOT, 'test_invalid_workingtree') |
164 | 221 | self.add_branch_config(tree_dir) | 221 | self.add_branch_config(tree_dir) |
165 | 222 | self.addCleanup(self.remove_branch_config, tree_dir) | 222 | self.addCleanup(self.remove_branch_config, tree_dir) |
167 | 223 | a_branch = branch.Branch(MockLPBranch(tree_dir), self.config) | 223 | a_branch = branch.BzrBranch(MockLPBranch(tree_dir), self.config) |
168 | 224 | a_branch.bzr_branch.user_url = 'lp:invalid' | 224 | a_branch.bzr_branch.user_url = 'lp:invalid' |
169 | 225 | self.assertRaises(InvalidWorkingTree, | 225 | self.assertRaises(InvalidWorkingTree, |
170 | 226 | a_branch.create_tree) | 226 | a_branch.create_tree) |
171 | @@ -233,7 +233,7 @@ | |||
172 | 233 | self.addCleanup(shutil.rmtree, tree_dir) | 233 | self.addCleanup(shutil.rmtree, tree_dir) |
173 | 234 | 234 | ||
174 | 235 | committer = 'LP User' | 235 | committer = 'LP User' |
176 | 236 | a_branch = branch.Branch.create(MockLPBranch(tree_dir), self.config, | 236 | a_branch = branch.BzrBranch.create(MockLPBranch(tree_dir), self.config, |
177 | 237 | create_tree=True, launchpad=Thing( | 237 | create_tree=True, launchpad=Thing( |
178 | 238 | me=Thing(display_name=committer))) | 238 | me=Thing(display_name=committer))) |
179 | 239 | a_branch.commit('Test LP User.') | 239 | a_branch.commit('Test LP User.') |
180 | 240 | 240 | ||
181 | === modified file 'tarmac/tests/test_commands.py' | |||
182 | --- tarmac/tests/test_commands.py 2014-02-24 23:41:32 +0000 | |||
183 | +++ tarmac/tests/test_commands.py 2015-06-09 15:08:40 +0000 | |||
184 | @@ -22,7 +22,7 @@ | |||
185 | 22 | from mock import patch, MagicMock | 22 | from mock import patch, MagicMock |
186 | 23 | from tarmac.bin import commands | 23 | from tarmac.bin import commands |
187 | 24 | from tarmac.bin.registry import CommandRegistry | 24 | from tarmac.bin.registry import CommandRegistry |
189 | 25 | from tarmac.branch import Branch | 25 | from tarmac.branch import BzrBranch |
190 | 26 | from tarmac.config import TarmacConfig | 26 | from tarmac.config import TarmacConfig |
191 | 27 | from tarmac.exceptions import ( | 27 | from tarmac.exceptions import ( |
192 | 28 | InvalidWorkingTree, | 28 | InvalidWorkingTree, |
193 | @@ -190,8 +190,8 @@ | |||
194 | 190 | # Create a 3rd branch we'll use to test with | 190 | # Create a 3rd branch we'll use to test with |
195 | 191 | branch3_dir = os.path.join(self.TEST_ROOT, name) | 191 | branch3_dir = os.path.join(self.TEST_ROOT, name) |
196 | 192 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) | 192 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) |
199 | 193 | branch3 = Branch.create(mock3, self.config, create_tree=True, | 193 | branch3 = BzrBranch.create(mock3, self.config, create_tree=True, |
200 | 194 | target=self.branch1) | 194 | target=self.branch1) |
201 | 195 | branch3.commit('Prerequisite commit.') | 195 | branch3.commit('Prerequisite commit.') |
202 | 196 | branch3.lp_branch.revision_count += 1 | 196 | branch3.lp_branch.revision_count += 1 |
203 | 197 | 197 | ||
204 | @@ -270,8 +270,8 @@ | |||
205 | 270 | # Create a 3rd prerequisite branch we'll use to test with | 270 | # Create a 3rd prerequisite branch we'll use to test with |
206 | 271 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') | 271 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') |
207 | 272 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) | 272 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) |
210 | 273 | branch3 = Branch.create(mock3, self.config, create_tree=True, | 273 | branch3 = BzrBranch.create(mock3, self.config, create_tree=True, |
211 | 274 | target=self.branch1) | 274 | target=self.branch1) |
212 | 275 | branch3.commit('Prerequisite commit.') | 275 | branch3.commit('Prerequisite commit.') |
213 | 276 | branch3.lp_branch.revision_count += 1 | 276 | branch3.lp_branch.revision_count += 1 |
214 | 277 | 277 | ||
215 | @@ -316,8 +316,8 @@ | |||
216 | 316 | # Create a 3rd prerequisite branch we'll use to test with | 316 | # Create a 3rd prerequisite branch we'll use to test with |
217 | 317 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') | 317 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') |
218 | 318 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) | 318 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) |
221 | 319 | branch3 = Branch.create(mock3, self.config, create_tree=True, | 319 | branch3 = BzrBranch.create(mock3, self.config, create_tree=True, |
222 | 320 | target=self.branch1) | 320 | target=self.branch1) |
223 | 321 | branch3.commit('Prerequisite commit.') | 321 | branch3.commit('Prerequisite commit.') |
224 | 322 | branch3.lp_branch.revision_count += 1 | 322 | branch3.lp_branch.revision_count += 1 |
225 | 323 | 323 | ||
226 | @@ -365,8 +365,8 @@ | |||
227 | 365 | # Create a 3rd prerequisite branch we'll use to test with | 365 | # Create a 3rd prerequisite branch we'll use to test with |
228 | 366 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') | 366 | branch3_dir = os.path.join(self.TEST_ROOT, 'branch3') |
229 | 367 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) | 367 | mock3 = MockLPBranch(branch3_dir, source_branch=self.branch1.lp_branch) |
232 | 368 | branch3 = Branch.create(mock3, self.config, create_tree=True, | 368 | branch3 = BzrBranch.create(mock3, self.config, create_tree=True, |
233 | 369 | target=self.branch1) | 369 | target=self.branch1) |
234 | 370 | branch3.commit('Prerequisite commit.') | 370 | branch3.commit('Prerequisite commit.') |
235 | 371 | branch3.lp_branch.revision_count += 1 | 371 | branch3.lp_branch.revision_count += 1 |
236 | 372 | 372 |
This specific change looks OK to me, but it implies there is an idea about how to get to the end goal. I'd like to know what the ideas of how to get to the end goal of this are, before landing this change, though.
There's a lot of ugliness in the current tests that I think could/should be cleaned up first, for example. Abstracting the bzr integration away and switching to use mocking in the tests, instead of creating actual branches and performing actions in them, will make things more reliable, and easy to repeat across VCS implementations.