Rev 4302: (abentley) store tree-references in a new branch format. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Apr 23 21:47:35 BST 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 4302
revision-id: pqm at pqm.ubuntu.com-20090423204730-kcbq9na0n3zs2y3l
parent: pqm at pqm.ubuntu.com-20090423015537-xfgqsbjj9ctpcd3o
parent: aaron at aaronbentley.com-20090423160228-gxb9fjel30ihjqm2
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-04-23 21:47:30 +0100
message:
(abentley) store tree-references in a new branch format.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
bzrlib/tests/test_upgrade.py test_upgrade.py-20051004040251-555fe1d2bae1bc71
------------------------------------------------------------
revno: 4273.1.15
revision-id: aaron at aaronbentley.com-20090423160228-gxb9fjel30ihjqm2
parent: aaron at aaronbentley.com-20090422200825-nhpatpznn1rbfz39
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Thu 2009-04-23 12:02:28 -0400
message:
Add reference_info caching.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
------------------------------------------------------------
revno: 4273.1.14
revision-id: aaron at aaronbentley.com-20090422200825-nhpatpznn1rbfz39
parent: aaron at aaronbentley.com-20090420205851-r6s96npwkuto0n0q
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Wed 2009-04-22 16:08:25 -0400
message:
Restore disabled test
modified:
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.13
revision-id: aaron at aaronbentley.com-20090420205851-r6s96npwkuto0n0q
parent: aaron at aaronbentley.com-20090414152901-r2i7jgu7gisu8hmy
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Mon 2009-04-20 16:58:51 -0400
message:
Implement upgrade from branch format 7 to 8.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/test_upgrade.py test_upgrade.py-20051004040251-555fe1d2bae1bc71
------------------------------------------------------------
revno: 4273.1.12
revision-id: aaron at aaronbentley.com-20090414152901-r2i7jgu7gisu8hmy
parent: aaron at aaronbentley.com-20090414152021-ggbp1i96z3w1jtpn
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 11:29:01 -0400
message:
Don't create reference files for older formats.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/test_branch.py test_branch.py-20060116013032-97819aa07b8ab3b5
------------------------------------------------------------
revno: 4273.1.11
revision-id: aaron at aaronbentley.com-20090414152021-ggbp1i96z3w1jtpn
parent: aaron at aaronbentley.com-20090414150646-442azwp8fhxi59b5
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 11:20:21 -0400
message:
Clean up naming and docstrings
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
------------------------------------------------------------
revno: 4273.1.10
revision-id: aaron at aaronbentley.com-20090414150646-442azwp8fhxi59b5
parent: aaron at aaronbentley.com-20090414150246-6xfd3bwwf2m8v4px
parent: pqm at pqm.ubuntu.com-20090414031543-gqbs23oebd68p7h7
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 11:06:46 -0400
message:
Merge bzr.dev into branch-subtree-locations.
added:
bzrlib/tests/blackbox/test_dpush.py test_dpush.py-20090108125928-st1td6le59g0vyv2-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/_btree_serializer_c.pyx _parse_btree_c.pyx-20080703034413-3q25bklkenti3p8p-2
bzrlib/branchbuilder.py branchbuilder.py-20070427022007-zlxpqz2lannhk6y8-1
bzrlib/btree_index.py index.py-20080624222253-p0x5f92uyh5hw734-7
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/fetch.py fetch.py-20050818234941-26fea6105696365d
bzrlib/filters/__init__.py __init__.py-20080416080515-mkxl29amuwrf6uir-2
bzrlib/filters/eol.py eol.py-20090327060429-todzdjmqt3bpv5r8-1
bzrlib/foreign.py foreign.py-20081112170002-olsxmandkk8qyfuq-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
bzrlib/plugins/launchpad/account.py account.py-20071011033320-50y6vfftywf4yllw-1
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repofmt/groupcompress_repo.py repofmt.py-20080715094215-wp1qfvoo7093c8qr-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/revision.py revision.py-20050309040759-e77802c08f3999d5
bzrlib/smtp_connection.py smtp_connection.py-20070618204456-nu6wag1ste4biuk2-1
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
bzrlib/tests/blackbox/test_ls.py test_ls.py-20060712232047-0jraqpecwngee12y-1
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
bzrlib/tests/test_config.py testconfig.py-20051011041908-742d0c15d8d8c8eb
bzrlib/tests/test_foreign.py test_foreign.py-20081125004048-ywb901edgp9lluxo-1
bzrlib/tests/test_ftp_transport.py test_aftp_transport.-20060823221619-98mwjzxtwtkt527k-1
bzrlib/tests/test_http.py testhttp.py-20051018020158-b2eef6e867c514d9
bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_revision.py testrevision.py-20050804210559-46f5e1eb67b01289
bzrlib/tests/test_selftest.py test_selftest.py-20051202044319-c110a115d8c0456a
bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
bzrlib/tests/test_workingtree_4.py test_workingtree_4.p-20070223025758-531n3tznl3zacv2o-1
bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
bzrlib/tests/tree_implementations/test_get_symlink_target.py test_get_symlink_tar-20070225165554-ickod3w3t7u0zzqh-1
bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
bzrlib/tests/tree_implementations/test_path_content_summary.py test_path_content_su-20070904100855-3vrwedz6akn34kl5-1
bzrlib/tests/tree_implementations/test_test_trees.py test_tree_trees.py-20060720091921-3nwi5h21lf06vf5p-1
bzrlib/tests/tree_implementations/test_walkdirs.py test_walkdirs.py-20060729160421-gmjnkotqgxdh98ce-1
bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
bzrlib/transport/ssh.py ssh.py-20060824042150-0s9787kng6zv1nwq-1
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 4273.1.9
revision-id: aaron at aaronbentley.com-20090414150246-6xfd3bwwf2m8v4px
parent: aaron at aaronbentley.com-20090414145322-2z6fjycf3j17hjbm
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 11:02:46 -0400
message:
Cleanup
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
------------------------------------------------------------
revno: 4273.1.8
revision-id: aaron at aaronbentley.com-20090414145322-2z6fjycf3j17hjbm
parent: aaron at aaronbentley.com-20090414135330-iowjjmz2g98nhcgb
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 10:53:22 -0400
message:
Handle references in push, pull, merge.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.7
revision-id: aaron at aaronbentley.com-20090414135330-iowjjmz2g98nhcgb
parent: aaron at aaronbentley.com-20090414132810-byuai43ht3t4htix
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 09:53:30 -0400
message:
Make update_references do a merge.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.6
revision-id: aaron at aaronbentley.com-20090414132810-byuai43ht3t4htix
parent: aaron at aaronbentley.com-20090409153149-p04wki1uuwrm2hsb
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Tue 2009-04-14 09:28:10 -0400
message:
Ensure references are rebased.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.5
revision-id: aaron at aaronbentley.com-20090409153149-p04wki1uuwrm2hsb
parent: aaron at aaronbentley.com-20090409143954-6beh111is9zesvqb
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Thu 2009-04-09 11:31:49 -0400
message:
Ensure references are propagated by sprout/clone.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.4
revision-id: aaron at aaronbentley.com-20090409143954-6beh111is9zesvqb
parent: aaron at aaronbentley.com-20090409134035-yzrbw9l6qjs7mniu
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Thu 2009-04-09 10:39:54 -0400
message:
Relative reference locations are branch-relative.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.3
revision-id: aaron at aaronbentley.com-20090409134035-yzrbw9l6qjs7mniu
parent: aaron at aaronbentley.com-20090408210701-l1sjtkomuy817ej3
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Thu 2009-04-09 09:40:35 -0400
message:
Use branch-relative paths to references.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.2
revision-id: aaron at aaronbentley.com-20090408210701-l1sjtkomuy817ej3
parent: aaron at aaronbentley.com-20090408204627-m4gbzrc255mhtjtu
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Wed 2009-04-08 17:07:01 -0400
message:
Use reference_info to get reference_parent.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
------------------------------------------------------------
revno: 4273.1.1
revision-id: aaron at aaronbentley.com-20090408204627-m4gbzrc255mhtjtu
parent: pqm at pqm.ubuntu.com-20090408143103-36oiu9zhl4r91hdq
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: branch-subtree-locations
timestamp: Wed 2009-04-08 16:46:27 -0400
message:
Implement branch format for tree references.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2009-04-15 07:30:34 +0000
+++ b/bzrlib/branch.py 2009-04-23 20:47:30 +0000
@@ -15,6 +15,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+from cStringIO import StringIO
import sys
from bzrlib.lazy_import import lazy_import
@@ -30,6 +31,7 @@
lockable_files,
repository,
revision as _mod_revision,
+ rio,
symbol_versioning,
transport,
tsort,
@@ -500,6 +502,14 @@
"""
raise errors.UpgradeRequired(self.base)
+ def set_reference_info(self, file_id, tree_path, branch_location):
+ """Set the branch location to use for a tree reference."""
+ raise errors.UnsupportedOperation(self.set_reference_info, self)
+
+ def get_reference_info(self, file_id):
+ """Get the tree_path and branch_location for a tree reference."""
+ raise errors.UnsupportedOperation(self.get_reference_info, self)
+
@needs_write_lock
def fetch(self, from_branch, last_revision=None, pb=None):
"""Copy revisions from from_branch into this branch.
@@ -1070,6 +1080,7 @@
revision_id: if not None, the revision history in the new branch will
be truncated to end with revision_id.
"""
+ self.update_references(destination)
self._synchronize_history(destination, revision_id)
try:
parent = self.get_parent()
@@ -1081,6 +1092,23 @@
if self._push_should_merge_tags():
self.tags.merge_to(destination.tags)
+ def update_references(self, target):
+ if not getattr(self._format, 'supports_reference_locations', False):
+ return
+ reference_dict = self._get_all_reference_info()
+ if len(reference_dict) == 0:
+ return
+ old_base = self.base
+ new_base = target.base
+ target_reference_dict = target._get_all_reference_info()
+ for file_id, (tree_path, branch_location) in (
+ reference_dict.items()):
+ branch_location = urlutils.rebase_url(branch_location,
+ old_base, new_base)
+ target_reference_dict.setdefault(
+ file_id, (tree_path, branch_location))
+ target._set_all_reference_info(target_reference_dict)
+
@needs_read_lock
def check(self):
"""Check consistency of the branch.
@@ -1205,14 +1233,15 @@
reconciler.reconcile()
return reconciler
- def reference_parent(self, file_id, path):
+ def reference_parent(self, file_id, path, possible_transports=None):
"""Return the parent branch for a tree-reference file_id
:param file_id: The file_id of the tree reference
:param path: The path of the file_id in the tree
:return: A branch associated with the file_id
"""
# FIXME should provide multiple branches, based on config
- return Branch.open(self.bzrdir.root_transport.clone(path).base)
+ return Branch.open(self.bzrdir.root_transport.clone(path).base,
+ possible_transports=possible_transports)
def supports_tags(self):
return self._format.supports_tags()
@@ -1716,7 +1745,45 @@
-class BzrBranchFormat7(BranchFormatMetadir):
+class BzrBranchFormat8(BranchFormatMetadir):
+ """Metadir format supporting storing locations of subtree branches."""
+
+ def _branch_class(self):
+ return BzrBranch8
+
+ def get_format_string(self):
+ """See BranchFormat.get_format_string()."""
+ return "Bazaar Branch Format 8 (needs bzr 1.15)\n"
+
+ def get_format_description(self):
+ """See BranchFormat.get_format_description()."""
+ return "Branch format 8"
+
+ def initialize(self, a_bzrdir):
+ """Create a branch of this format in a_bzrdir."""
+ utf8_files = [('last-revision', '0 null:\n'),
+ ('branch.conf', ''),
+ ('tags', ''),
+ ('references', '')
+ ]
+ return self._initialize_helper(a_bzrdir, utf8_files)
+
+ def __init__(self):
+ super(BzrBranchFormat8, self).__init__()
+ self._matchingbzrdir.repository_format = \
+ RepositoryFormatKnitPack5RichRoot()
+
+ def make_tags(self, branch):
+ """See bzrlib.branch.BranchFormat.make_tags()."""
+ return BasicTags(branch)
+
+ def supports_stacking(self):
+ return True
+
+ supports_reference_locations = True
+
+
+class BzrBranchFormat7(BzrBranchFormat8):
"""Branch format with last-revision, tags, and a stacked location pointer.
The stacked location pointer is passed down to the repository and requires
@@ -1725,6 +1792,14 @@
This format was introduced in bzr 1.6.
"""
+ def initialize(self, a_bzrdir):
+ """Create a branch of this format in a_bzrdir."""
+ utf8_files = [('last-revision', '0 null:\n'),
+ ('branch.conf', ''),
+ ('tags', ''),
+ ]
+ return self._initialize_helper(a_bzrdir, utf8_files)
+
def _branch_class(self):
return BzrBranch7
@@ -1736,25 +1811,7 @@
"""See BranchFormat.get_format_description()."""
return "Branch format 7"
- def initialize(self, a_bzrdir):
- """Create a branch of this format in a_bzrdir."""
- utf8_files = [('last-revision', '0 null:\n'),
- ('branch.conf', ''),
- ('tags', ''),
- ]
- return self._initialize_helper(a_bzrdir, utf8_files)
-
- def __init__(self):
- super(BzrBranchFormat7, self).__init__()
- self._matchingbzrdir.repository_format = \
- RepositoryFormatKnitPack5RichRoot()
-
- def make_tags(self, branch):
- """See bzrlib.branch.BranchFormat.make_tags()."""
- return BasicTags(branch)
-
- def supports_stacking(self):
- return True
+ supports_reference_locations = False
class BranchReferenceFormat(BranchFormat):
@@ -1867,10 +1924,12 @@
__format5 = BzrBranchFormat5()
__format6 = BzrBranchFormat6()
__format7 = BzrBranchFormat7()
+__format8 = BzrBranchFormat8()
BranchFormat.register_format(__format5)
BranchFormat.register_format(BranchReferenceFormat())
BranchFormat.register_format(__format6)
BranchFormat.register_format(__format7)
+BranchFormat.register_format(__format8)
BranchFormat.set_default_format(__format6)
_legacy_formats = [BzrBranchFormat4(),
]
@@ -2119,6 +2178,7 @@
try:
# We assume that during 'pull' the local repository is closer than
# the remote one.
+ source.update_references(self)
graph = self.repository.get_graph(source.repository)
result.old_revno, result.old_revid = self.last_revision_info()
self.update_revisions(source, stop_revision, overwrite=overwrite,
@@ -2221,6 +2281,7 @@
result.source_branch = self
result.target_branch = target
result.old_revno, result.old_revid = target.last_revision_info()
+ self.update_references(target)
if result.old_revid != self.last_revision():
# We assume that during 'push' this repository is closer than
# the target.
@@ -2376,8 +2437,8 @@
return None
-class BzrBranch7(BzrBranch5):
- """A branch with support for a fallback repository."""
+class BzrBranch8(BzrBranch5):
+ """A branch that stores tree-reference locations."""
def _open_hook(self):
if self._ignore_fallbacks:
@@ -2399,14 +2460,16 @@
def __init__(self, *args, **kwargs):
self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)
- super(BzrBranch7, self).__init__(*args, **kwargs)
+ super(BzrBranch8, self).__init__(*args, **kwargs)
self._last_revision_info_cache = None
self._partial_revision_history_cache = []
+ self._reference_info = None
def _clear_cached_state(self):
- super(BzrBranch7, self)._clear_cached_state()
+ super(BzrBranch8, self)._clear_cached_state()
self._last_revision_info_cache = None
self._partial_revision_history_cache = []
+ self._reference_info = None
def _last_revision_info(self):
revision_string = self._transport.get_bytes('last-revision')
@@ -2522,6 +2585,81 @@
"""Set the parent branch"""
return self._get_config_location('parent_location')
+ @needs_write_lock
+ def _set_all_reference_info(self, info_dict):
+ """Replace all reference info stored in a branch.
+
+ :param info_dict: A dict of {file_id: (tree_path, branch_location)}
+ """
+ s = StringIO()
+ writer = rio.RioWriter(s)
+ for key, (tree_path, branch_location) in info_dict.iteritems():
+ stanza = rio.Stanza(file_id=key, tree_path=tree_path,
+ branch_location=branch_location)
+ writer.write_stanza(stanza)
+ self._transport.put_bytes('references', s.getvalue())
+ self._reference_info = info_dict
+
+ @needs_read_lock
+ def _get_all_reference_info(self):
+ """Return all the reference info stored in a branch.
+
+ :return: A dict of {file_id: (tree_path, branch_location)}
+ """
+ if self._reference_info is not None:
+ return self._reference_info
+ rio_file = self._transport.get('references')
+ try:
+ stanzas = rio.read_stanzas(rio_file)
+ info_dict = dict((s['file_id'], (s['tree_path'],
+ s['branch_location'])) for s in stanzas)
+ finally:
+ rio_file.close()
+ self._reference_info = info_dict
+ return info_dict
+
+ def set_reference_info(self, file_id, tree_path, branch_location):
+ """Set the branch location to use for a tree reference.
+
+ :param file_id: The file-id of the tree reference.
+ :param tree_path: The path of the tree reference in the tree.
+ :param branch_location: The location of the branch to retrieve tree
+ references from.
+ """
+ info_dict = self._get_all_reference_info()
+ info_dict[file_id] = (tree_path, branch_location)
+ if None in (tree_path, branch_location):
+ if tree_path is not None:
+ raise ValueError('tree_path must be None when branch_location'
+ ' is None.')
+ if branch_location is not None:
+ raise ValueError('branch_location must be None when tree_path'
+ ' is None.')
+ del info_dict[file_id]
+ self._set_all_reference_info(info_dict)
+
+ def get_reference_info(self, file_id):
+ """Get the tree_path and branch_location for a tree reference.
+
+ :return: a tuple of (tree_path, branch_location)
+ """
+ return self._get_all_reference_info().get(file_id, (None, None))
+
+ def reference_parent(self, file_id, path, possible_transports=None):
+ """Return the parent branch for a tree-reference file_id.
+
+ :param file_id: The file_id of the tree reference
+ :param path: The path of the file_id in the tree
+ :return: A branch associated with the file_id
+ """
+ branch_location = self.get_reference_info(file_id)[1]
+ if branch_location is None:
+ return Branch.reference_parent(self, file_id, path,
+ possible_transports)
+ branch_location = urlutils.join(self.base, branch_location)
+ return Branch.open(branch_location,
+ possible_transports=possible_transports)
+
def set_push_location(self, location):
"""See Branch.set_push_location."""
self._set_config_location('push_location', location)
@@ -2625,6 +2763,20 @@
return self.revno() - index
+class BzrBranch7(BzrBranch8):
+ """A branch with support for a fallback repository."""
+
+ def set_reference_info(self, file_id, tree_path, branch_location):
+ Branch.set_reference_info(self, file_id, tree_path, branch_location)
+
+ def get_reference_info(self, file_id):
+ Branch.get_reference_info(self, file_id)
+
+ def reference_parent(self, file_id, path, possible_transports=None):
+ return Branch.reference_parent(self, file_id, path,
+ possible_transports)
+
+
class BzrBranch6(BzrBranch7):
"""See BzrBranchFormat6 for the capabilities of this branch.
@@ -2771,6 +2923,15 @@
branch._transport.put_bytes('format', format.get_format_string())
+class Converter7to8(object):
+ """Perform an in-place upgrade of format 6 to format 7"""
+
+ def convert(self, branch):
+ format = BzrBranchFormat8()
+ branch._transport.put_bytes('references', '')
+ # update target format
+ branch._transport.put_bytes('format', format.get_format_string())
+
def _run_with_write_locked_target(target, callable, *args, **kwargs):
"""Run ``callable(*args, **kwargs)``, write-locking target for the
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2009-04-14 02:35:07 +0000
+++ b/bzrlib/bzrdir.py 2009-04-23 20:47:30 +0000
@@ -2788,11 +2788,16 @@
while old != new:
if (old == _mod_branch.BzrBranchFormat5 and
new in (_mod_branch.BzrBranchFormat6,
- _mod_branch.BzrBranchFormat7)):
+ _mod_branch.BzrBranchFormat7,
+ _mod_branch.BzrBranchFormat8)):
branch_converter = _mod_branch.Converter5to6()
elif (old == _mod_branch.BzrBranchFormat6 and
- new == _mod_branch.BzrBranchFormat7):
+ new in (_mod_branch.BzrBranchFormat7,
+ _mod_branch.BzrBranchFormat8)):
branch_converter = _mod_branch.Converter6to7()
+ elif (old == _mod_branch.BzrBranchFormat7 and
+ new is _mod_branch.BzrBranchFormat8):
+ branch_converter = _mod_branch.Converter7to8()
else:
raise errors.BadConversionTarget("No converter", new)
branch_converter.convert(branch)
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2009-04-04 02:50:01 +0000
+++ b/bzrlib/merge.py 2009-04-14 15:02:46 +0000
@@ -462,6 +462,8 @@
**kwargs)
def _do_merge_to(self, merge):
+ if self.other_branch is not None:
+ self.other_branch.update_references(self.this_branch)
merge.do_merge()
if self.recurse == 'down':
for relpath, file_id in self.this_tree.iter_references():
=== modified file 'bzrlib/tests/branch_implementations/test_branch.py'
--- a/bzrlib/tests/branch_implementations/test_branch.py 2009-03-24 06:40:26 +0000
+++ b/bzrlib/tests/branch_implementations/test_branch.py 2009-04-22 20:08:25 +0000
@@ -24,6 +24,7 @@
bzrdir,
errors,
gpg,
+ merge,
urlutils,
transactions,
remote,
@@ -769,8 +770,202 @@
self.get_transport('').rename('fallback', 'moved')
reopened = stacked.bzrdir.open_branch(ignore_fallbacks=True)
self.assertEqual([], reopened.repository._fallback_repositories)
-
+
def test_fallbacks_are_opened(self):
stacked = self.make_branch_with_fallback()
reopened = stacked.bzrdir.open_branch(ignore_fallbacks=False)
self.assertLength(1, reopened.repository._fallback_repositories)
+
+
+class TestReferenceLocation(TestCaseWithBranch):
+
+ def test_reference_parent(self):
+ tree = self.make_branch_and_tree('tree')
+ subtree = self.make_branch_and_tree('tree/subtree')
+ subtree.set_root_id('subtree-id')
+ try:
+ tree.add_reference(subtree)
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Tree cannot hold references.')
+ reference_parent = tree.branch.reference_parent('subtree-id',
+ 'subtree')
+ self.assertEqual(subtree.branch.base, reference_parent.base)
+
+ def test_reference_parent_accepts_possible_transports(self):
+ tree = self.make_branch_and_tree('tree')
+ subtree = self.make_branch_and_tree('tree/subtree')
+ subtree.set_root_id('subtree-id')
+ try:
+ tree.add_reference(subtree)
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Tree cannot hold references.')
+ reference_parent = tree.branch.reference_parent('subtree-id',
+ 'subtree', possible_transports=[subtree.bzrdir.root_transport])
+
+ def test_get_reference_info(self):
+ branch = self.make_branch('branch')
+ try:
+ path, loc = branch.get_reference_info('file-id')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ self.assertIs(None, path)
+ self.assertIs(None, loc)
+
+ def test_set_reference_info(self):
+ branch = self.make_branch('branch')
+ try:
+ branch.set_reference_info('file-id', 'path/to/location',
+ 'path/to/file')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+
+ def test_set_get_reference_info(self):
+ branch = self.make_branch('branch')
+ try:
+ branch.set_reference_info('file-id', 'path/to/file',
+ 'path/to/location')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ # Create a new instance to ensure storage is permanent
+ branch = Branch.open('branch')
+ tree_path, branch_location = branch.get_reference_info('file-id')
+ self.assertEqual('path/to/location', branch_location)
+
+ def test_set_null_reference_info(self):
+ branch = self.make_branch('branch')
+ try:
+ branch.set_reference_info('file-id', 'path/to/file',
+ 'path/to/location')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ branch.set_reference_info('file-id', None, None)
+ tree_path, branch_location = branch.get_reference_info('file-id')
+ self.assertIs(None, tree_path)
+ self.assertIs(None, branch_location)
+
+ def test_set_null_reference_info_when_null(self):
+ branch = self.make_branch('branch')
+ try:
+ tree_path, branch_location = branch.get_reference_info('file-id')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ self.assertIs(None, tree_path)
+ self.assertIs(None, branch_location)
+ branch.set_reference_info('file-id', None, None)
+
+ def test_set_null_requires_two_nones(self):
+ branch = self.make_branch('branch')
+ try:
+ e = self.assertRaises(ValueError, branch.set_reference_info,
+ 'file-id', 'path', None)
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ self.assertEqual('tree_path must be None when branch_location is'
+ ' None.', str(e))
+ e = self.assertRaises(ValueError, branch.set_reference_info,
+ 'file-id', None, 'location')
+ self.assertEqual('branch_location must be None when tree_path is'
+ ' None.', str(e))
+
+ def make_branch_with_reference(self, location, reference_location,
+ file_id='file-id'):
+ branch = self.make_branch(location)
+ try:
+ branch.set_reference_info(file_id, 'path/to/file',
+ reference_location)
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ return branch
+
+ def test_reference_parent_from_reference_info_(self):
+ referenced_branch = self.make_branch('reference_branch')
+ branch = self.make_branch_with_reference('branch',
+ referenced_branch.base)
+ parent = branch.reference_parent('file-id', 'path/to/file')
+ self.assertEqual(parent.base, referenced_branch.base)
+
+ def test_branch_relative_reference_location(self):
+ branch = self.make_branch('branch')
+ try:
+ branch.set_reference_info('file-id', 'path/to/file',
+ '../reference_branch')
+ except bzrlib.errors.UnsupportedOperation:
+ raise tests.TestNotApplicable('Branch cannot hold references.')
+ referenced_branch = self.make_branch('reference_branch')
+ parent = branch.reference_parent('file-id', 'path/to/file')
+ self.assertEqual(parent.base, referenced_branch.base)
+
+ def test_sprout_copies_reference_location(self):
+ branch = self.make_branch_with_reference('branch', '../reference')
+ new_branch = branch.bzrdir.sprout('new-branch').open_branch()
+ self.assertEqual('../reference',
+ new_branch.get_reference_info('file-id')[1])
+
+ def test_clone_copies_reference_location(self):
+ branch = self.make_branch_with_reference('branch', '../reference')
+ new_branch = branch.bzrdir.clone('new-branch').open_branch()
+ self.assertEqual('../reference',
+ new_branch.get_reference_info('file-id')[1])
+
+ def test_copied_locations_are_rebased(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
+ self.assertEqual('../reference',
+ new_branch.get_reference_info('file-id')[1])
+
+ def test_update_references_retains_old_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = self.make_branch_with_reference(
+ 'new_branch', 'reference', 'file-id2')
+ new_branch.update_references(branch)
+ self.assertEqual('reference',
+ branch.get_reference_info('file-id')[1])
+
+ def test_update_references_retains_known_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = self.make_branch_with_reference(
+ 'new_branch', 'reference2')
+ new_branch.update_references(branch)
+ self.assertEqual('reference',
+ branch.get_reference_info('file-id')[1])
+
+ def test_update_references_skips_known_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
+ new_branch.set_reference_info('file-id', '../foo', '../foo')
+ new_branch.update_references(branch)
+ self.assertEqual('reference',
+ branch.get_reference_info('file-id')[1])
+
+ def test_pull_updates_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
+ new_branch.set_reference_info('file-id2', '../foo', '../foo')
+ branch.pull(new_branch)
+ self.assertEqual('foo',
+ branch.get_reference_info('file-id2')[1])
+
+ def test_push_updates_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ new_branch = branch.bzrdir.sprout('branch/new-branch').open_branch()
+ new_branch.set_reference_info('file-id2', '../foo', '../foo')
+ new_branch.push(branch)
+ self.assertEqual('foo',
+ branch.get_reference_info('file-id2')[1])
+
+ def test_merge_updates_references(self):
+ branch = self.make_branch_with_reference('branch', 'reference')
+ tree = self.make_branch_and_tree('tree')
+ tree.commit('foo')
+ branch.pull(tree.branch)
+ checkout = branch.create_checkout('checkout', lightweight=True)
+ checkout.commit('bar')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ merger = merge.Merger.from_revision_ids(None, tree,
+ branch.last_revision(),
+ other_branch=branch)
+ merger.merge_type = merge.Merge3Merger
+ merger.do_merge()
+ self.assertEqual('../branch/reference',
+ tree.branch.get_reference_info('file-id')[1])
=== modified file 'bzrlib/tests/test_branch.py'
--- a/bzrlib/tests/test_branch.py 2009-04-08 03:34:31 +0000
+++ b/bzrlib/tests/test_branch.py 2009-04-23 16:02:28 +0000
@@ -228,6 +228,7 @@
branch = self.make_branch('a', format=self.get_format_name())
self.failUnlessExists('a/.bzr/branch/last-revision')
self.failIfExists('a/.bzr/branch/revision-history')
+ self.failIfExists('a/.bzr/branch/references')
def test_config(self):
"""Ensure that all configuration data is stored in the branch"""
@@ -378,6 +379,67 @@
self.assertTrue(branch.repository.has_revision(revid))
+class BzrBranch8(TestCaseWithTransport):
+
+ def make_branch(self, location, format=None):
+ if format is None:
+ format = bzrdir.format_registry.make_bzrdir('1.9')
+ format.set_branch_format(_mod_branch.BzrBranchFormat8())
+ return TestCaseWithTransport.make_branch(self, location, format=format)
+
+ def create_branch_with_reference(self):
+ branch = self.make_branch('branch')
+ branch._set_all_reference_info({'file-id': ('path', 'location')})
+ return branch
+
+ @staticmethod
+ def instrument_branch(branch, gets):
+ old_get = branch._transport.get
+ def get(*args, **kwargs):
+ gets.append((args, kwargs))
+ return old_get(*args, **kwargs)
+ branch._transport.get = get
+
+ def test_reference_info_caching_read_locked(self):
+ gets = []
+ branch = self.create_branch_with_reference()
+ branch.lock_read()
+ self.addCleanup(branch.unlock)
+ self.instrument_branch(branch, gets)
+ branch.get_reference_info('file-id')
+ branch.get_reference_info('file-id')
+ self.assertEqual(1, len(gets))
+
+ def test_reference_info_caching_read_unlocked(self):
+ gets = []
+ branch = self.create_branch_with_reference()
+ self.instrument_branch(branch, gets)
+ branch.get_reference_info('file-id')
+ branch.get_reference_info('file-id')
+ self.assertEqual(2, len(gets))
+
+ def test_reference_info_caching_write_locked(self):
+ gets = []
+ branch = self.make_branch('branch')
+ branch.lock_write()
+ self.instrument_branch(branch, gets)
+ self.addCleanup(branch.unlock)
+ branch._set_all_reference_info({'file-id': ('path2', 'location2')})
+ path, location = branch.get_reference_info('file-id')
+ self.assertEqual(0, len(gets))
+ self.assertEqual('path2', path)
+ self.assertEqual('location2', location)
+
+ def test_reference_info_caches_cleared(self):
+ branch = self.make_branch('branch')
+ branch.lock_write()
+ branch.set_reference_info('file-id', 'path2', 'location2')
+ branch.unlock()
+ doppelganger = Branch.open('branch')
+ doppelganger.set_reference_info('file-id', 'path3', 'location3')
+ self.assertEqual(('path3', 'location3'),
+ branch.get_reference_info('file-id'))
+
class TestBranchReference(TestCaseWithTransport):
"""Tests for the branch reference facility."""
=== modified file 'bzrlib/tests/test_upgrade.py'
--- a/bzrlib/tests/test_upgrade.py 2009-03-28 14:24:46 +0000
+++ b/bzrlib/tests/test_upgrade.py 2009-04-20 20:58:51 +0000
@@ -201,6 +201,16 @@
branch2 = _mod_branch.Branch.open(self.get_url('branch'))
self.assertIs(branch2.__class__, _mod_branch.BzrBranch6)
+ def test_convert_branch7_branch8(self):
+ branch = self.make_branch('branch', format='1.9')
+ target = bzrdir.format_registry.make_bzrdir('1.9')
+ target.set_branch_format(_mod_branch.BzrBranchFormat8())
+ converter = branch.bzrdir._format.get_converter(target)
+ converter.convert(branch.bzrdir, progress.DummyProgress())
+ branch = _mod_branch.Branch.open(self.get_url('branch'))
+ self.assertIs(branch.__class__, _mod_branch.BzrBranch8)
+ self.assertEqual({}, branch._get_all_reference_info())
+
def test_convert_knit_dirstate_empty(self):
# test that asking for an upgrade from knit to dirstate works.
tree = self.make_branch_and_tree('tree', format='knit')
More information about the bazaar-commits
mailing list