Merge lp:~jelmer/brz/get-nested-tree into lp:brz

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/get-nested-tree
Merge into: lp:brz
Diff against target: 211 lines (+75/-8)
6 files modified
breezy/bzr/inventorytree.py (+5/-0)
breezy/bzr/workingtree_4.py (+8/-0)
breezy/git/tree.py (+31/-4)
breezy/tests/per_tree/test_tree.py (+11/-4)
breezy/tree.py (+17/-0)
doc/en/release-notes/brz-3.1.txt (+3/-0)
To merge this branch: bzr merge lp:~jelmer/brz/get-nested-tree
Reviewer Review Type Date Requested Status
Martin Packman Approve
Review via email: mp+369476@code.launchpad.net

Commit message

Add ``Tree.get_nested_tree`` for retrieving a nested tree from another tree.

Description of the change

Add ``Tree.get_nested_tree`` for retrieving a nested tree.

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

Looks good, thanks.

review: Approve
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
1=== modified file 'breezy/bzr/inventorytree.py'
2--- breezy/bzr/inventorytree.py 2019-06-22 12:07:42 +0000
3+++ breezy/bzr/inventorytree.py 2019-07-07 16:28:18 +0000
4@@ -51,6 +51,7 @@
5 from ..tree import (
6 FileTimestampUnavailable,
7 InterTree,
8+ MissingNestedTree,
9 Tree,
10 TreeChange,
11 )
12@@ -773,6 +774,10 @@
13 def get_reference_revision(self, path):
14 return self._path2ie(path).reference_revision
15
16+ def get_nested_tree(self, path):
17+ nested_revid = self.get_reference_revision(path)
18+ raise MissingNestedTree(path)
19+
20 def get_root_id(self):
21 if self.root_inventory.root:
22 return self.root_inventory.root.file_id
23
24=== modified file 'breezy/bzr/workingtree_4.py'
25--- breezy/bzr/workingtree_4.py 2019-06-18 13:48:45 +0000
26+++ breezy/bzr/workingtree_4.py 2019-07-07 16:28:18 +0000
27@@ -78,6 +78,7 @@
28 from ..tree import (
29 FileTimestampUnavailable,
30 InterTree,
31+ MissingNestedTree,
32 )
33 from ..workingtree import (
34 WorkingTree,
35@@ -1758,6 +1759,13 @@
36 path_utf8 = osutils.pathjoin(entry[0][0], entry[0][1])
37 return path_utf8.decode('utf8')
38
39+ def get_nested_tree(self, path):
40+ with self.lock_read():
41+ nested_revid = self.get_reference_revision(path)
42+ # TODO(jelmer): Attempt to open 'path' as a working tree, and see if we can find
43+ # the referenced revision id in our memory?
44+ raise MissingNestedTree(path)
45+
46 def iter_references(self):
47 if not self._repo_supports_tree_reference:
48 # When the repo doesn't support references, we will have nothing to
49
50=== modified file 'breezy/git/tree.py'
51--- breezy/git/tree.py 2019-06-21 17:49:36 +0000
52+++ breezy/git/tree.py 2019-07-07 16:28:18 +0000
53@@ -253,6 +253,7 @@
54 def __init__(self, repository, revision_id):
55 self._revision_id = revision_id
56 self._repository = repository
57+ self._submodules = None
58 self.store = repository._git.object_store
59 if not isinstance(revision_id, bytes):
60 raise TypeError(revision_id)
61@@ -273,12 +274,38 @@
62 self._fileid_map = self.mapping.get_fileid_map(
63 self.store.__getitem__, self.tree)
64
65- def _get_nested_repository(self, path):
66- nested_repo_transport = self._repository.user_transport.clone(path)
67+ def _submodule_info(self):
68+ if self._submodules is None:
69+ try:
70+ with self.get_file('.gitmodules') as f:
71+ config = GitConfigFile.from_file(f)
72+ self._submodules = {
73+ path: (url, section)
74+ for path, url, section in parse_submodules(config)}
75+ except errors.NoSuchFile:
76+ self._submodules = {}
77+ return self._submodules
78+
79+ def _get_submodule_repository(self, relpath):
80+ if not isinstance(relpath, bytes):
81+ raise TypeError(relpath)
82+ try:
83+ info = self._submodule_info()[relpath]
84+ except KeyError:
85+ nested_repo_transport = self._repository.user_transport.clone(relpath.decode('utf-8'))
86+ else:
87+ nested_repo_transport = self._repository.control_transport.clone(
88+ posixpath.join('modules', info[0]))
89 nested_controldir = _mod_controldir.ControlDir.open_from_transport(
90 nested_repo_transport)
91 return nested_controldir.find_repository()
92
93+ def get_nested_tree(self, path):
94+ encoded_path = path.encode('utf-8')
95+ nested_repo = self._get_submodule_repository(encoded_path)
96+ ref_rev = self.get_reference_revision(path)
97+ return nested_repo.revision_tree(ref_rev)
98+
99 def supports_rename_tracking(self):
100 return False
101
102@@ -565,7 +592,7 @@
103 """See RevisionTree.get_symlink_target."""
104 (store, mode, hexsha) = self._lookup_path(path)
105 if S_ISGITLINK(mode):
106- nested_repo = self._get_nested_repository(path)
107+ nested_repo = self._get_submodule_repository(path.encode('utf-8'))
108 return nested_repo.lookup_foreign_revision_id(hexsha)
109 else:
110 return None
111@@ -590,7 +617,7 @@
112 elif kind == 'symlink':
113 return (kind, None, None, store[hexsha].data.decode('utf-8'))
114 elif kind == 'tree-reference':
115- nested_repo = self._get_nested_repository(path)
116+ nested_repo = self._get_submodule_repository(path.encode('utf-8'))
117 return (kind, None, None,
118 nested_repo.lookup_foreign_revision_id(hexsha))
119 else:
120
121=== modified file 'breezy/tests/per_tree/test_tree.py'
122--- breezy/tests/per_tree/test_tree.py 2019-06-22 12:07:42 +0000
123+++ breezy/tests/per_tree/test_tree.py 2019-07-07 16:28:18 +0000
124@@ -21,6 +21,7 @@
125 revisiontree,
126 tests,
127 )
128+from breezy.tree import MissingNestedTree
129 from breezy.bzr import (
130 workingtree_4,
131 )
132@@ -82,14 +83,11 @@
133
134 def create_nested(self):
135 work_tree = self.make_branch_and_tree('wt')
136- work_tree.lock_write()
137- try:
138+ with work_tree.lock_write():
139 self.skip_if_no_reference(work_tree)
140 subtree = self.make_branch_and_tree('wt/subtree')
141 subtree.commit('foo')
142 work_tree.add_reference(subtree)
143- finally:
144- work_tree.unlock()
145 tree = self._convert_tree(work_tree)
146 self.skip_if_no_reference(tree)
147 return tree, subtree
148@@ -110,6 +108,15 @@
149 [u'subtree'],
150 list(tree.iter_references()))
151
152+ def test_get_nested_tree(self):
153+ tree, subtree = self.create_nested()
154+ try:
155+ changes = subtree.changes_from(tree.get_nested_tree('subtree'))
156+ self.assertFalse(changes.has_changed())
157+ except MissingNestedTree:
158+ # Also okay.
159+ pass
160+
161 def test_get_root_id(self):
162 # trees should return some kind of root id; it can be none
163 tree = self.make_branch_and_tree('tree')
164
165=== modified file 'breezy/tree.py'
166--- breezy/tree.py 2019-06-22 11:16:17 +0000
167+++ breezy/tree.py 2019-07-07 16:28:18 +0000
168@@ -61,6 +61,14 @@
169 self.path = path
170
171
172+class MissingNestedTree(errors.BzrError):
173+
174+ _fmt = "The nested tree for %(path)s can not be resolved."""
175+
176+ def __init__(self, path):
177+ self.path = path
178+
179+
180 class TreeEntry(object):
181 """An entry that implements the minimum interface used by commands.
182 """
183@@ -349,6 +357,15 @@
184 if entry.kind == 'tree-reference':
185 yield path
186
187+ def get_nested_tree(self, path):
188+ """Open the nested tree at the specified path.
189+
190+ :param path: Path from which to resolve tree reference.
191+ :return: A Tree object for the nested tree
192+ :raise MissingNestedTree: If the nested tree can not be resolved
193+ """
194+ raise NotImplementedError(self.get_nested_tree)
195+
196 def kind(self, path):
197 raise NotImplementedError("Tree subclass %s must implement kind"
198 % self.__class__.__name__)
199
200=== modified file 'doc/en/release-notes/brz-3.1.txt'
201--- doc/en/release-notes/brz-3.1.txt 2019-07-07 16:21:24 +0000
202+++ doc/en/release-notes/brz-3.1.txt 2019-07-07 16:28:18 +0000
203@@ -84,6 +84,9 @@
204 * New ``Tree.get_transform`` method for getting a ``TreeTransform``
205 object. (Jelmer Vernooij)
206
207+* New ``Tree.get_nested_tree`` method for retrieving a nested tree.
208+ (Jelmer Vernooij)
209+
210 Internals
211 *********
212

Subscribers

People subscribed via source and target branches