Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Jelmer Vernooij | ||||
Approved revision: | no longer in the source branch. | ||||
Merge reported by: | The Breezy Bot | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~jelmer/brz/clone | ||||
Merge into: | lp:brz/3.1 | ||||
Diff against target: |
948 lines (+305/-83) 20 files modified
breezy/branch.py (+3/-3) breezy/builtins.py (+33/-0) breezy/bzr/branch.py (+3/-3) breezy/bzr/bzrdir.py (+29/-14) breezy/bzr/remote.py (+23/-4) breezy/bzr/smart/bzrdir.py (+10/-3) breezy/controldir.py (+12/-0) breezy/git/dir.py (+25/-9) breezy/git/tests/test_blackbox.py (+3/-3) breezy/git/tests/test_remote.py (+2/-0) breezy/info.py (+1/-1) breezy/plugins/weave_fmt/bzrdir.py (+1/-1) breezy/tests/blackbox/__init__.py (+1/-0) breezy/tests/blackbox/test_clone.py (+70/-0) breezy/tests/blackbox/test_switch.py (+1/-1) breezy/tests/per_bzrdir/test_bzrdir.py (+1/-1) breezy/tests/per_controldir/test_controldir.py (+62/-40) breezy/tests/per_controldir_colo/test_supported.py (+5/-0) breezy/tests/test_smart.py (+13/-0) doc/en/release-notes/brz-3.1.txt (+7/-0) |
||||
To merge this branch: | bzr merge lp:~jelmer/brz/clone | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email:
|
Commit message
Add a 'brz clone' command.
Description of the change
Add a 'brz clone' command.
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
The Breezy Bot (the-breezy-bot) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/branch.py' |
2 | --- breezy/branch.py 2020-02-18 03:11:01 +0000 |
3 | +++ breezy/branch.py 2020-03-22 21:30:11 +0000 |
4 | @@ -1194,8 +1194,8 @@ |
5 | if revno < 1 or revno > self.revno(): |
6 | raise errors.InvalidRevisionNumber(revno) |
7 | |
8 | - def clone(self, to_controldir, revision_id=None, repository_policy=None, |
9 | - tag_selector=None): |
10 | + def clone(self, to_controldir, revision_id=None, name=None, |
11 | + repository_policy=None, tag_selector=None): |
12 | """Clone this branch into to_controldir preserving all semantic values. |
13 | |
14 | Most API users will want 'create_clone_on_transport', which creates a |
15 | @@ -1204,7 +1204,7 @@ |
16 | revision_id: if not None, the revision history in the new branch will |
17 | be truncated to end with revision_id. |
18 | """ |
19 | - result = to_controldir.create_branch() |
20 | + result = to_controldir.create_branch(name=name) |
21 | with self.lock_read(), result.lock_write(): |
22 | if repository_policy is not None: |
23 | repository_policy.configure_branch(result) |
24 | |
25 | === modified file 'breezy/builtins.py' |
26 | --- breezy/builtins.py 2020-01-31 02:34:57 +0000 |
27 | +++ breezy/builtins.py 2020-03-22 21:30:11 +0000 |
28 | @@ -1442,6 +1442,7 @@ |
29 | parameter, as in "branch foo/bar -r 5". |
30 | """ |
31 | |
32 | + aliase = ['sprout'] |
33 | _see_also = ['checkout'] |
34 | takes_args = ['from_location', 'to_location?'] |
35 | takes_options = ['revision', |
36 | @@ -1704,6 +1705,38 @@ |
37 | accelerator_tree, hardlink) |
38 | |
39 | |
40 | +class cmd_clone(Command): |
41 | + __doc__ = """Clone a control directory. |
42 | + """ |
43 | + |
44 | + takes_args = ['from_location', 'to_location?'] |
45 | + takes_options = ['revision', |
46 | + Option('no-recurse-nested', |
47 | + help='Do not recursively check out nested trees.'), |
48 | + ] |
49 | + |
50 | + def run(self, from_location, to_location=None, revision=None, no_recurse_nested=False): |
51 | + accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch( |
52 | + from_location) |
53 | + if no_recurse_nested: |
54 | + recurse = 'none' |
55 | + else: |
56 | + recurse = 'down' |
57 | + revision = _get_one_revision('branch', revision) |
58 | + self.enter_context(br_from.lock_read()) |
59 | + if revision is not None: |
60 | + revision_id = revision.as_revision_id(br_from) |
61 | + else: |
62 | + # FIXME - wt.last_revision, fallback to branch, fall back to |
63 | + # None or perhaps NULL_REVISION to mean copy nothing |
64 | + # RBC 20060209 |
65 | + revision_id = br_from.last_revision() |
66 | + if to_location is None: |
67 | + to_location = urlutils.derive_to_location(from_location) |
68 | + target_controldir = br_from.controldir.clone(to_location, revision_id=revision_id) |
69 | + note(gettext('Created new control directory.')) |
70 | + |
71 | + |
72 | class cmd_renames(Command): |
73 | __doc__ = """Show list of renamed files. |
74 | """ |
75 | |
76 | === modified file 'breezy/bzr/branch.py' |
77 | --- breezy/bzr/branch.py 2020-02-18 03:11:01 +0000 |
78 | +++ breezy/bzr/branch.py 2020-03-22 21:30:11 +0000 |
79 | @@ -1032,10 +1032,10 @@ |
80 | |
81 | def _make_reference_clone_function(format, a_branch): |
82 | """Create a clone() routine for a branch dynamically.""" |
83 | - def clone(to_bzrdir, revision_id=None, |
84 | - repository_policy=None, tag_selector=None): |
85 | + def clone(to_bzrdir, revision_id=None, repository_policy=None, name=None, |
86 | + tag_selector=None): |
87 | """See Branch.clone().""" |
88 | - return format.initialize(to_bzrdir, target_branch=a_branch) |
89 | + return format.initialize(to_bzrdir, target_branch=a_branch, name=name) |
90 | # cannot obey revision_id limits when cloning a reference ... |
91 | # FIXME RBC 20060210 either nuke revision_id for clone, or |
92 | # emit some sort of warning/error to the caller ?! |
93 | |
94 | === modified file 'breezy/bzr/bzrdir.py' |
95 | --- breezy/bzr/bzrdir.py 2020-02-18 03:11:01 +0000 |
96 | +++ breezy/bzr/bzrdir.py 2020-03-22 21:30:11 +0000 |
97 | @@ -174,17 +174,18 @@ |
98 | local_repo = self.find_repository() |
99 | except errors.NoRepositoryPresent: |
100 | local_repo = None |
101 | + local_branches = self.get_branches() |
102 | try: |
103 | - local_branch = self.open_branch() |
104 | - except errors.NotBranchError: |
105 | - local_branch = None |
106 | + local_active_branch = local_branches[''] |
107 | + except KeyError: |
108 | + pass |
109 | else: |
110 | # enable fallbacks when branch is not a branch reference |
111 | - if local_branch.repository.has_same_location(local_repo): |
112 | - local_repo = local_branch.repository |
113 | + if local_active_branch.repository.has_same_location(local_repo): |
114 | + local_repo = local_active_branch.repository |
115 | if preserve_stacking: |
116 | try: |
117 | - stacked_on = local_branch.get_stacked_on_url() |
118 | + stacked_on = local_active_branch.get_stacked_on_url() |
119 | except (_mod_branch.UnstackableBranchFormat, |
120 | errors.UnstackableRepositoryFormat, |
121 | errors.NotStacked): |
122 | @@ -233,11 +234,11 @@ |
123 | # 1 if there is a branch present |
124 | # make sure its content is available in the target repository |
125 | # clone it. |
126 | - if local_branch is not None: |
127 | + for name, local_branch in local_branches.items(): |
128 | local_branch.clone( |
129 | - result, revision_id=revision_id, |
130 | + result, revision_id=(None if name != '' else revision_id), |
131 | repository_policy=repository_policy, |
132 | - tag_selector=tag_selector) |
133 | + name=name, tag_selector=tag_selector) |
134 | try: |
135 | # Cheaper to check if the target is not local, than to try making |
136 | # the tree and fail. |
137 | @@ -1016,6 +1017,18 @@ |
138 | pass |
139 | return self.transport.clone('checkout') |
140 | |
141 | + def branch_names(self): |
142 | + """See ControlDir.branch_names.""" |
143 | + ret = [] |
144 | + try: |
145 | + self.get_branch_reference() |
146 | + except errors.NotBranchError: |
147 | + pass |
148 | + else: |
149 | + ret.append("") |
150 | + ret.extend(self._read_branch_list()) |
151 | + return ret |
152 | + |
153 | def get_branches(self): |
154 | """See ControlDir.get_branches.""" |
155 | ret = {} |
156 | @@ -1314,11 +1327,13 @@ |
157 | remote_dir_format = RemoteBzrDirFormat() |
158 | remote_dir_format._network_name = self.network_name() |
159 | self._supply_sub_formats_to(remote_dir_format) |
160 | - return remote_dir_format.initialize_on_transport_ex(transport, |
161 | - use_existing_dir=use_existing_dir, create_prefix=create_prefix, |
162 | - force_new_repo=force_new_repo, stacked_on=stacked_on, |
163 | - stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name, |
164 | - make_working_trees=make_working_trees, shared_repo=shared_repo) |
165 | + return remote_dir_format.initialize_on_transport_ex( |
166 | + transport, use_existing_dir=use_existing_dir, |
167 | + create_prefix=create_prefix, force_new_repo=force_new_repo, |
168 | + stacked_on=stacked_on, stack_on_pwd=stack_on_pwd, |
169 | + repo_format_name=repo_format_name, |
170 | + make_working_trees=make_working_trees, |
171 | + shared_repo=shared_repo) |
172 | # XXX: Refactor the create_prefix/no_create_prefix code into a |
173 | # common helper function |
174 | # The destination may not exist - if so make it according to policy. |
175 | |
176 | === modified file 'breezy/bzr/remote.py' |
177 | --- breezy/bzr/remote.py 2020-02-19 04:50:09 +0000 |
178 | +++ breezy/bzr/remote.py 2020-03-22 21:30:11 +0000 |
179 | @@ -707,6 +707,23 @@ |
180 | b = self.open_branch(name=name) |
181 | return b._format |
182 | |
183 | + def branch_names(self): |
184 | + path = self._path_for_remote_call(self._client) |
185 | + try: |
186 | + response, handler = self._call_expecting_body( |
187 | + b'BzrDir.get_branches', path) |
188 | + except errors.UnknownSmartMethod: |
189 | + self._ensure_real() |
190 | + return self._real_bzrdir.branch_names() |
191 | + if response[0] != b"success": |
192 | + raise errors.UnexpectedSmartServerResponse(response) |
193 | + body = bencode.bdecode(handler.read_body_bytes()) |
194 | + ret = [] |
195 | + for name, value in viewitems(body): |
196 | + name = name.decode('utf-8') |
197 | + ret.append(name) |
198 | + return ret |
199 | + |
200 | def get_branches(self, possible_transports=None, ignore_fallbacks=False): |
201 | path = self._path_for_remote_call(self._client) |
202 | try: |
203 | @@ -721,9 +738,10 @@ |
204 | ret = {} |
205 | for name, value in viewitems(body): |
206 | name = name.decode('utf-8') |
207 | - ret[name] = self._open_branch(name, value[0], value[1], |
208 | - possible_transports=possible_transports, |
209 | - ignore_fallbacks=ignore_fallbacks) |
210 | + ret[name] = self._open_branch( |
211 | + name, value[0].decode('ascii'), value[1], |
212 | + possible_transports=possible_transports, |
213 | + ignore_fallbacks=ignore_fallbacks) |
214 | return ret |
215 | |
216 | def set_branch_reference(self, target_branch, name=None): |
217 | @@ -792,8 +810,9 @@ |
218 | if kind == 'ref': |
219 | # a branch reference, use the existing BranchReference logic. |
220 | format = BranchReferenceFormat() |
221 | + ref_loc = urlutils.join(self.user_url, location_or_format.decode('utf-8')) |
222 | return format.open(self, name=name, _found=True, |
223 | - location=location_or_format.decode('utf-8'), |
224 | + location=ref_loc, |
225 | ignore_fallbacks=ignore_fallbacks, |
226 | possible_transports=possible_transports) |
227 | branch_format_name = location_or_format |
228 | |
229 | === modified file 'breezy/bzr/smart/bzrdir.py' |
230 | --- breezy/bzr/smart/bzrdir.py 2018-11-11 04:08:32 +0000 |
231 | +++ breezy/bzr/smart/bzrdir.py 2020-03-22 21:30:11 +0000 |
232 | @@ -443,12 +443,19 @@ |
233 | The body is a bencoded dictionary, with values similar to the return |
234 | value of the open branch request. |
235 | """ |
236 | - branches = self._bzrdir.get_branches() |
237 | + branch_names = self._bzrdir.branch_names() |
238 | ret = {} |
239 | - for name, b in branches.items(): |
240 | + for name in branch_names: |
241 | if name is None: |
242 | name = b"" |
243 | - ret[name.encode('utf-8')] = (b"branch", b._format.network_name()) |
244 | + branch_ref = self._bzrdir.get_branch_reference(name=name) |
245 | + if branch_ref is not None: |
246 | + branch_ref = urlutils.relative_url(self._bzrdir.user_url, branch_ref) |
247 | + value = (b"ref", branch_ref.encode('utf-8')) |
248 | + else: |
249 | + b = self._bzrdir.open_branch(name=name, ignore_fallbacks=True) |
250 | + value = (b"branch", b._format.network_name()) |
251 | + ret[name.encode('utf-8')] = value |
252 | return SuccessfulSmartServerResponse( |
253 | (b"success", ), bencode.bencode(ret)) |
254 | |
255 | |
256 | === modified file 'breezy/controldir.py' |
257 | --- breezy/controldir.py 2020-02-18 03:11:01 +0000 |
258 | +++ breezy/controldir.py 2020-03-22 21:30:11 +0000 |
259 | @@ -129,6 +129,18 @@ |
260 | """ |
261 | return list(self.get_branches().values()) |
262 | |
263 | + def branch_names(self): |
264 | + """List all branch names in this control directory. |
265 | + |
266 | + :return: List of branch names |
267 | + """ |
268 | + try: |
269 | + self.get_branch_reference() |
270 | + except (errors.NotBranchError, errors.NoRepositoryPresent): |
271 | + return [] |
272 | + else: |
273 | + return [""] |
274 | + |
275 | def get_branches(self): |
276 | """Get all branches in this control directory, as a dictionary. |
277 | |
278 | |
279 | === modified file 'breezy/git/dir.py' |
280 | --- breezy/git/dir.py 2020-02-19 04:50:09 +0000 |
281 | +++ breezy/git/dir.py 2020-03-22 21:30:11 +0000 |
282 | @@ -228,6 +228,7 @@ |
283 | """See ControlDir.clone_on_transport.""" |
284 | from ..repository import InterRepository |
285 | from .mapping import default_mapping |
286 | + from ..transport.local import LocalTransport |
287 | if stacked_on is not None: |
288 | raise _mod_branch.UnstackableBranchFormat( |
289 | self._format, self.user_url) |
290 | @@ -253,18 +254,19 @@ |
291 | mapping=default_mapping) |
292 | for name, val in viewitems(refs): |
293 | target_git_repo.refs[name] = val |
294 | - result_dir = self.__class__(transport, target_git_repo, format) |
295 | + result_dir = LocalGitDir(transport, target_git_repo, format) |
296 | if revision_id is not None: |
297 | result_dir.open_branch().set_last_revision(revision_id) |
298 | - try: |
299 | - # Cheaper to check if the target is not local, than to try making |
300 | - # the tree and fail. |
301 | - result_dir.root_transport.local_abspath('.') |
302 | + if not no_tree and isinstance(result_dir.root_transport, LocalTransport): |
303 | if result_dir.open_repository().make_working_trees(): |
304 | - self.open_workingtree().clone( |
305 | - result_dir, revision_id=revision_id) |
306 | - except (brz_errors.NoWorkingTree, brz_errors.NotLocalUrl): |
307 | - pass |
308 | + try: |
309 | + local_wt = self.open_workingtree() |
310 | + except brz_errors.NoWorkingTree: |
311 | + pass |
312 | + except brz_errors.NotLocalUrl: |
313 | + result_dir.create_workingtree(revision_id=revision_id) |
314 | + else: |
315 | + local_wt.clone(result_dir, revision_id=revision_id) |
316 | |
317 | return result_dir |
318 | |
319 | @@ -299,6 +301,20 @@ |
320 | """ |
321 | return UseExistingRepository(self.find_repository()) |
322 | |
323 | + def branch_names(self): |
324 | + from .refs import ref_to_branch_name |
325 | + ret = [] |
326 | + for ref in self.get_refs_container().keys(): |
327 | + try: |
328 | + branch_name = ref_to_branch_name(ref) |
329 | + except UnicodeDecodeError: |
330 | + trace.warning("Ignoring branch %r with unicode error ref", ref) |
331 | + continue |
332 | + except ValueError: |
333 | + continue |
334 | + ret.append(branch_name) |
335 | + return ret |
336 | + |
337 | def get_branches(self): |
338 | from .refs import ref_to_branch_name |
339 | ret = {} |
340 | |
341 | === modified file 'breezy/git/tests/test_blackbox.py' |
342 | --- breezy/git/tests/test_blackbox.py 2020-03-21 20:56:33 +0000 |
343 | +++ breezy/git/tests/test_blackbox.py 2020-03-22 21:30:11 +0000 |
344 | @@ -349,7 +349,7 @@ |
345 | self.run_bzr(["git-import", "--colocated", "a", "b"]) |
346 | self.assertEqual(set([".bzr"]), set(os.listdir("b"))) |
347 | self.assertEqual(set(["abranch", "bbranch"]), |
348 | - set(ControlDir.open("b").get_branches().keys())) |
349 | + set(ControlDir.open("b").branch_names())) |
350 | |
351 | def test_git_import_incremental(self): |
352 | r = GitRepo.init("a", mkdir=True) |
353 | @@ -361,7 +361,7 @@ |
354 | self.run_bzr(["git-import", "--colocated", "a", "b"]) |
355 | self.assertEqual(set([".bzr"]), set(os.listdir("b"))) |
356 | b = ControlDir.open("b") |
357 | - self.assertEqual(["abranch"], list(b.get_branches().keys())) |
358 | + self.assertEqual(["abranch"], b.branch_names()) |
359 | |
360 | def test_git_import_tags(self): |
361 | r = GitRepo.init("a", mkdir=True) |
362 | @@ -373,7 +373,7 @@ |
363 | self.run_bzr(["git-import", "--colocated", "a", "b"]) |
364 | self.assertEqual(set([".bzr"]), set(os.listdir("b"))) |
365 | b = ControlDir.open("b") |
366 | - self.assertEqual(["abranch"], list(b.get_branches().keys())) |
367 | + self.assertEqual(["abranch"], b.branch_names()) |
368 | self.assertEqual(["atag"], |
369 | list(b.open_branch("abranch").tags.get_tag_dict().keys())) |
370 | |
371 | |
372 | === modified file 'breezy/git/tests/test_remote.py' |
373 | --- breezy/git/tests/test_remote.py 2020-02-08 18:51:59 +0000 |
374 | +++ breezy/git/tests/test_remote.py 2020-03-22 21:30:11 +0000 |
375 | @@ -567,6 +567,8 @@ |
376 | self.assertEqual( |
377 | {'': 'master', 'blah': 'blah', 'master': 'master'}, |
378 | {n: b.name for (n, b) in remote.get_branches().items()}) |
379 | + self.assertEqual( |
380 | + set(['', 'blah', 'master']), set(remote.branch_names())) |
381 | |
382 | def test_remove_tag(self): |
383 | c1 = self.remote_real.do_commit( |
384 | |
385 | === modified file 'breezy/info.py' |
386 | --- breezy/info.py 2019-11-19 18:10:28 +0000 |
387 | +++ breezy/info.py 2020-03-22 21:30:11 +0000 |
388 | @@ -457,7 +457,7 @@ |
389 | extra = [] |
390 | if repository.make_working_trees(): |
391 | extra.append('trees') |
392 | - if len(control.get_branches()) > 0: |
393 | + if len(control.branch_names()) > 0: |
394 | extra.append('colocated branches') |
395 | if extra: |
396 | phrase += ' with ' + " and ".join(extra) |
397 | |
398 | === modified file 'breezy/plugins/weave_fmt/bzrdir.py' |
399 | --- breezy/plugins/weave_fmt/bzrdir.py 2020-02-18 03:16:21 +0000 |
400 | +++ breezy/plugins/weave_fmt/bzrdir.py 2020-03-22 21:30:11 +0000 |
401 | @@ -842,7 +842,7 @@ |
402 | |
403 | def get_branch_transport(self, branch_format, name=None): |
404 | """See BzrDir.get_branch_transport().""" |
405 | - if name is not None: |
406 | + if name: |
407 | raise errors.NoColocatedBranchSupport(self) |
408 | if branch_format is None: |
409 | return self.transport |
410 | |
411 | === modified file 'breezy/tests/blackbox/__init__.py' |
412 | --- breezy/tests/blackbox/__init__.py 2019-06-15 17:06:40 +0000 |
413 | +++ breezy/tests/blackbox/__init__.py 2020-03-22 21:30:11 +0000 |
414 | @@ -51,6 +51,7 @@ |
415 | 'test_check', |
416 | 'test_checkout', |
417 | 'test_clean_tree', |
418 | + 'test_clone', |
419 | 'test_command_encoding', |
420 | 'test_commit', |
421 | 'test_config', |
422 | |
423 | === added file 'breezy/tests/blackbox/test_clone.py' |
424 | --- breezy/tests/blackbox/test_clone.py 1970-01-01 00:00:00 +0000 |
425 | +++ breezy/tests/blackbox/test_clone.py 2020-03-22 21:30:11 +0000 |
426 | @@ -0,0 +1,70 @@ |
427 | +# Copyright (C) 2006-2012, 2016 Canonical Ltd |
428 | +# |
429 | +# This program is free software; you can redistribute it and/or modify |
430 | +# it under the terms of the GNU General Public License as published by |
431 | +# the Free Software Foundation; either version 2 of the License, or |
432 | +# (at your option) any later version. |
433 | +# |
434 | +# This program is distributed in the hope that it will be useful, |
435 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
436 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
437 | +# GNU General Public License for more details. |
438 | +# |
439 | +# You should have received a copy of the GNU General Public License |
440 | +# along with this program; if not, write to the Free Software |
441 | +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
442 | + |
443 | + |
444 | +"""Black-box tests for brz branch.""" |
445 | + |
446 | +import os |
447 | + |
448 | +from breezy import ( |
449 | + branch, |
450 | + controldir, |
451 | + tests, |
452 | + ) |
453 | +from breezy.urlutils import local_path_to_url |
454 | + |
455 | + |
456 | +class TestClone(tests.TestCaseWithTransport): |
457 | + |
458 | + def example_dir(self, path='.', format=None): |
459 | + tree = self.make_branch_and_tree(path, format=format) |
460 | + self.build_tree_contents([(path + '/hello', b'foo')]) |
461 | + tree.add('hello') |
462 | + tree.commit(message='setup') |
463 | + self.build_tree_contents([(path + '/goodbye', b'baz')]) |
464 | + tree.add('goodbye') |
465 | + tree.commit(message='setup') |
466 | + return tree |
467 | + |
468 | + def test_clone(self): |
469 | + """Branch from one branch to another.""" |
470 | + self.example_dir('a') |
471 | + self.run_bzr('clone a b') |
472 | + b = branch.Branch.open('b') |
473 | + self.run_bzr('clone a c -r 1') |
474 | + # previously was erroneously created by branching |
475 | + self.assertFalse(b._transport.has('branch-name')) |
476 | + b.controldir.open_workingtree().commit(message='foo', allow_pointless=True) |
477 | + |
478 | + def test_clone_no_to_location(self): |
479 | + """The to_location is derived from the source branch name.""" |
480 | + os.mkdir("something") |
481 | + a = self.example_dir('something/a').branch |
482 | + self.run_bzr('clone something/a') |
483 | + b = branch.Branch.open('a') |
484 | + self.assertEqual(b.last_revision_info(), a.last_revision_info()) |
485 | + |
486 | + def test_from_colocated(self): |
487 | + """Branch from a colocated branch into a regular branch.""" |
488 | + os.mkdir('b') |
489 | + tree = self.example_dir('b/a') |
490 | + tree.controldir.create_branch(name='somecolo') |
491 | + out, err = self.run_bzr('clone %s' % local_path_to_url('b/a')) |
492 | + self.assertEqual('', out) |
493 | + self.assertEqual('Created new control directory.\n', err) |
494 | + self.assertPathExists('a') |
495 | + target = controldir.ControlDir.open('a') |
496 | + self.assertEqual(['', 'somecolo'], target.branch_names()) |
497 | |
498 | === modified file 'breezy/tests/blackbox/test_switch.py' |
499 | --- breezy/tests/blackbox/test_switch.py 2019-09-01 15:33:59 +0000 |
500 | +++ breezy/tests/blackbox/test_switch.py 2020-03-22 21:30:11 +0000 |
501 | @@ -207,7 +207,7 @@ |
502 | self.run_bzr(['switch', '-b', 'anotherbranch']) |
503 | self.assertEqual( |
504 | {'', 'anotherbranch'}, |
505 | - set(tree.branch.controldir.get_branches().keys())) |
506 | + set(tree.branch.controldir.branch_names())) |
507 | |
508 | def test_switch_into_unrelated_colocated(self): |
509 | # Create a new colocated branch from an existing non-colocated branch. |
510 | |
511 | === modified file 'breezy/tests/per_bzrdir/test_bzrdir.py' |
512 | --- breezy/tests/per_bzrdir/test_bzrdir.py 2018-11-11 04:08:32 +0000 |
513 | +++ breezy/tests/per_bzrdir/test_bzrdir.py 2020-03-22 21:30:11 +0000 |
514 | @@ -688,4 +688,4 @@ |
515 | target_branch = repo.controldir.create_branch(name='foo') |
516 | repo.controldir.set_branch_reference(target_branch) |
517 | self.assertEqual({"", 'foo'}, |
518 | - set(repo.controldir.get_branches().keys())) |
519 | + set(repo.controldir.branch_names())) |
520 | |
521 | === modified file 'breezy/tests/per_controldir/test_controldir.py' |
522 | --- breezy/tests/per_controldir/test_controldir.py 2019-05-29 03:22:34 +0000 |
523 | +++ breezy/tests/per_controldir/test_controldir.py 2020-03-22 21:30:11 +0000 |
524 | @@ -199,7 +199,7 @@ |
525 | "control directories without working tree") |
526 | self.assertRaises(errors.NoWorkingTree, dir.open_workingtree) |
527 | |
528 | - def test_clone_bzrdir_repository_under_shared(self): |
529 | + def test_clone_controldir_repository_under_shared(self): |
530 | tree = self.make_branch_and_tree('commit_tree') |
531 | self.build_tree( |
532 | ['foo'], transport=tree.controldir.transport.clone('..')) |
533 | @@ -221,7 +221,7 @@ |
534 | self.assertNotEqual(dir.transport.base, target.transport.base) |
535 | self.assertRaises(errors.NoRepositoryPresent, target.open_repository) |
536 | |
537 | - def test_clone_bzrdir_repository_branch_both_under_shared(self): |
538 | + def test_clone_controldir_repository_branch_both_under_shared(self): |
539 | # Create a shared repository |
540 | try: |
541 | shared_repo = self.make_repository('shared', shared=True) |
542 | @@ -249,7 +249,7 @@ |
543 | dir.create_branch() |
544 | # Clone 'source' to 'target', also inside the shared repository. |
545 | target = dir.clone(self.get_url('shared/target')) |
546 | - # 'source', 'target', and the shared repo all have distinct bzrdirs. |
547 | + # 'source', 'target', and the shared repo all have distinct controldirs. |
548 | self.assertNotEqual(dir.transport.base, target.transport.base) |
549 | self.assertNotEqual( |
550 | dir.transport.base, shared_repo.controldir.transport.base) |
551 | @@ -258,7 +258,7 @@ |
552 | # 'commit_tree' branch. |
553 | self.assertTrue(shared_repo.has_revision(rev1)) |
554 | |
555 | - def test_clone_bzrdir_repository_branch_only_source_under_shared(self): |
556 | + def test_clone_controldir_repository_branch_only_source_under_shared(self): |
557 | try: |
558 | shared_repo = self.make_repository('shared', shared=True) |
559 | except errors.IncompatibleFormat: |
560 | @@ -291,7 +291,7 @@ |
561 | self.assertFalse(branch.repository.make_working_trees()) |
562 | self.assertTrue(branch.repository.is_shared()) |
563 | |
564 | - def test_clone_bzrdir_repository_revision(self): |
565 | + def test_clone_controldir_repository_revision(self): |
566 | # test for revision limiting, [smoke test, not corner case checks]. |
567 | # make a repository with some revisions, |
568 | # and clone it with a revision limit. |
569 | @@ -310,7 +310,7 @@ |
570 | dir.clone(self.get_url('target'), revision_id=rev2) |
571 | raise TestSkipped('revision limiting not strict yet') |
572 | |
573 | - def test_clone_bzrdir_branch_and_repo_fixed_user_id(self): |
574 | + def test_clone_controldir_branch_and_repo_fixed_user_id(self): |
575 | # Bug #430868 is about an email containing '.sig' |
576 | self.overrideEnv('BRZ_EMAIL', 'murphy@host.sighup.org') |
577 | tree = self.make_branch_and_tree('commit_tree') |
578 | @@ -330,7 +330,7 @@ |
579 | tree_repo.get_signature_text(rev1), |
580 | target.repository.get_signature_text(rev1)) |
581 | |
582 | - def test_clone_bzrdir_branch_and_repo_into_shared_repo(self): |
583 | + def test_clone_controldir_branch_and_repo_into_shared_repo(self): |
584 | # by default cloning into a shared repo uses the shared repo. |
585 | tree = self.make_branch_and_tree('commit_tree') |
586 | self.build_tree(['commit_tree/foo']) |
587 | @@ -354,7 +354,7 @@ |
588 | self.assertEqual(source.last_revision(), |
589 | target.open_branch().last_revision()) |
590 | |
591 | - def test_clone_bzrdir_branch_revision(self): |
592 | + def test_clone_controldir_branch_revision(self): |
593 | # test for revision limiting, [smoke test, not corner case checks]. |
594 | # make a branch with some revisions, |
595 | # and clone it with a revision limit. |
596 | @@ -371,6 +371,23 @@ |
597 | target = dir.clone(self.get_url('target'), revision_id=rev1) |
598 | self.assertEqual(rev1, target.open_branch().last_revision()) |
599 | |
600 | + def test_clone_controldir_with_colocated(self): |
601 | + if not self.bzrdir_format.colocated_branches: |
602 | + raise TestNotApplicable( |
603 | + 'format does not supported colocated branches') |
604 | + tree = self.make_branch_and_tree('commit_tree') |
605 | + self.build_tree(['commit_tree/foo']) |
606 | + tree.add('foo') |
607 | + rev1 = tree.commit('revision 1') |
608 | + rev2 = tree.commit('revision 2', allow_pointless=True) |
609 | + rev3 = tree.commit('revision 2', allow_pointless=True) |
610 | + dir = tree.branch.controldir |
611 | + colo = dir.create_branch(name='colo') |
612 | + colo.pull(tree.branch, stop_revision=rev1) |
613 | + target = dir.clone(self.get_url('target'), revision_id=rev2) |
614 | + self.assertEqual(rev2, target.open_branch().last_revision()) |
615 | + self.assertEqual(rev1, target.open_branch(name='colo').last_revision()) |
616 | + |
617 | def test_clone_on_transport_preserves_repo_format(self): |
618 | if self.bzrdir_format == controldir.format_registry.make_controldir('default'): |
619 | format = 'knit' |
620 | @@ -381,8 +398,8 @@ |
621 | a_dir = breezy.branch.Branch.open_from_transport( |
622 | self.get_transport('source')).controldir |
623 | target_transport = self.get_transport('target') |
624 | - target_bzrdir = a_dir.clone_on_transport(target_transport) |
625 | - target_repo = target_bzrdir.open_repository() |
626 | + target_controldir = a_dir.clone_on_transport(target_transport) |
627 | + target_repo = target_controldir.open_repository() |
628 | source_branch = breezy.branch.Branch.open( |
629 | self.get_vfs_only_url('source')) |
630 | if isinstance(target_repo, RemoteRepository): |
631 | @@ -390,7 +407,7 @@ |
632 | target_repo = target_repo._real_repository |
633 | self.assertEqual(target_repo._format, source_branch.repository._format) |
634 | |
635 | - def test_clone_bzrdir_tree_revision(self): |
636 | + def test_clone_controldir_tree_revision(self): |
637 | # test for revision limiting, [smoke test, not corner case checks]. |
638 | # make a tree with a revision with a last-revision |
639 | # and clone it with a revision limit. |
640 | @@ -406,7 +423,7 @@ |
641 | self.skipIfNoWorkingTree(target) |
642 | self.assertEqual([rev1], target.open_workingtree().get_parent_ids()) |
643 | |
644 | - def test_clone_bzrdir_into_notrees_repo(self): |
645 | + def test_clone_controldir_into_notrees_repo(self): |
646 | """Cloning into a no-trees repo should not create a working tree""" |
647 | tree = self.make_branch_and_tree('source') |
648 | self.build_tree(['source/foo']) |
649 | @@ -514,12 +531,12 @@ |
650 | """get_branch_reference should not mask NotBranchErrors.""" |
651 | dir = self.make_controldir('source') |
652 | if dir.has_branch(): |
653 | - # this format does not support branchless bzrdirs. |
654 | + # this format does not support branchless controldirs. |
655 | raise TestNotApplicable("format does not support " |
656 | "branchless control directories") |
657 | self.assertRaises(errors.NotBranchError, dir.get_branch_reference) |
658 | |
659 | - def test_sprout_bzrdir_empty(self): |
660 | + def test_sprout_controldir_empty(self): |
661 | dir = self.make_controldir('source') |
662 | target = dir.sprout(self.get_url('target')) |
663 | self.assertNotEqual(dir.control_transport.base, |
664 | @@ -529,7 +546,7 @@ |
665 | target.open_branch() |
666 | self.openWorkingTreeIfLocal(target) |
667 | |
668 | - def test_sprout_bzrdir_empty_under_shared_repo(self): |
669 | + def test_sprout_controldir_empty_under_shared_repo(self): |
670 | # sprouting an empty dir into a repo uses the repo |
671 | dir = self.make_controldir('source') |
672 | try: |
673 | @@ -543,13 +560,13 @@ |
674 | try: |
675 | target.open_workingtree() |
676 | except errors.NoWorkingTree: |
677 | - # Some bzrdirs can never have working trees. |
678 | + # Some controldirs can never have working trees. |
679 | repo = target.find_repository() |
680 | self.assertFalse(repo.controldir._format.supports_workingtrees) |
681 | |
682 | - def test_sprout_bzrdir_empty_under_shared_repo_force_new(self): |
683 | + def test_sprout_controldir_empty_under_shared_repo_force_new(self): |
684 | # the force_new_repo parameter should force use of a new repo in an empty |
685 | - # bzrdir's sprout logic |
686 | + # controldir's sprout logic |
687 | dir = self.make_controldir('source') |
688 | try: |
689 | self.make_repository('target', shared=True) |
690 | @@ -561,7 +578,7 @@ |
691 | target.open_branch() |
692 | self.openWorkingTreeIfLocal(target) |
693 | |
694 | - def test_sprout_bzrdir_with_repository_to_shared(self): |
695 | + def test_sprout_controldir_with_repository_to_shared(self): |
696 | tree = self.make_branch_and_tree('commit_tree') |
697 | self.build_tree(['commit_tree/foo']) |
698 | tree.add('foo') |
699 | @@ -583,7 +600,7 @@ |
700 | target.user_transport.base) |
701 | self.assertTrue(shared_repo.has_revision(rev1)) |
702 | |
703 | - def test_sprout_bzrdir_repository_branch_both_under_shared(self): |
704 | + def test_sprout_controldir_repository_branch_both_under_shared(self): |
705 | try: |
706 | shared_repo = self.make_repository('shared', shared=True) |
707 | except errors.IncompatibleFormat: |
708 | @@ -609,7 +626,7 @@ |
709 | shared_repo.controldir.transport.base) |
710 | self.assertTrue(shared_repo.has_revision(rev1)) |
711 | |
712 | - def test_sprout_bzrdir_repository_branch_only_source_under_shared(self): |
713 | + def test_sprout_controldir_repository_branch_only_source_under_shared(self): |
714 | try: |
715 | shared_repo = self.make_repository('shared', shared=True) |
716 | except errors.IncompatibleFormat: |
717 | @@ -639,7 +656,7 @@ |
718 | dir.transport.base, |
719 | shared_repo.controldir.transport.base) |
720 | branch = target.open_branch() |
721 | - # The sprouted bzrdir has a branch, so only revisions referenced by |
722 | + # The sprouted controldir has a branch, so only revisions referenced by |
723 | # that branch are copied, rather than the whole repository. It's an |
724 | # empty branch, so none are copied. |
725 | self.assertEqual([], branch.repository.all_revision_ids()) |
726 | @@ -647,7 +664,7 @@ |
727 | self.assertTrue(branch.repository.make_working_trees()) |
728 | self.assertFalse(branch.repository.is_shared()) |
729 | |
730 | - def test_sprout_bzrdir_repository_under_shared_force_new_repo(self): |
731 | + def test_sprout_controldir_repository_under_shared_force_new_repo(self): |
732 | tree = self.make_branch_and_tree('commit_tree') |
733 | self.build_tree(['commit_tree/foo']) |
734 | tree.add('foo') |
735 | @@ -670,7 +687,7 @@ |
736 | target.control_transport.base) |
737 | self.assertFalse(shared_repo.has_revision(rev1)) |
738 | |
739 | - def test_sprout_bzrdir_repository_revision(self): |
740 | + def test_sprout_controldir_repository_revision(self): |
741 | # test for revision limiting, [smoke test, not corner case checks]. |
742 | # make a repository with some revisions, |
743 | # and sprout it with a revision limit. |
744 | @@ -689,7 +706,7 @@ |
745 | self.sproutOrSkip(dir, self.get_url('target'), revision_id=rev2) |
746 | raise TestSkipped('revision limiting not strict yet') |
747 | |
748 | - def test_sprout_bzrdir_branch_and_repo_shared(self): |
749 | + def test_sprout_controldir_branch_and_repo_shared(self): |
750 | # sprouting a branch with a repo into a shared repo uses the shared |
751 | # repo |
752 | tree = self.make_branch_and_tree('commit_tree') |
753 | @@ -708,7 +725,7 @@ |
754 | dir.sprout(self.get_url('target/child')) |
755 | self.assertTrue(shared_repo.has_revision(rev1)) |
756 | |
757 | - def test_sprout_bzrdir_branch_and_repo_shared_force_new_repo(self): |
758 | + def test_sprout_controldir_branch_and_repo_shared_force_new_repo(self): |
759 | # sprouting a branch with a repo into a shared repo uses the shared |
760 | # repo |
761 | tree = self.make_branch_and_tree('commit_tree') |
762 | @@ -729,7 +746,7 @@ |
763 | dir.control_transport.base, target.control_transport.base) |
764 | self.assertFalse(shared_repo.has_revision(rev1)) |
765 | |
766 | - def test_sprout_bzrdir_branch_reference(self): |
767 | + def test_sprout_controldir_branch_reference(self): |
768 | # sprouting should create a repository if needed and a sprouted branch. |
769 | referenced_branch = self.make_branch('referenced') |
770 | dir = self.make_controldir('source') |
771 | @@ -747,7 +764,7 @@ |
772 | # place |
773 | target.open_repository() |
774 | |
775 | - def test_sprout_bzrdir_branch_reference_shared(self): |
776 | + def test_sprout_controldir_branch_reference_shared(self): |
777 | # sprouting should create a repository if needed and a sprouted branch. |
778 | referenced_tree = self.make_branch_and_tree('referenced') |
779 | rev1 = referenced_tree.commit('1', allow_pointless=True) |
780 | @@ -773,7 +790,7 @@ |
781 | # and we want revision '1' in the shared repo |
782 | self.assertTrue(shared_repo.has_revision(rev1)) |
783 | |
784 | - def test_sprout_bzrdir_branch_reference_shared_force_new_repo(self): |
785 | + def test_sprout_controldir_branch_reference_shared_force_new_repo(self): |
786 | # sprouting should create a repository if needed and a sprouted branch. |
787 | referenced_tree = self.make_branch_and_tree('referenced') |
788 | rev1 = referenced_tree.commit('1', allow_pointless=True) |
789 | @@ -799,7 +816,7 @@ |
790 | # but not the shared one |
791 | self.assertFalse(shared_repo.has_revision(rev1)) |
792 | |
793 | - def test_sprout_bzrdir_branch_revision(self): |
794 | + def test_sprout_controldir_branch_revision(self): |
795 | # test for revision limiting, [smoke test, not corner case checks]. |
796 | # make a repository with some revisions, |
797 | # and sprout it with a revision limit. |
798 | @@ -816,7 +833,7 @@ |
799 | target = dir.sprout(self.get_url('target'), revision_id=rev1) |
800 | self.assertEqual(rev1, target.open_branch().last_revision()) |
801 | |
802 | - def test_sprout_bzrdir_branch_with_tags(self): |
803 | + def test_sprout_controldir_branch_with_tags(self): |
804 | # when sprouting a branch all revisions named in the tags are copied |
805 | # too. |
806 | builder = self.make_branch_builder('source') |
807 | @@ -835,7 +852,7 @@ |
808 | self.assertEqual(rev2, new_branch.tags.lookup_tag('tag-a')) |
809 | new_branch.repository.get_revision(rev2) |
810 | |
811 | - def test_sprout_bzrdir_branch_with_absent_tag(self): |
812 | + def test_sprout_controldir_branch_with_absent_tag(self): |
813 | # tags referencing absent revisions are copied (and those absent |
814 | # revisions do not prevent the sprout.) |
815 | builder = self.make_branch_builder('source') |
816 | @@ -855,7 +872,7 @@ |
817 | new_branch = target.open_branch() |
818 | self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a')) |
819 | |
820 | - def test_sprout_bzrdir_passing_source_branch_with_absent_tag(self): |
821 | + def test_sprout_controldir_passing_source_branch_with_absent_tag(self): |
822 | # tags referencing absent revisions are copied (and those absent |
823 | # revisions do not prevent the sprout.) |
824 | builder = self.make_branch_builder('source') |
825 | @@ -875,9 +892,9 @@ |
826 | new_branch = target.open_branch() |
827 | self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a')) |
828 | |
829 | - def test_sprout_bzrdir_passing_rev_not_source_branch_copies_tags(self): |
830 | + def test_sprout_controldir_passing_rev_not_source_branch_copies_tags(self): |
831 | # dir.sprout(..., revision_id=b'rev1') copies rev1, and all the tags of |
832 | - # the branch at that bzrdir, the ancestry of all of those, but no other |
833 | + # the branch at that controldir, the ancestry of all of those, but no other |
834 | # revs (not even the tip of the source branch). |
835 | builder = self.make_branch_builder('source') |
836 | base_rev = builder.build_commit(message="Base") |
837 | @@ -927,7 +944,7 @@ |
838 | sorted([base_rev, rev_b1, rev_b2, rev_c1, rev_c2]), |
839 | sorted(new_branch.repository.all_revision_ids())) |
840 | |
841 | - def test_sprout_bzrdir_tree_branch_reference(self): |
842 | + def test_sprout_controldir_tree_branch_reference(self): |
843 | # sprouting should create a repository if needed and a sprouted branch. |
844 | # the tree state should not be copied. |
845 | referenced_branch = self.make_branch('referencced') |
846 | @@ -952,7 +969,7 @@ |
847 | result_tree = target.open_workingtree() |
848 | self.assertFalse(result_tree.has_filename('subdir')) |
849 | |
850 | - def test_sprout_bzrdir_tree_branch_reference_revision(self): |
851 | + def test_sprout_controldir_tree_branch_reference_revision(self): |
852 | # sprouting should create a repository if needed and a sprouted branch. |
853 | # the tree state should not be copied but the revision changed, |
854 | # and the likewise the new branch should be truncated too |
855 | @@ -982,7 +999,7 @@ |
856 | self.assertEqual([rev1], target.open_workingtree().get_parent_ids()) |
857 | self.assertEqual(rev1, target.open_branch().last_revision()) |
858 | |
859 | - def test_sprout_bzrdir_tree_revision(self): |
860 | + def test_sprout_controldir_tree_revision(self): |
861 | # test for revision limiting, [smoke test, not corner case checks]. |
862 | # make a tree with a revision with a last-revision |
863 | # and sprout it with a revision limit. |
864 | @@ -1034,13 +1051,13 @@ |
865 | rev3 = builder.build_commit(message='Rev 3.') |
866 | builder.finish_series() |
867 | stack_on = builder.get_branch() |
868 | - # Make a bzrdir with a default stacking policy to stack on that branch. |
869 | + # Make a controldir with a default stacking policy to stack on that branch. |
870 | config = self.make_controldir('policy-dir').get_config() |
871 | try: |
872 | config.set_default_stack_on(self.get_url('stack-on')) |
873 | except errors.BzrError: |
874 | raise TestNotApplicable('Only relevant for stackable formats.') |
875 | - # Sprout the stacked-on branch into the bzrdir. |
876 | + # Sprout the stacked-on branch into the controldir. |
877 | sprouted = stack_on.controldir.sprout( |
878 | self.get_url('policy-dir/sprouted'), revision_id=rev3) |
879 | # Not all revisions are copied into the sprouted repository. |
880 | @@ -1288,6 +1305,11 @@ |
881 | repo.controldir.create_branch() |
882 | self.assertEqual([""], list(repo.controldir.get_branches())) |
883 | |
884 | + def test_branch_names(self): |
885 | + repo = self.make_repository('branch-1') |
886 | + repo.controldir.create_branch() |
887 | + self.assertEqual([""], repo.controldir.branch_names()) |
888 | + |
889 | def test_create_repository(self): |
890 | # a bzrdir can construct a repository for itself. |
891 | if not self.bzrdir_format.is_initializable(): |
892 | |
893 | === modified file 'breezy/tests/per_controldir_colo/test_supported.py' |
894 | --- breezy/tests/per_controldir_colo/test_supported.py 2019-04-13 21:37:04 +0000 |
895 | +++ breezy/tests/per_controldir_colo/test_supported.py 2020-03-22 21:30:11 +0000 |
896 | @@ -184,6 +184,11 @@ |
897 | self.assertEqual(target_branch.base, |
898 | repo.controldir.get_branches()['foo'].base) |
899 | |
900 | + def test_branch_names(self): |
901 | + repo = self.make_repository('branch-1') |
902 | + target_branch = self.create_branch(repo.controldir, name='foo') |
903 | + self.assertIn('foo', repo.controldir.branch_names()) |
904 | + |
905 | def test_branch_name_with_slash(self): |
906 | repo = self.make_repository('branch-1') |
907 | try: |
908 | |
909 | === modified file 'breezy/tests/test_smart.py' |
910 | --- breezy/tests/test_smart.py 2020-01-18 02:42:17 +0000 |
911 | +++ breezy/tests/test_smart.py 2020-03-22 21:30:11 +0000 |
912 | @@ -485,6 +485,19 @@ |
913 | (b"success", ), local_result) |
914 | self.assertEqual(expected, request.execute(b'')) |
915 | |
916 | + def test_ref(self): |
917 | + backing = self.get_transport() |
918 | + dir = self.make_controldir('foo') |
919 | + b = self.make_branch('bar') |
920 | + dir.set_branch_reference(b) |
921 | + request_class = smart_dir.SmartServerBzrDirRequestGetBranches |
922 | + request = request_class(backing) |
923 | + local_result = bencode.bencode( |
924 | + {b"": (b"ref", b'../bar/')}) |
925 | + expected = smart_req.SuccessfulSmartServerResponse( |
926 | + (b"success", ), local_result) |
927 | + self.assertEqual(expected, request.execute(b'foo')) |
928 | + |
929 | def test_empty(self): |
930 | backing = self.get_transport() |
931 | self.make_controldir('.') |
932 | |
933 | === modified file 'doc/en/release-notes/brz-3.1.txt' |
934 | --- doc/en/release-notes/brz-3.1.txt 2020-03-21 20:56:33 +0000 |
935 | +++ doc/en/release-notes/brz-3.1.txt 2020-03-22 21:30:11 +0000 |
936 | @@ -73,6 +73,13 @@ |
937 | * When pushing to Git repositories, symrefs are now followed. |
938 | (Jelmer Vernooij, #1800393) |
939 | |
940 | + * New ``brz clone`` command, which clones everything under |
941 | + a control directory. I.e. all colocated branches, like |
942 | + ``git clone``. (Jelmer Vernooij, #831939) |
943 | + |
944 | + * ``brz sprout`` is now an alias for ``brz branch``. |
945 | + (Jelmer Vernooij) |
946 | + |
947 | Improvements |
948 | ************ |
949 |
Running landing tests failed /ci.breezy- vcs.org/ job/brz- 3.1/job/ brz-3.1- land/4/
https:/