Merge lp:~jelmer/brz/clone into lp:brz/3.1

Proposed by Jelmer Vernooij
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
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+379369@code.launchpad.net

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
Jelmer Vernooij (jelmer) :
review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'breezy/branch.py'
--- breezy/branch.py 2020-02-18 03:11:01 +0000
+++ breezy/branch.py 2020-03-22 21:30:11 +0000
@@ -1194,8 +1194,8 @@
1194 if revno < 1 or revno > self.revno():1194 if revno < 1 or revno > self.revno():
1195 raise errors.InvalidRevisionNumber(revno)1195 raise errors.InvalidRevisionNumber(revno)
11961196
1197 def clone(self, to_controldir, revision_id=None, repository_policy=None,1197 def clone(self, to_controldir, revision_id=None, name=None,
1198 tag_selector=None):1198 repository_policy=None, tag_selector=None):
1199 """Clone this branch into to_controldir preserving all semantic values.1199 """Clone this branch into to_controldir preserving all semantic values.
12001200
1201 Most API users will want 'create_clone_on_transport', which creates a1201 Most API users will want 'create_clone_on_transport', which creates a
@@ -1204,7 +1204,7 @@
1204 revision_id: if not None, the revision history in the new branch will1204 revision_id: if not None, the revision history in the new branch will
1205 be truncated to end with revision_id.1205 be truncated to end with revision_id.
1206 """1206 """
1207 result = to_controldir.create_branch()1207 result = to_controldir.create_branch(name=name)
1208 with self.lock_read(), result.lock_write():1208 with self.lock_read(), result.lock_write():
1209 if repository_policy is not None:1209 if repository_policy is not None:
1210 repository_policy.configure_branch(result)1210 repository_policy.configure_branch(result)
12111211
=== modified file 'breezy/builtins.py'
--- breezy/builtins.py 2020-01-31 02:34:57 +0000
+++ breezy/builtins.py 2020-03-22 21:30:11 +0000
@@ -1442,6 +1442,7 @@
1442 parameter, as in "branch foo/bar -r 5".1442 parameter, as in "branch foo/bar -r 5".
1443 """1443 """
14441444
1445 aliase = ['sprout']
1445 _see_also = ['checkout']1446 _see_also = ['checkout']
1446 takes_args = ['from_location', 'to_location?']1447 takes_args = ['from_location', 'to_location?']
1447 takes_options = ['revision',1448 takes_options = ['revision',
@@ -1704,6 +1705,38 @@
1704 accelerator_tree, hardlink)1705 accelerator_tree, hardlink)
17051706
17061707
1708class cmd_clone(Command):
1709 __doc__ = """Clone a control directory.
1710 """
1711
1712 takes_args = ['from_location', 'to_location?']
1713 takes_options = ['revision',
1714 Option('no-recurse-nested',
1715 help='Do not recursively check out nested trees.'),
1716 ]
1717
1718 def run(self, from_location, to_location=None, revision=None, no_recurse_nested=False):
1719 accelerator_tree, br_from = controldir.ControlDir.open_tree_or_branch(
1720 from_location)
1721 if no_recurse_nested:
1722 recurse = 'none'
1723 else:
1724 recurse = 'down'
1725 revision = _get_one_revision('branch', revision)
1726 self.enter_context(br_from.lock_read())
1727 if revision is not None:
1728 revision_id = revision.as_revision_id(br_from)
1729 else:
1730 # FIXME - wt.last_revision, fallback to branch, fall back to
1731 # None or perhaps NULL_REVISION to mean copy nothing
1732 # RBC 20060209
1733 revision_id = br_from.last_revision()
1734 if to_location is None:
1735 to_location = urlutils.derive_to_location(from_location)
1736 target_controldir = br_from.controldir.clone(to_location, revision_id=revision_id)
1737 note(gettext('Created new control directory.'))
1738
1739
1707class cmd_renames(Command):1740class cmd_renames(Command):
1708 __doc__ = """Show list of renamed files.1741 __doc__ = """Show list of renamed files.
1709 """1742 """
17101743
=== modified file 'breezy/bzr/branch.py'
--- breezy/bzr/branch.py 2020-02-18 03:11:01 +0000
+++ breezy/bzr/branch.py 2020-03-22 21:30:11 +0000
@@ -1032,10 +1032,10 @@
10321032
1033 def _make_reference_clone_function(format, a_branch):1033 def _make_reference_clone_function(format, a_branch):
1034 """Create a clone() routine for a branch dynamically."""1034 """Create a clone() routine for a branch dynamically."""
1035 def clone(to_bzrdir, revision_id=None,1035 def clone(to_bzrdir, revision_id=None, repository_policy=None, name=None,
1036 repository_policy=None, tag_selector=None):1036 tag_selector=None):
1037 """See Branch.clone()."""1037 """See Branch.clone()."""
1038 return format.initialize(to_bzrdir, target_branch=a_branch)1038 return format.initialize(to_bzrdir, target_branch=a_branch, name=name)
1039 # cannot obey revision_id limits when cloning a reference ...1039 # cannot obey revision_id limits when cloning a reference ...
1040 # FIXME RBC 20060210 either nuke revision_id for clone, or1040 # FIXME RBC 20060210 either nuke revision_id for clone, or
1041 # emit some sort of warning/error to the caller ?!1041 # emit some sort of warning/error to the caller ?!
10421042
=== modified file 'breezy/bzr/bzrdir.py'
--- breezy/bzr/bzrdir.py 2020-02-18 03:11:01 +0000
+++ breezy/bzr/bzrdir.py 2020-03-22 21:30:11 +0000
@@ -174,17 +174,18 @@
174 local_repo = self.find_repository()174 local_repo = self.find_repository()
175 except errors.NoRepositoryPresent:175 except errors.NoRepositoryPresent:
176 local_repo = None176 local_repo = None
177 local_branches = self.get_branches()
177 try:178 try:
178 local_branch = self.open_branch()179 local_active_branch = local_branches['']
179 except errors.NotBranchError:180 except KeyError:
180 local_branch = None181 pass
181 else:182 else:
182 # enable fallbacks when branch is not a branch reference183 # enable fallbacks when branch is not a branch reference
183 if local_branch.repository.has_same_location(local_repo):184 if local_active_branch.repository.has_same_location(local_repo):
184 local_repo = local_branch.repository185 local_repo = local_active_branch.repository
185 if preserve_stacking:186 if preserve_stacking:
186 try:187 try:
187 stacked_on = local_branch.get_stacked_on_url()188 stacked_on = local_active_branch.get_stacked_on_url()
188 except (_mod_branch.UnstackableBranchFormat,189 except (_mod_branch.UnstackableBranchFormat,
189 errors.UnstackableRepositoryFormat,190 errors.UnstackableRepositoryFormat,
190 errors.NotStacked):191 errors.NotStacked):
@@ -233,11 +234,11 @@
233 # 1 if there is a branch present234 # 1 if there is a branch present
234 # make sure its content is available in the target repository235 # make sure its content is available in the target repository
235 # clone it.236 # clone it.
236 if local_branch is not None:237 for name, local_branch in local_branches.items():
237 local_branch.clone(238 local_branch.clone(
238 result, revision_id=revision_id,239 result, revision_id=(None if name != '' else revision_id),
239 repository_policy=repository_policy,240 repository_policy=repository_policy,
240 tag_selector=tag_selector)241 name=name, tag_selector=tag_selector)
241 try:242 try:
242 # Cheaper to check if the target is not local, than to try making243 # Cheaper to check if the target is not local, than to try making
243 # the tree and fail.244 # the tree and fail.
@@ -1016,6 +1017,18 @@
1016 pass1017 pass
1017 return self.transport.clone('checkout')1018 return self.transport.clone('checkout')
10181019
1020 def branch_names(self):
1021 """See ControlDir.branch_names."""
1022 ret = []
1023 try:
1024 self.get_branch_reference()
1025 except errors.NotBranchError:
1026 pass
1027 else:
1028 ret.append("")
1029 ret.extend(self._read_branch_list())
1030 return ret
1031
1019 def get_branches(self):1032 def get_branches(self):
1020 """See ControlDir.get_branches."""1033 """See ControlDir.get_branches."""
1021 ret = {}1034 ret = {}
@@ -1314,11 +1327,13 @@
1314 remote_dir_format = RemoteBzrDirFormat()1327 remote_dir_format = RemoteBzrDirFormat()
1315 remote_dir_format._network_name = self.network_name()1328 remote_dir_format._network_name = self.network_name()
1316 self._supply_sub_formats_to(remote_dir_format)1329 self._supply_sub_formats_to(remote_dir_format)
1317 return remote_dir_format.initialize_on_transport_ex(transport,1330 return remote_dir_format.initialize_on_transport_ex(
1318 use_existing_dir=use_existing_dir, create_prefix=create_prefix,1331 transport, use_existing_dir=use_existing_dir,
1319 force_new_repo=force_new_repo, stacked_on=stacked_on,1332 create_prefix=create_prefix, force_new_repo=force_new_repo,
1320 stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,1333 stacked_on=stacked_on, stack_on_pwd=stack_on_pwd,
1321 make_working_trees=make_working_trees, shared_repo=shared_repo)1334 repo_format_name=repo_format_name,
1335 make_working_trees=make_working_trees,
1336 shared_repo=shared_repo)
1322 # XXX: Refactor the create_prefix/no_create_prefix code into a1337 # XXX: Refactor the create_prefix/no_create_prefix code into a
1323 # common helper function1338 # common helper function
1324 # The destination may not exist - if so make it according to policy.1339 # The destination may not exist - if so make it according to policy.
13251340
=== modified file 'breezy/bzr/remote.py'
--- breezy/bzr/remote.py 2020-02-19 04:50:09 +0000
+++ breezy/bzr/remote.py 2020-03-22 21:30:11 +0000
@@ -707,6 +707,23 @@
707 b = self.open_branch(name=name)707 b = self.open_branch(name=name)
708 return b._format708 return b._format
709709
710 def branch_names(self):
711 path = self._path_for_remote_call(self._client)
712 try:
713 response, handler = self._call_expecting_body(
714 b'BzrDir.get_branches', path)
715 except errors.UnknownSmartMethod:
716 self._ensure_real()
717 return self._real_bzrdir.branch_names()
718 if response[0] != b"success":
719 raise errors.UnexpectedSmartServerResponse(response)
720 body = bencode.bdecode(handler.read_body_bytes())
721 ret = []
722 for name, value in viewitems(body):
723 name = name.decode('utf-8')
724 ret.append(name)
725 return ret
726
710 def get_branches(self, possible_transports=None, ignore_fallbacks=False):727 def get_branches(self, possible_transports=None, ignore_fallbacks=False):
711 path = self._path_for_remote_call(self._client)728 path = self._path_for_remote_call(self._client)
712 try:729 try:
@@ -721,9 +738,10 @@
721 ret = {}738 ret = {}
722 for name, value in viewitems(body):739 for name, value in viewitems(body):
723 name = name.decode('utf-8')740 name = name.decode('utf-8')
724 ret[name] = self._open_branch(name, value[0], value[1],741 ret[name] = self._open_branch(
725 possible_transports=possible_transports,742 name, value[0].decode('ascii'), value[1],
726 ignore_fallbacks=ignore_fallbacks)743 possible_transports=possible_transports,
744 ignore_fallbacks=ignore_fallbacks)
727 return ret745 return ret
728746
729 def set_branch_reference(self, target_branch, name=None):747 def set_branch_reference(self, target_branch, name=None):
@@ -792,8 +810,9 @@
792 if kind == 'ref':810 if kind == 'ref':
793 # a branch reference, use the existing BranchReference logic.811 # a branch reference, use the existing BranchReference logic.
794 format = BranchReferenceFormat()812 format = BranchReferenceFormat()
813 ref_loc = urlutils.join(self.user_url, location_or_format.decode('utf-8'))
795 return format.open(self, name=name, _found=True,814 return format.open(self, name=name, _found=True,
796 location=location_or_format.decode('utf-8'),815 location=ref_loc,
797 ignore_fallbacks=ignore_fallbacks,816 ignore_fallbacks=ignore_fallbacks,
798 possible_transports=possible_transports)817 possible_transports=possible_transports)
799 branch_format_name = location_or_format818 branch_format_name = location_or_format
800819
=== modified file 'breezy/bzr/smart/bzrdir.py'
--- breezy/bzr/smart/bzrdir.py 2018-11-11 04:08:32 +0000
+++ breezy/bzr/smart/bzrdir.py 2020-03-22 21:30:11 +0000
@@ -443,12 +443,19 @@
443 The body is a bencoded dictionary, with values similar to the return443 The body is a bencoded dictionary, with values similar to the return
444 value of the open branch request.444 value of the open branch request.
445 """445 """
446 branches = self._bzrdir.get_branches()446 branch_names = self._bzrdir.branch_names()
447 ret = {}447 ret = {}
448 for name, b in branches.items():448 for name in branch_names:
449 if name is None:449 if name is None:
450 name = b""450 name = b""
451 ret[name.encode('utf-8')] = (b"branch", b._format.network_name())451 branch_ref = self._bzrdir.get_branch_reference(name=name)
452 if branch_ref is not None:
453 branch_ref = urlutils.relative_url(self._bzrdir.user_url, branch_ref)
454 value = (b"ref", branch_ref.encode('utf-8'))
455 else:
456 b = self._bzrdir.open_branch(name=name, ignore_fallbacks=True)
457 value = (b"branch", b._format.network_name())
458 ret[name.encode('utf-8')] = value
452 return SuccessfulSmartServerResponse(459 return SuccessfulSmartServerResponse(
453 (b"success", ), bencode.bencode(ret))460 (b"success", ), bencode.bencode(ret))
454461
455462
=== modified file 'breezy/controldir.py'
--- breezy/controldir.py 2020-02-18 03:11:01 +0000
+++ breezy/controldir.py 2020-03-22 21:30:11 +0000
@@ -129,6 +129,18 @@
129 """129 """
130 return list(self.get_branches().values())130 return list(self.get_branches().values())
131131
132 def branch_names(self):
133 """List all branch names in this control directory.
134
135 :return: List of branch names
136 """
137 try:
138 self.get_branch_reference()
139 except (errors.NotBranchError, errors.NoRepositoryPresent):
140 return []
141 else:
142 return [""]
143
132 def get_branches(self):144 def get_branches(self):
133 """Get all branches in this control directory, as a dictionary.145 """Get all branches in this control directory, as a dictionary.
134146
135147
=== modified file 'breezy/git/dir.py'
--- breezy/git/dir.py 2020-02-19 04:50:09 +0000
+++ breezy/git/dir.py 2020-03-22 21:30:11 +0000
@@ -228,6 +228,7 @@
228 """See ControlDir.clone_on_transport."""228 """See ControlDir.clone_on_transport."""
229 from ..repository import InterRepository229 from ..repository import InterRepository
230 from .mapping import default_mapping230 from .mapping import default_mapping
231 from ..transport.local import LocalTransport
231 if stacked_on is not None:232 if stacked_on is not None:
232 raise _mod_branch.UnstackableBranchFormat(233 raise _mod_branch.UnstackableBranchFormat(
233 self._format, self.user_url)234 self._format, self.user_url)
@@ -253,18 +254,19 @@
253 mapping=default_mapping)254 mapping=default_mapping)
254 for name, val in viewitems(refs):255 for name, val in viewitems(refs):
255 target_git_repo.refs[name] = val256 target_git_repo.refs[name] = val
256 result_dir = self.__class__(transport, target_git_repo, format)257 result_dir = LocalGitDir(transport, target_git_repo, format)
257 if revision_id is not None:258 if revision_id is not None:
258 result_dir.open_branch().set_last_revision(revision_id)259 result_dir.open_branch().set_last_revision(revision_id)
259 try:260 if not no_tree and isinstance(result_dir.root_transport, LocalTransport):
260 # Cheaper to check if the target is not local, than to try making
261 # the tree and fail.
262 result_dir.root_transport.local_abspath('.')
263 if result_dir.open_repository().make_working_trees():261 if result_dir.open_repository().make_working_trees():
264 self.open_workingtree().clone(262 try:
265 result_dir, revision_id=revision_id)263 local_wt = self.open_workingtree()
266 except (brz_errors.NoWorkingTree, brz_errors.NotLocalUrl):264 except brz_errors.NoWorkingTree:
267 pass265 pass
266 except brz_errors.NotLocalUrl:
267 result_dir.create_workingtree(revision_id=revision_id)
268 else:
269 local_wt.clone(result_dir, revision_id=revision_id)
268270
269 return result_dir271 return result_dir
270272
@@ -299,6 +301,20 @@
299 """301 """
300 return UseExistingRepository(self.find_repository())302 return UseExistingRepository(self.find_repository())
301303
304 def branch_names(self):
305 from .refs import ref_to_branch_name
306 ret = []
307 for ref in self.get_refs_container().keys():
308 try:
309 branch_name = ref_to_branch_name(ref)
310 except UnicodeDecodeError:
311 trace.warning("Ignoring branch %r with unicode error ref", ref)
312 continue
313 except ValueError:
314 continue
315 ret.append(branch_name)
316 return ret
317
302 def get_branches(self):318 def get_branches(self):
303 from .refs import ref_to_branch_name319 from .refs import ref_to_branch_name
304 ret = {}320 ret = {}
305321
=== modified file 'breezy/git/tests/test_blackbox.py'
--- breezy/git/tests/test_blackbox.py 2020-03-21 20:56:33 +0000
+++ breezy/git/tests/test_blackbox.py 2020-03-22 21:30:11 +0000
@@ -349,7 +349,7 @@
349 self.run_bzr(["git-import", "--colocated", "a", "b"])349 self.run_bzr(["git-import", "--colocated", "a", "b"])
350 self.assertEqual(set([".bzr"]), set(os.listdir("b")))350 self.assertEqual(set([".bzr"]), set(os.listdir("b")))
351 self.assertEqual(set(["abranch", "bbranch"]),351 self.assertEqual(set(["abranch", "bbranch"]),
352 set(ControlDir.open("b").get_branches().keys()))352 set(ControlDir.open("b").branch_names()))
353353
354 def test_git_import_incremental(self):354 def test_git_import_incremental(self):
355 r = GitRepo.init("a", mkdir=True)355 r = GitRepo.init("a", mkdir=True)
@@ -361,7 +361,7 @@
361 self.run_bzr(["git-import", "--colocated", "a", "b"])361 self.run_bzr(["git-import", "--colocated", "a", "b"])
362 self.assertEqual(set([".bzr"]), set(os.listdir("b")))362 self.assertEqual(set([".bzr"]), set(os.listdir("b")))
363 b = ControlDir.open("b")363 b = ControlDir.open("b")
364 self.assertEqual(["abranch"], list(b.get_branches().keys()))364 self.assertEqual(["abranch"], b.branch_names())
365365
366 def test_git_import_tags(self):366 def test_git_import_tags(self):
367 r = GitRepo.init("a", mkdir=True)367 r = GitRepo.init("a", mkdir=True)
@@ -373,7 +373,7 @@
373 self.run_bzr(["git-import", "--colocated", "a", "b"])373 self.run_bzr(["git-import", "--colocated", "a", "b"])
374 self.assertEqual(set([".bzr"]), set(os.listdir("b")))374 self.assertEqual(set([".bzr"]), set(os.listdir("b")))
375 b = ControlDir.open("b")375 b = ControlDir.open("b")
376 self.assertEqual(["abranch"], list(b.get_branches().keys()))376 self.assertEqual(["abranch"], b.branch_names())
377 self.assertEqual(["atag"],377 self.assertEqual(["atag"],
378 list(b.open_branch("abranch").tags.get_tag_dict().keys()))378 list(b.open_branch("abranch").tags.get_tag_dict().keys()))
379379
380380
=== modified file 'breezy/git/tests/test_remote.py'
--- breezy/git/tests/test_remote.py 2020-02-08 18:51:59 +0000
+++ breezy/git/tests/test_remote.py 2020-03-22 21:30:11 +0000
@@ -567,6 +567,8 @@
567 self.assertEqual(567 self.assertEqual(
568 {'': 'master', 'blah': 'blah', 'master': 'master'},568 {'': 'master', 'blah': 'blah', 'master': 'master'},
569 {n: b.name for (n, b) in remote.get_branches().items()})569 {n: b.name for (n, b) in remote.get_branches().items()})
570 self.assertEqual(
571 set(['', 'blah', 'master']), set(remote.branch_names()))
570572
571 def test_remove_tag(self):573 def test_remove_tag(self):
572 c1 = self.remote_real.do_commit(574 c1 = self.remote_real.do_commit(
573575
=== modified file 'breezy/info.py'
--- breezy/info.py 2019-11-19 18:10:28 +0000
+++ breezy/info.py 2020-03-22 21:30:11 +0000
@@ -457,7 +457,7 @@
457 extra = []457 extra = []
458 if repository.make_working_trees():458 if repository.make_working_trees():
459 extra.append('trees')459 extra.append('trees')
460 if len(control.get_branches()) > 0:460 if len(control.branch_names()) > 0:
461 extra.append('colocated branches')461 extra.append('colocated branches')
462 if extra:462 if extra:
463 phrase += ' with ' + " and ".join(extra)463 phrase += ' with ' + " and ".join(extra)
464464
=== modified file 'breezy/plugins/weave_fmt/bzrdir.py'
--- breezy/plugins/weave_fmt/bzrdir.py 2020-02-18 03:16:21 +0000
+++ breezy/plugins/weave_fmt/bzrdir.py 2020-03-22 21:30:11 +0000
@@ -842,7 +842,7 @@
842842
843 def get_branch_transport(self, branch_format, name=None):843 def get_branch_transport(self, branch_format, name=None):
844 """See BzrDir.get_branch_transport()."""844 """See BzrDir.get_branch_transport()."""
845 if name is not None:845 if name:
846 raise errors.NoColocatedBranchSupport(self)846 raise errors.NoColocatedBranchSupport(self)
847 if branch_format is None:847 if branch_format is None:
848 return self.transport848 return self.transport
849849
=== modified file 'breezy/tests/blackbox/__init__.py'
--- breezy/tests/blackbox/__init__.py 2019-06-15 17:06:40 +0000
+++ breezy/tests/blackbox/__init__.py 2020-03-22 21:30:11 +0000
@@ -51,6 +51,7 @@
51 'test_check',51 'test_check',
52 'test_checkout',52 'test_checkout',
53 'test_clean_tree',53 'test_clean_tree',
54 'test_clone',
54 'test_command_encoding',55 'test_command_encoding',
55 'test_commit',56 'test_commit',
56 'test_config',57 'test_config',
5758
=== added file 'breezy/tests/blackbox/test_clone.py'
--- breezy/tests/blackbox/test_clone.py 1970-01-01 00:00:00 +0000
+++ breezy/tests/blackbox/test_clone.py 2020-03-22 21:30:11 +0000
@@ -0,0 +1,70 @@
1# Copyright (C) 2006-2012, 2016 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
18"""Black-box tests for brz branch."""
19
20import os
21
22from breezy import (
23 branch,
24 controldir,
25 tests,
26 )
27from breezy.urlutils import local_path_to_url
28
29
30class TestClone(tests.TestCaseWithTransport):
31
32 def example_dir(self, path='.', format=None):
33 tree = self.make_branch_and_tree(path, format=format)
34 self.build_tree_contents([(path + '/hello', b'foo')])
35 tree.add('hello')
36 tree.commit(message='setup')
37 self.build_tree_contents([(path + '/goodbye', b'baz')])
38 tree.add('goodbye')
39 tree.commit(message='setup')
40 return tree
41
42 def test_clone(self):
43 """Branch from one branch to another."""
44 self.example_dir('a')
45 self.run_bzr('clone a b')
46 b = branch.Branch.open('b')
47 self.run_bzr('clone a c -r 1')
48 # previously was erroneously created by branching
49 self.assertFalse(b._transport.has('branch-name'))
50 b.controldir.open_workingtree().commit(message='foo', allow_pointless=True)
51
52 def test_clone_no_to_location(self):
53 """The to_location is derived from the source branch name."""
54 os.mkdir("something")
55 a = self.example_dir('something/a').branch
56 self.run_bzr('clone something/a')
57 b = branch.Branch.open('a')
58 self.assertEqual(b.last_revision_info(), a.last_revision_info())
59
60 def test_from_colocated(self):
61 """Branch from a colocated branch into a regular branch."""
62 os.mkdir('b')
63 tree = self.example_dir('b/a')
64 tree.controldir.create_branch(name='somecolo')
65 out, err = self.run_bzr('clone %s' % local_path_to_url('b/a'))
66 self.assertEqual('', out)
67 self.assertEqual('Created new control directory.\n', err)
68 self.assertPathExists('a')
69 target = controldir.ControlDir.open('a')
70 self.assertEqual(['', 'somecolo'], target.branch_names())
071
=== modified file 'breezy/tests/blackbox/test_switch.py'
--- breezy/tests/blackbox/test_switch.py 2019-09-01 15:33:59 +0000
+++ breezy/tests/blackbox/test_switch.py 2020-03-22 21:30:11 +0000
@@ -207,7 +207,7 @@
207 self.run_bzr(['switch', '-b', 'anotherbranch'])207 self.run_bzr(['switch', '-b', 'anotherbranch'])
208 self.assertEqual(208 self.assertEqual(
209 {'', 'anotherbranch'},209 {'', 'anotherbranch'},
210 set(tree.branch.controldir.get_branches().keys()))210 set(tree.branch.controldir.branch_names()))
211211
212 def test_switch_into_unrelated_colocated(self):212 def test_switch_into_unrelated_colocated(self):
213 # Create a new colocated branch from an existing non-colocated branch.213 # Create a new colocated branch from an existing non-colocated branch.
214214
=== modified file 'breezy/tests/per_bzrdir/test_bzrdir.py'
--- breezy/tests/per_bzrdir/test_bzrdir.py 2018-11-11 04:08:32 +0000
+++ breezy/tests/per_bzrdir/test_bzrdir.py 2020-03-22 21:30:11 +0000
@@ -688,4 +688,4 @@
688 target_branch = repo.controldir.create_branch(name='foo')688 target_branch = repo.controldir.create_branch(name='foo')
689 repo.controldir.set_branch_reference(target_branch)689 repo.controldir.set_branch_reference(target_branch)
690 self.assertEqual({"", 'foo'},690 self.assertEqual({"", 'foo'},
691 set(repo.controldir.get_branches().keys()))691 set(repo.controldir.branch_names()))
692692
=== modified file 'breezy/tests/per_controldir/test_controldir.py'
--- breezy/tests/per_controldir/test_controldir.py 2019-05-29 03:22:34 +0000
+++ breezy/tests/per_controldir/test_controldir.py 2020-03-22 21:30:11 +0000
@@ -199,7 +199,7 @@
199 "control directories without working tree")199 "control directories without working tree")
200 self.assertRaises(errors.NoWorkingTree, dir.open_workingtree)200 self.assertRaises(errors.NoWorkingTree, dir.open_workingtree)
201201
202 def test_clone_bzrdir_repository_under_shared(self):202 def test_clone_controldir_repository_under_shared(self):
203 tree = self.make_branch_and_tree('commit_tree')203 tree = self.make_branch_and_tree('commit_tree')
204 self.build_tree(204 self.build_tree(
205 ['foo'], transport=tree.controldir.transport.clone('..'))205 ['foo'], transport=tree.controldir.transport.clone('..'))
@@ -221,7 +221,7 @@
221 self.assertNotEqual(dir.transport.base, target.transport.base)221 self.assertNotEqual(dir.transport.base, target.transport.base)
222 self.assertRaises(errors.NoRepositoryPresent, target.open_repository)222 self.assertRaises(errors.NoRepositoryPresent, target.open_repository)
223223
224 def test_clone_bzrdir_repository_branch_both_under_shared(self):224 def test_clone_controldir_repository_branch_both_under_shared(self):
225 # Create a shared repository225 # Create a shared repository
226 try:226 try:
227 shared_repo = self.make_repository('shared', shared=True)227 shared_repo = self.make_repository('shared', shared=True)
@@ -249,7 +249,7 @@
249 dir.create_branch()249 dir.create_branch()
250 # Clone 'source' to 'target', also inside the shared repository.250 # Clone 'source' to 'target', also inside the shared repository.
251 target = dir.clone(self.get_url('shared/target'))251 target = dir.clone(self.get_url('shared/target'))
252 # 'source', 'target', and the shared repo all have distinct bzrdirs.252 # 'source', 'target', and the shared repo all have distinct controldirs.
253 self.assertNotEqual(dir.transport.base, target.transport.base)253 self.assertNotEqual(dir.transport.base, target.transport.base)
254 self.assertNotEqual(254 self.assertNotEqual(
255 dir.transport.base, shared_repo.controldir.transport.base)255 dir.transport.base, shared_repo.controldir.transport.base)
@@ -258,7 +258,7 @@
258 # 'commit_tree' branch.258 # 'commit_tree' branch.
259 self.assertTrue(shared_repo.has_revision(rev1))259 self.assertTrue(shared_repo.has_revision(rev1))
260260
261 def test_clone_bzrdir_repository_branch_only_source_under_shared(self):261 def test_clone_controldir_repository_branch_only_source_under_shared(self):
262 try:262 try:
263 shared_repo = self.make_repository('shared', shared=True)263 shared_repo = self.make_repository('shared', shared=True)
264 except errors.IncompatibleFormat:264 except errors.IncompatibleFormat:
@@ -291,7 +291,7 @@
291 self.assertFalse(branch.repository.make_working_trees())291 self.assertFalse(branch.repository.make_working_trees())
292 self.assertTrue(branch.repository.is_shared())292 self.assertTrue(branch.repository.is_shared())
293293
294 def test_clone_bzrdir_repository_revision(self):294 def test_clone_controldir_repository_revision(self):
295 # test for revision limiting, [smoke test, not corner case checks].295 # test for revision limiting, [smoke test, not corner case checks].
296 # make a repository with some revisions,296 # make a repository with some revisions,
297 # and clone it with a revision limit.297 # and clone it with a revision limit.
@@ -310,7 +310,7 @@
310 dir.clone(self.get_url('target'), revision_id=rev2)310 dir.clone(self.get_url('target'), revision_id=rev2)
311 raise TestSkipped('revision limiting not strict yet')311 raise TestSkipped('revision limiting not strict yet')
312312
313 def test_clone_bzrdir_branch_and_repo_fixed_user_id(self):313 def test_clone_controldir_branch_and_repo_fixed_user_id(self):
314 # Bug #430868 is about an email containing '.sig'314 # Bug #430868 is about an email containing '.sig'
315 self.overrideEnv('BRZ_EMAIL', 'murphy@host.sighup.org')315 self.overrideEnv('BRZ_EMAIL', 'murphy@host.sighup.org')
316 tree = self.make_branch_and_tree('commit_tree')316 tree = self.make_branch_and_tree('commit_tree')
@@ -330,7 +330,7 @@
330 tree_repo.get_signature_text(rev1),330 tree_repo.get_signature_text(rev1),
331 target.repository.get_signature_text(rev1))331 target.repository.get_signature_text(rev1))
332332
333 def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):333 def test_clone_controldir_branch_and_repo_into_shared_repo(self):
334 # by default cloning into a shared repo uses the shared repo.334 # by default cloning into a shared repo uses the shared repo.
335 tree = self.make_branch_and_tree('commit_tree')335 tree = self.make_branch_and_tree('commit_tree')
336 self.build_tree(['commit_tree/foo'])336 self.build_tree(['commit_tree/foo'])
@@ -354,7 +354,7 @@
354 self.assertEqual(source.last_revision(),354 self.assertEqual(source.last_revision(),
355 target.open_branch().last_revision())355 target.open_branch().last_revision())
356356
357 def test_clone_bzrdir_branch_revision(self):357 def test_clone_controldir_branch_revision(self):
358 # test for revision limiting, [smoke test, not corner case checks].358 # test for revision limiting, [smoke test, not corner case checks].
359 # make a branch with some revisions,359 # make a branch with some revisions,
360 # and clone it with a revision limit.360 # and clone it with a revision limit.
@@ -371,6 +371,23 @@
371 target = dir.clone(self.get_url('target'), revision_id=rev1)371 target = dir.clone(self.get_url('target'), revision_id=rev1)
372 self.assertEqual(rev1, target.open_branch().last_revision())372 self.assertEqual(rev1, target.open_branch().last_revision())
373373
374 def test_clone_controldir_with_colocated(self):
375 if not self.bzrdir_format.colocated_branches:
376 raise TestNotApplicable(
377 'format does not supported colocated branches')
378 tree = self.make_branch_and_tree('commit_tree')
379 self.build_tree(['commit_tree/foo'])
380 tree.add('foo')
381 rev1 = tree.commit('revision 1')
382 rev2 = tree.commit('revision 2', allow_pointless=True)
383 rev3 = tree.commit('revision 2', allow_pointless=True)
384 dir = tree.branch.controldir
385 colo = dir.create_branch(name='colo')
386 colo.pull(tree.branch, stop_revision=rev1)
387 target = dir.clone(self.get_url('target'), revision_id=rev2)
388 self.assertEqual(rev2, target.open_branch().last_revision())
389 self.assertEqual(rev1, target.open_branch(name='colo').last_revision())
390
374 def test_clone_on_transport_preserves_repo_format(self):391 def test_clone_on_transport_preserves_repo_format(self):
375 if self.bzrdir_format == controldir.format_registry.make_controldir('default'):392 if self.bzrdir_format == controldir.format_registry.make_controldir('default'):
376 format = 'knit'393 format = 'knit'
@@ -381,8 +398,8 @@
381 a_dir = breezy.branch.Branch.open_from_transport(398 a_dir = breezy.branch.Branch.open_from_transport(
382 self.get_transport('source')).controldir399 self.get_transport('source')).controldir
383 target_transport = self.get_transport('target')400 target_transport = self.get_transport('target')
384 target_bzrdir = a_dir.clone_on_transport(target_transport)401 target_controldir = a_dir.clone_on_transport(target_transport)
385 target_repo = target_bzrdir.open_repository()402 target_repo = target_controldir.open_repository()
386 source_branch = breezy.branch.Branch.open(403 source_branch = breezy.branch.Branch.open(
387 self.get_vfs_only_url('source'))404 self.get_vfs_only_url('source'))
388 if isinstance(target_repo, RemoteRepository):405 if isinstance(target_repo, RemoteRepository):
@@ -390,7 +407,7 @@
390 target_repo = target_repo._real_repository407 target_repo = target_repo._real_repository
391 self.assertEqual(target_repo._format, source_branch.repository._format)408 self.assertEqual(target_repo._format, source_branch.repository._format)
392409
393 def test_clone_bzrdir_tree_revision(self):410 def test_clone_controldir_tree_revision(self):
394 # test for revision limiting, [smoke test, not corner case checks].411 # test for revision limiting, [smoke test, not corner case checks].
395 # make a tree with a revision with a last-revision412 # make a tree with a revision with a last-revision
396 # and clone it with a revision limit.413 # and clone it with a revision limit.
@@ -406,7 +423,7 @@
406 self.skipIfNoWorkingTree(target)423 self.skipIfNoWorkingTree(target)
407 self.assertEqual([rev1], target.open_workingtree().get_parent_ids())424 self.assertEqual([rev1], target.open_workingtree().get_parent_ids())
408425
409 def test_clone_bzrdir_into_notrees_repo(self):426 def test_clone_controldir_into_notrees_repo(self):
410 """Cloning into a no-trees repo should not create a working tree"""427 """Cloning into a no-trees repo should not create a working tree"""
411 tree = self.make_branch_and_tree('source')428 tree = self.make_branch_and_tree('source')
412 self.build_tree(['source/foo'])429 self.build_tree(['source/foo'])
@@ -514,12 +531,12 @@
514 """get_branch_reference should not mask NotBranchErrors."""531 """get_branch_reference should not mask NotBranchErrors."""
515 dir = self.make_controldir('source')532 dir = self.make_controldir('source')
516 if dir.has_branch():533 if dir.has_branch():
517 # this format does not support branchless bzrdirs.534 # this format does not support branchless controldirs.
518 raise TestNotApplicable("format does not support "535 raise TestNotApplicable("format does not support "
519 "branchless control directories")536 "branchless control directories")
520 self.assertRaises(errors.NotBranchError, dir.get_branch_reference)537 self.assertRaises(errors.NotBranchError, dir.get_branch_reference)
521538
522 def test_sprout_bzrdir_empty(self):539 def test_sprout_controldir_empty(self):
523 dir = self.make_controldir('source')540 dir = self.make_controldir('source')
524 target = dir.sprout(self.get_url('target'))541 target = dir.sprout(self.get_url('target'))
525 self.assertNotEqual(dir.control_transport.base,542 self.assertNotEqual(dir.control_transport.base,
@@ -529,7 +546,7 @@
529 target.open_branch()546 target.open_branch()
530 self.openWorkingTreeIfLocal(target)547 self.openWorkingTreeIfLocal(target)
531548
532 def test_sprout_bzrdir_empty_under_shared_repo(self):549 def test_sprout_controldir_empty_under_shared_repo(self):
533 # sprouting an empty dir into a repo uses the repo550 # sprouting an empty dir into a repo uses the repo
534 dir = self.make_controldir('source')551 dir = self.make_controldir('source')
535 try:552 try:
@@ -543,13 +560,13 @@
543 try:560 try:
544 target.open_workingtree()561 target.open_workingtree()
545 except errors.NoWorkingTree:562 except errors.NoWorkingTree:
546 # Some bzrdirs can never have working trees.563 # Some controldirs can never have working trees.
547 repo = target.find_repository()564 repo = target.find_repository()
548 self.assertFalse(repo.controldir._format.supports_workingtrees)565 self.assertFalse(repo.controldir._format.supports_workingtrees)
549566
550 def test_sprout_bzrdir_empty_under_shared_repo_force_new(self):567 def test_sprout_controldir_empty_under_shared_repo_force_new(self):
551 # the force_new_repo parameter should force use of a new repo in an empty568 # the force_new_repo parameter should force use of a new repo in an empty
552 # bzrdir's sprout logic569 # controldir's sprout logic
553 dir = self.make_controldir('source')570 dir = self.make_controldir('source')
554 try:571 try:
555 self.make_repository('target', shared=True)572 self.make_repository('target', shared=True)
@@ -561,7 +578,7 @@
561 target.open_branch()578 target.open_branch()
562 self.openWorkingTreeIfLocal(target)579 self.openWorkingTreeIfLocal(target)
563580
564 def test_sprout_bzrdir_with_repository_to_shared(self):581 def test_sprout_controldir_with_repository_to_shared(self):
565 tree = self.make_branch_and_tree('commit_tree')582 tree = self.make_branch_and_tree('commit_tree')
566 self.build_tree(['commit_tree/foo'])583 self.build_tree(['commit_tree/foo'])
567 tree.add('foo')584 tree.add('foo')
@@ -583,7 +600,7 @@
583 target.user_transport.base)600 target.user_transport.base)
584 self.assertTrue(shared_repo.has_revision(rev1))601 self.assertTrue(shared_repo.has_revision(rev1))
585602
586 def test_sprout_bzrdir_repository_branch_both_under_shared(self):603 def test_sprout_controldir_repository_branch_both_under_shared(self):
587 try:604 try:
588 shared_repo = self.make_repository('shared', shared=True)605 shared_repo = self.make_repository('shared', shared=True)
589 except errors.IncompatibleFormat:606 except errors.IncompatibleFormat:
@@ -609,7 +626,7 @@
609 shared_repo.controldir.transport.base)626 shared_repo.controldir.transport.base)
610 self.assertTrue(shared_repo.has_revision(rev1))627 self.assertTrue(shared_repo.has_revision(rev1))
611628
612 def test_sprout_bzrdir_repository_branch_only_source_under_shared(self):629 def test_sprout_controldir_repository_branch_only_source_under_shared(self):
613 try:630 try:
614 shared_repo = self.make_repository('shared', shared=True)631 shared_repo = self.make_repository('shared', shared=True)
615 except errors.IncompatibleFormat:632 except errors.IncompatibleFormat:
@@ -639,7 +656,7 @@
639 dir.transport.base,656 dir.transport.base,
640 shared_repo.controldir.transport.base)657 shared_repo.controldir.transport.base)
641 branch = target.open_branch()658 branch = target.open_branch()
642 # The sprouted bzrdir has a branch, so only revisions referenced by659 # The sprouted controldir has a branch, so only revisions referenced by
643 # that branch are copied, rather than the whole repository. It's an660 # that branch are copied, rather than the whole repository. It's an
644 # empty branch, so none are copied.661 # empty branch, so none are copied.
645 self.assertEqual([], branch.repository.all_revision_ids())662 self.assertEqual([], branch.repository.all_revision_ids())
@@ -647,7 +664,7 @@
647 self.assertTrue(branch.repository.make_working_trees())664 self.assertTrue(branch.repository.make_working_trees())
648 self.assertFalse(branch.repository.is_shared())665 self.assertFalse(branch.repository.is_shared())
649666
650 def test_sprout_bzrdir_repository_under_shared_force_new_repo(self):667 def test_sprout_controldir_repository_under_shared_force_new_repo(self):
651 tree = self.make_branch_and_tree('commit_tree')668 tree = self.make_branch_and_tree('commit_tree')
652 self.build_tree(['commit_tree/foo'])669 self.build_tree(['commit_tree/foo'])
653 tree.add('foo')670 tree.add('foo')
@@ -670,7 +687,7 @@
670 target.control_transport.base)687 target.control_transport.base)
671 self.assertFalse(shared_repo.has_revision(rev1))688 self.assertFalse(shared_repo.has_revision(rev1))
672689
673 def test_sprout_bzrdir_repository_revision(self):690 def test_sprout_controldir_repository_revision(self):
674 # test for revision limiting, [smoke test, not corner case checks].691 # test for revision limiting, [smoke test, not corner case checks].
675 # make a repository with some revisions,692 # make a repository with some revisions,
676 # and sprout it with a revision limit.693 # and sprout it with a revision limit.
@@ -689,7 +706,7 @@
689 self.sproutOrSkip(dir, self.get_url('target'), revision_id=rev2)706 self.sproutOrSkip(dir, self.get_url('target'), revision_id=rev2)
690 raise TestSkipped('revision limiting not strict yet')707 raise TestSkipped('revision limiting not strict yet')
691708
692 def test_sprout_bzrdir_branch_and_repo_shared(self):709 def test_sprout_controldir_branch_and_repo_shared(self):
693 # sprouting a branch with a repo into a shared repo uses the shared710 # sprouting a branch with a repo into a shared repo uses the shared
694 # repo711 # repo
695 tree = self.make_branch_and_tree('commit_tree')712 tree = self.make_branch_and_tree('commit_tree')
@@ -708,7 +725,7 @@
708 dir.sprout(self.get_url('target/child'))725 dir.sprout(self.get_url('target/child'))
709 self.assertTrue(shared_repo.has_revision(rev1))726 self.assertTrue(shared_repo.has_revision(rev1))
710727
711 def test_sprout_bzrdir_branch_and_repo_shared_force_new_repo(self):728 def test_sprout_controldir_branch_and_repo_shared_force_new_repo(self):
712 # sprouting a branch with a repo into a shared repo uses the shared729 # sprouting a branch with a repo into a shared repo uses the shared
713 # repo730 # repo
714 tree = self.make_branch_and_tree('commit_tree')731 tree = self.make_branch_and_tree('commit_tree')
@@ -729,7 +746,7 @@
729 dir.control_transport.base, target.control_transport.base)746 dir.control_transport.base, target.control_transport.base)
730 self.assertFalse(shared_repo.has_revision(rev1))747 self.assertFalse(shared_repo.has_revision(rev1))
731748
732 def test_sprout_bzrdir_branch_reference(self):749 def test_sprout_controldir_branch_reference(self):
733 # sprouting should create a repository if needed and a sprouted branch.750 # sprouting should create a repository if needed and a sprouted branch.
734 referenced_branch = self.make_branch('referenced')751 referenced_branch = self.make_branch('referenced')
735 dir = self.make_controldir('source')752 dir = self.make_controldir('source')
@@ -747,7 +764,7 @@
747 # place764 # place
748 target.open_repository()765 target.open_repository()
749766
750 def test_sprout_bzrdir_branch_reference_shared(self):767 def test_sprout_controldir_branch_reference_shared(self):
751 # sprouting should create a repository if needed and a sprouted branch.768 # sprouting should create a repository if needed and a sprouted branch.
752 referenced_tree = self.make_branch_and_tree('referenced')769 referenced_tree = self.make_branch_and_tree('referenced')
753 rev1 = referenced_tree.commit('1', allow_pointless=True)770 rev1 = referenced_tree.commit('1', allow_pointless=True)
@@ -773,7 +790,7 @@
773 # and we want revision '1' in the shared repo790 # and we want revision '1' in the shared repo
774 self.assertTrue(shared_repo.has_revision(rev1))791 self.assertTrue(shared_repo.has_revision(rev1))
775792
776 def test_sprout_bzrdir_branch_reference_shared_force_new_repo(self):793 def test_sprout_controldir_branch_reference_shared_force_new_repo(self):
777 # sprouting should create a repository if needed and a sprouted branch.794 # sprouting should create a repository if needed and a sprouted branch.
778 referenced_tree = self.make_branch_and_tree('referenced')795 referenced_tree = self.make_branch_and_tree('referenced')
779 rev1 = referenced_tree.commit('1', allow_pointless=True)796 rev1 = referenced_tree.commit('1', allow_pointless=True)
@@ -799,7 +816,7 @@
799 # but not the shared one816 # but not the shared one
800 self.assertFalse(shared_repo.has_revision(rev1))817 self.assertFalse(shared_repo.has_revision(rev1))
801818
802 def test_sprout_bzrdir_branch_revision(self):819 def test_sprout_controldir_branch_revision(self):
803 # test for revision limiting, [smoke test, not corner case checks].820 # test for revision limiting, [smoke test, not corner case checks].
804 # make a repository with some revisions,821 # make a repository with some revisions,
805 # and sprout it with a revision limit.822 # and sprout it with a revision limit.
@@ -816,7 +833,7 @@
816 target = dir.sprout(self.get_url('target'), revision_id=rev1)833 target = dir.sprout(self.get_url('target'), revision_id=rev1)
817 self.assertEqual(rev1, target.open_branch().last_revision())834 self.assertEqual(rev1, target.open_branch().last_revision())
818835
819 def test_sprout_bzrdir_branch_with_tags(self):836 def test_sprout_controldir_branch_with_tags(self):
820 # when sprouting a branch all revisions named in the tags are copied837 # when sprouting a branch all revisions named in the tags are copied
821 # too.838 # too.
822 builder = self.make_branch_builder('source')839 builder = self.make_branch_builder('source')
@@ -835,7 +852,7 @@
835 self.assertEqual(rev2, new_branch.tags.lookup_tag('tag-a'))852 self.assertEqual(rev2, new_branch.tags.lookup_tag('tag-a'))
836 new_branch.repository.get_revision(rev2)853 new_branch.repository.get_revision(rev2)
837854
838 def test_sprout_bzrdir_branch_with_absent_tag(self):855 def test_sprout_controldir_branch_with_absent_tag(self):
839 # tags referencing absent revisions are copied (and those absent856 # tags referencing absent revisions are copied (and those absent
840 # revisions do not prevent the sprout.)857 # revisions do not prevent the sprout.)
841 builder = self.make_branch_builder('source')858 builder = self.make_branch_builder('source')
@@ -855,7 +872,7 @@
855 new_branch = target.open_branch()872 new_branch = target.open_branch()
856 self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a'))873 self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a'))
857874
858 def test_sprout_bzrdir_passing_source_branch_with_absent_tag(self):875 def test_sprout_controldir_passing_source_branch_with_absent_tag(self):
859 # tags referencing absent revisions are copied (and those absent876 # tags referencing absent revisions are copied (and those absent
860 # revisions do not prevent the sprout.)877 # revisions do not prevent the sprout.)
861 builder = self.make_branch_builder('source')878 builder = self.make_branch_builder('source')
@@ -875,9 +892,9 @@
875 new_branch = target.open_branch()892 new_branch = target.open_branch()
876 self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a'))893 self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a'))
877894
878 def test_sprout_bzrdir_passing_rev_not_source_branch_copies_tags(self):895 def test_sprout_controldir_passing_rev_not_source_branch_copies_tags(self):
879 # dir.sprout(..., revision_id=b'rev1') copies rev1, and all the tags of896 # dir.sprout(..., revision_id=b'rev1') copies rev1, and all the tags of
880 # the branch at that bzrdir, the ancestry of all of those, but no other897 # the branch at that controldir, the ancestry of all of those, but no other
881 # revs (not even the tip of the source branch).898 # revs (not even the tip of the source branch).
882 builder = self.make_branch_builder('source')899 builder = self.make_branch_builder('source')
883 base_rev = builder.build_commit(message="Base")900 base_rev = builder.build_commit(message="Base")
@@ -927,7 +944,7 @@
927 sorted([base_rev, rev_b1, rev_b2, rev_c1, rev_c2]),944 sorted([base_rev, rev_b1, rev_b2, rev_c1, rev_c2]),
928 sorted(new_branch.repository.all_revision_ids()))945 sorted(new_branch.repository.all_revision_ids()))
929946
930 def test_sprout_bzrdir_tree_branch_reference(self):947 def test_sprout_controldir_tree_branch_reference(self):
931 # sprouting should create a repository if needed and a sprouted branch.948 # sprouting should create a repository if needed and a sprouted branch.
932 # the tree state should not be copied.949 # the tree state should not be copied.
933 referenced_branch = self.make_branch('referencced')950 referenced_branch = self.make_branch('referencced')
@@ -952,7 +969,7 @@
952 result_tree = target.open_workingtree()969 result_tree = target.open_workingtree()
953 self.assertFalse(result_tree.has_filename('subdir'))970 self.assertFalse(result_tree.has_filename('subdir'))
954971
955 def test_sprout_bzrdir_tree_branch_reference_revision(self):972 def test_sprout_controldir_tree_branch_reference_revision(self):
956 # sprouting should create a repository if needed and a sprouted branch.973 # sprouting should create a repository if needed and a sprouted branch.
957 # the tree state should not be copied but the revision changed,974 # the tree state should not be copied but the revision changed,
958 # and the likewise the new branch should be truncated too975 # and the likewise the new branch should be truncated too
@@ -982,7 +999,7 @@
982 self.assertEqual([rev1], target.open_workingtree().get_parent_ids())999 self.assertEqual([rev1], target.open_workingtree().get_parent_ids())
983 self.assertEqual(rev1, target.open_branch().last_revision())1000 self.assertEqual(rev1, target.open_branch().last_revision())
9841001
985 def test_sprout_bzrdir_tree_revision(self):1002 def test_sprout_controldir_tree_revision(self):
986 # test for revision limiting, [smoke test, not corner case checks].1003 # test for revision limiting, [smoke test, not corner case checks].
987 # make a tree with a revision with a last-revision1004 # make a tree with a revision with a last-revision
988 # and sprout it with a revision limit.1005 # and sprout it with a revision limit.
@@ -1034,13 +1051,13 @@
1034 rev3 = builder.build_commit(message='Rev 3.')1051 rev3 = builder.build_commit(message='Rev 3.')
1035 builder.finish_series()1052 builder.finish_series()
1036 stack_on = builder.get_branch()1053 stack_on = builder.get_branch()
1037 # Make a bzrdir with a default stacking policy to stack on that branch.1054 # Make a controldir with a default stacking policy to stack on that branch.
1038 config = self.make_controldir('policy-dir').get_config()1055 config = self.make_controldir('policy-dir').get_config()
1039 try:1056 try:
1040 config.set_default_stack_on(self.get_url('stack-on'))1057 config.set_default_stack_on(self.get_url('stack-on'))
1041 except errors.BzrError:1058 except errors.BzrError:
1042 raise TestNotApplicable('Only relevant for stackable formats.')1059 raise TestNotApplicable('Only relevant for stackable formats.')
1043 # Sprout the stacked-on branch into the bzrdir.1060 # Sprout the stacked-on branch into the controldir.
1044 sprouted = stack_on.controldir.sprout(1061 sprouted = stack_on.controldir.sprout(
1045 self.get_url('policy-dir/sprouted'), revision_id=rev3)1062 self.get_url('policy-dir/sprouted'), revision_id=rev3)
1046 # Not all revisions are copied into the sprouted repository.1063 # Not all revisions are copied into the sprouted repository.
@@ -1288,6 +1305,11 @@
1288 repo.controldir.create_branch()1305 repo.controldir.create_branch()
1289 self.assertEqual([""], list(repo.controldir.get_branches()))1306 self.assertEqual([""], list(repo.controldir.get_branches()))
12901307
1308 def test_branch_names(self):
1309 repo = self.make_repository('branch-1')
1310 repo.controldir.create_branch()
1311 self.assertEqual([""], repo.controldir.branch_names())
1312
1291 def test_create_repository(self):1313 def test_create_repository(self):
1292 # a bzrdir can construct a repository for itself.1314 # a bzrdir can construct a repository for itself.
1293 if not self.bzrdir_format.is_initializable():1315 if not self.bzrdir_format.is_initializable():
12941316
=== modified file 'breezy/tests/per_controldir_colo/test_supported.py'
--- breezy/tests/per_controldir_colo/test_supported.py 2019-04-13 21:37:04 +0000
+++ breezy/tests/per_controldir_colo/test_supported.py 2020-03-22 21:30:11 +0000
@@ -184,6 +184,11 @@
184 self.assertEqual(target_branch.base,184 self.assertEqual(target_branch.base,
185 repo.controldir.get_branches()['foo'].base)185 repo.controldir.get_branches()['foo'].base)
186186
187 def test_branch_names(self):
188 repo = self.make_repository('branch-1')
189 target_branch = self.create_branch(repo.controldir, name='foo')
190 self.assertIn('foo', repo.controldir.branch_names())
191
187 def test_branch_name_with_slash(self):192 def test_branch_name_with_slash(self):
188 repo = self.make_repository('branch-1')193 repo = self.make_repository('branch-1')
189 try:194 try:
190195
=== modified file 'breezy/tests/test_smart.py'
--- breezy/tests/test_smart.py 2020-01-18 02:42:17 +0000
+++ breezy/tests/test_smart.py 2020-03-22 21:30:11 +0000
@@ -485,6 +485,19 @@
485 (b"success", ), local_result)485 (b"success", ), local_result)
486 self.assertEqual(expected, request.execute(b''))486 self.assertEqual(expected, request.execute(b''))
487487
488 def test_ref(self):
489 backing = self.get_transport()
490 dir = self.make_controldir('foo')
491 b = self.make_branch('bar')
492 dir.set_branch_reference(b)
493 request_class = smart_dir.SmartServerBzrDirRequestGetBranches
494 request = request_class(backing)
495 local_result = bencode.bencode(
496 {b"": (b"ref", b'../bar/')})
497 expected = smart_req.SuccessfulSmartServerResponse(
498 (b"success", ), local_result)
499 self.assertEqual(expected, request.execute(b'foo'))
500
488 def test_empty(self):501 def test_empty(self):
489 backing = self.get_transport()502 backing = self.get_transport()
490 self.make_controldir('.')503 self.make_controldir('.')
491504
=== modified file 'doc/en/release-notes/brz-3.1.txt'
--- doc/en/release-notes/brz-3.1.txt 2020-03-21 20:56:33 +0000
+++ doc/en/release-notes/brz-3.1.txt 2020-03-22 21:30:11 +0000
@@ -73,6 +73,13 @@
73 * When pushing to Git repositories, symrefs are now followed.73 * When pushing to Git repositories, symrefs are now followed.
74 (Jelmer Vernooij, #1800393)74 (Jelmer Vernooij, #1800393)
7575
76 * New ``brz clone`` command, which clones everything under
77 a control directory. I.e. all colocated branches, like
78 ``git clone``. (Jelmer Vernooij, #831939)
79
80 * ``brz sprout`` is now an alias for ``brz branch``.
81 (Jelmer Vernooij)
82
76Improvements83Improvements
77************84************
7885

Subscribers

People subscribed via source and target branches