Merge lp:~jelmer/brz/nested-tree-filetimes into lp:brz/3.2
- nested-tree-filetimes
- Merge into 3.2
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | 7572 |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/nested-tree-filetimes |
Merge into: | lp:brz/3.2 |
Diff against target: |
290 lines (+67/-31) 10 files modified
breezy/archive/tar.py (+1/-2) breezy/bzr/workingtree_4.py (+3/-0) breezy/git/annotate.py (+1/-1) breezy/git/filegraph.py (+25/-8) breezy/git/repository.py (+2/-4) breezy/git/tree.py (+9/-10) breezy/git/workingtree.py (+3/-4) breezy/tests/per_workingtree/test_get_file_mtime.py (+21/-0) byov.conf (+1/-1) setup.py (+1/-1) |
To merge this branch: | bzr merge lp:~jelmer/brz/nested-tree-filetimes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+413630@code.launchpad.net |
Commit message
Support nested trees in Tree.get_
Description of the change
Support nested trees in Tree.get_
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 : | # |
- 7573. By Jelmer Vernooij
-
install dulwich from pip.
- 7574. By Jelmer Vernooij
-
Bump dulwich.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/archive/tar.py' | |||
2 | --- breezy/archive/tar.py 2020-02-18 01:57:45 +0000 | |||
3 | +++ breezy/archive/tar.py 2022-01-04 23:27:18 +0000 | |||
4 | @@ -41,7 +41,6 @@ | |||
5 | 41 | 41 | ||
6 | 42 | Returns a (tarinfo, fileobj) tuple | 42 | Returns a (tarinfo, fileobj) tuple |
7 | 43 | """ | 43 | """ |
8 | 44 | file_id = getattr(entry, 'file_id', None) | ||
9 | 45 | filename = osutils.pathjoin(root, final_path) | 44 | filename = osutils.pathjoin(root, final_path) |
10 | 46 | item = tarfile.TarInfo(filename) | 45 | item = tarfile.TarInfo(filename) |
11 | 47 | if force_mtime is not None: | 46 | if force_mtime is not None: |
12 | @@ -75,7 +74,7 @@ | |||
13 | 75 | fileobj = None | 74 | fileobj = None |
14 | 76 | else: | 75 | else: |
15 | 77 | raise errors.BzrError("don't know how to export {%s} of kind %r" | 76 | raise errors.BzrError("don't know how to export {%s} of kind %r" |
17 | 78 | % (file_id, entry.kind)) | 77 | % (final_path, entry.kind)) |
18 | 79 | return (item, fileobj) | 78 | return (item, fileobj) |
19 | 80 | 79 | ||
20 | 81 | 80 | ||
21 | 82 | 81 | ||
22 | === modified file 'breezy/bzr/workingtree_4.py' | |||
23 | --- breezy/bzr/workingtree_4.py 2020-11-18 02:15:43 +0000 | |||
24 | +++ breezy/bzr/workingtree_4.py 2022-01-04 23:27:18 +0000 | |||
25 | @@ -1928,6 +1928,9 @@ | |||
26 | 1928 | # Make sure the file exists | 1928 | # Make sure the file exists |
27 | 1929 | entry = self._get_entry(path=path) | 1929 | entry = self._get_entry(path=path) |
28 | 1930 | if entry == (None, None): # do we raise? | 1930 | if entry == (None, None): # do we raise? |
29 | 1931 | nested_tree, subpath = self.get_containing_nested_tree(path) | ||
30 | 1932 | if nested_tree is not None: | ||
31 | 1933 | return nested_tree.get_file_mtime(subpath) | ||
32 | 1931 | raise errors.NoSuchFile(path) | 1934 | raise errors.NoSuchFile(path) |
33 | 1932 | parent_index = self._get_parent_index() | 1935 | parent_index = self._get_parent_index() |
34 | 1933 | last_changed_revision = entry[1][parent_index][4] | 1936 | last_changed_revision = entry[1][parent_index][4] |
35 | 1934 | 1937 | ||
36 | === modified file 'breezy/git/annotate.py' | |||
37 | --- breezy/git/annotate.py 2020-07-18 23:14:00 +0000 | |||
38 | +++ breezy/git/annotate.py 2022-01-04 23:27:18 +0000 | |||
39 | @@ -122,7 +122,7 @@ | |||
40 | 122 | path = encode_git_path(path) | 122 | path = encode_git_path(path) |
41 | 123 | for commit_parent in self.store[commit_id].parents: | 123 | for commit_parent in self.store[commit_id].parents: |
42 | 124 | try: | 124 | try: |
44 | 125 | (path, text_parent) = ( | 125 | (store, path, text_parent) = ( |
45 | 126 | self.change_scanner.find_last_change_revision( | 126 | self.change_scanner.find_last_change_revision( |
46 | 127 | path, commit_parent)) | 127 | path, commit_parent)) |
47 | 128 | except KeyError: | 128 | except KeyError: |
48 | 129 | 129 | ||
49 | === modified file 'breezy/git/filegraph.py' | |||
50 | --- breezy/git/filegraph.py 2020-07-18 23:14:00 +0000 | |||
51 | +++ breezy/git/filegraph.py 2022-01-04 23:27:18 +0000 | |||
52 | @@ -17,11 +17,17 @@ | |||
53 | 17 | 17 | ||
54 | 18 | """File graph access.""" | 18 | """File graph access.""" |
55 | 19 | 19 | ||
56 | 20 | import posixpath | ||
57 | 20 | import stat | 21 | import stat |
58 | 21 | 22 | ||
59 | 22 | from dulwich.errors import ( | 23 | from dulwich.errors import ( |
60 | 23 | NotTreeError, | 24 | NotTreeError, |
61 | 24 | ) | 25 | ) |
62 | 26 | try: | ||
63 | 27 | from dulwich.objects import SubmoduleEncountered | ||
64 | 28 | except ImportError: | ||
65 | 29 | class SubmoduleEncountered(Exception): | ||
66 | 30 | pass | ||
67 | 25 | from dulwich.object_store import ( | 31 | from dulwich.object_store import ( |
68 | 26 | tree_lookup_path, | 32 | tree_lookup_path, |
69 | 27 | ) | 33 | ) |
70 | @@ -44,9 +50,20 @@ | |||
71 | 44 | def find_last_change_revision(self, path, commit_id): | 50 | def find_last_change_revision(self, path, commit_id): |
72 | 45 | if not isinstance(path, bytes): | 51 | if not isinstance(path, bytes): |
73 | 46 | raise TypeError(path) | 52 | raise TypeError(path) |
77 | 47 | commit = self.store[commit_id] | 53 | store = self.store |
78 | 48 | target_mode, target_sha = tree_lookup_path(self.store.__getitem__, | 54 | while True: |
79 | 49 | commit.tree, path) | 55 | commit = store[commit_id] |
80 | 56 | try: | ||
81 | 57 | target_mode, target_sha = tree_lookup_path( | ||
82 | 58 | store.__getitem__, commit.tree, path) | ||
83 | 59 | except SubmoduleEncountered as e: | ||
84 | 60 | revid = self.repository.lookup_foreign_revision_id(commit_id) | ||
85 | 61 | revtree = self.repository.revision_tree(revid) | ||
86 | 62 | store = revtree._get_submodule_store(e.path) | ||
87 | 63 | commit_id = e.sha | ||
88 | 64 | path = posixpath.relpath(path, e.path) | ||
89 | 65 | else: | ||
90 | 66 | break | ||
91 | 50 | if path == b'': | 67 | if path == b'': |
92 | 51 | target_mode = stat.S_IFDIR | 68 | target_mode = stat.S_IFDIR |
93 | 52 | if target_mode is None: | 69 | if target_mode is None: |
94 | @@ -54,9 +71,9 @@ | |||
95 | 54 | (target_sha, path, commit_id)) | 71 | (target_sha, path, commit_id)) |
96 | 55 | while True: | 72 | while True: |
97 | 56 | parent_commits = [] | 73 | parent_commits = [] |
99 | 57 | for parent_commit in [self.store[c] for c in commit.parents]: | 74 | for parent_commit in [store[c] for c in commit.parents]: |
100 | 58 | try: | 75 | try: |
102 | 59 | mode, sha = tree_lookup_path(self.store.__getitem__, | 76 | mode, sha = tree_lookup_path(store.__getitem__, |
103 | 60 | parent_commit.tree, path) | 77 | parent_commit.tree, path) |
104 | 61 | except (NotTreeError, KeyError): | 78 | except (NotTreeError, KeyError): |
105 | 62 | continue | 79 | continue |
106 | @@ -68,11 +85,11 @@ | |||
107 | 68 | # or is a directory that didn't previously exist. | 85 | # or is a directory that didn't previously exist. |
108 | 69 | if mode != target_mode or ( | 86 | if mode != target_mode or ( |
109 | 70 | not stat.S_ISDIR(target_mode) and sha != target_sha): | 87 | not stat.S_ISDIR(target_mode) and sha != target_sha): |
111 | 71 | return (path, commit.id) | 88 | return (store, path, commit.id) |
112 | 72 | if parent_commits == []: | 89 | if parent_commits == []: |
113 | 73 | break | 90 | break |
114 | 74 | commit = parent_commits[0] | 91 | commit = parent_commits[0] |
116 | 75 | return (path, commit.id) | 92 | return (store, path, commit.id) |
117 | 76 | 93 | ||
118 | 77 | 94 | ||
119 | 78 | class GitFileParentProvider(object): | 95 | class GitFileParentProvider(object): |
120 | @@ -92,7 +109,7 @@ | |||
121 | 92 | text_parents = [] | 109 | text_parents = [] |
122 | 93 | for commit_parent in self.store[commit_id].parents: | 110 | for commit_parent in self.store[commit_id].parents: |
123 | 94 | try: | 111 | try: |
125 | 95 | (path, text_parent) = ( | 112 | (store, path, text_parent) = ( |
126 | 96 | self.change_scanner.find_last_change_revision( | 113 | self.change_scanner.find_last_change_revision( |
127 | 97 | path, commit_parent)) | 114 | path, commit_parent)) |
128 | 98 | except KeyError: | 115 | except KeyError: |
129 | 99 | 116 | ||
130 | === modified file 'breezy/git/repository.py' | |||
131 | --- breezy/git/repository.py 2021-04-03 12:58:34 +0000 | |||
132 | +++ breezy/git/repository.py 2022-01-04 23:27:18 +0000 | |||
133 | @@ -308,12 +308,10 @@ | |||
134 | 308 | except ValueError: | 308 | except ValueError: |
135 | 309 | raise errors.RevisionNotPresent((fileid, revid), self) | 309 | raise errors.RevisionNotPresent((fileid, revid), self) |
136 | 310 | try: | 310 | try: |
138 | 311 | obj = tree_lookup_path( | 311 | mode, item_id = tree_lookup_path( |
139 | 312 | self._git.object_store.__getitem__, root_tree, | 312 | self._git.object_store.__getitem__, root_tree, |
140 | 313 | encode_git_path(path)) | 313 | encode_git_path(path)) |
144 | 314 | if isinstance(obj, tuple): | 314 | obj = self._git.object_store[item_id] |
142 | 315 | (mode, item_id) = obj | ||
143 | 316 | obj = self._git.object_store[item_id] | ||
145 | 317 | except KeyError: | 315 | except KeyError: |
146 | 318 | raise errors.RevisionNotPresent((fileid, revid), self) | 316 | raise errors.RevisionNotPresent((fileid, revid), self) |
147 | 319 | else: | 317 | else: |
148 | 320 | 318 | ||
149 | === modified file 'breezy/git/tree.py' | |||
150 | --- breezy/git/tree.py 2021-12-09 20:50:25 +0000 | |||
151 | +++ breezy/git/tree.py 2022-01-04 23:27:18 +0000 | |||
152 | @@ -37,7 +37,6 @@ | |||
153 | 37 | IndexEntry, | 37 | IndexEntry, |
154 | 38 | ) | 38 | ) |
155 | 39 | from dulwich.object_store import ( | 39 | from dulwich.object_store import ( |
156 | 40 | tree_lookup_path, | ||
157 | 41 | OverlayObjectStore, | 40 | OverlayObjectStore, |
158 | 42 | ) | 41 | ) |
159 | 43 | from dulwich.objects import ( | 42 | from dulwich.objects import ( |
160 | @@ -369,21 +368,21 @@ | |||
161 | 369 | change_scanner = self._repository._file_change_scanner | 368 | change_scanner = self._repository._file_change_scanner |
162 | 370 | if self.commit_id == ZERO_SHA: | 369 | if self.commit_id == ZERO_SHA: |
163 | 371 | return NULL_REVISION | 370 | return NULL_REVISION |
165 | 372 | (unused_path, commit_id) = change_scanner.find_last_change_revision( | 371 | (store, unused_path, commit_id) = change_scanner.find_last_change_revision( |
166 | 373 | encode_git_path(path), self.commit_id) | 372 | encode_git_path(path), self.commit_id) |
169 | 374 | return self._repository.lookup_foreign_revision_id( | 373 | return self.mapping.revision_id_foreign_to_bzr(commit_id) |
168 | 375 | commit_id, self.mapping) | ||
170 | 376 | 374 | ||
171 | 377 | def get_file_mtime(self, path): | 375 | def get_file_mtime(self, path): |
172 | 376 | change_scanner = self._repository._file_change_scanner | ||
173 | 377 | if self.commit_id == ZERO_SHA: | ||
174 | 378 | return NULL_REVISION | ||
175 | 378 | try: | 379 | try: |
177 | 379 | revid = self.get_file_revision(path) | 380 | (store, unused_path, commit_id) = change_scanner.find_last_change_revision( |
178 | 381 | encode_git_path(path), self.commit_id) | ||
179 | 380 | except KeyError: | 382 | except KeyError: |
180 | 381 | raise errors.NoSuchFile(path) | 383 | raise errors.NoSuchFile(path) |
186 | 382 | try: | 384 | commit = store[commit_id] |
187 | 383 | rev = self._repository.get_revision(revid) | 385 | return commit.commit_time |
183 | 384 | except errors.NoSuchRevision: | ||
184 | 385 | raise _mod_tree.FileTimestampUnavailable(path) | ||
185 | 386 | return rev.timestamp | ||
188 | 387 | 386 | ||
189 | 388 | def id2path(self, file_id, recurse='down'): | 387 | def id2path(self, file_id, recurse='down'): |
190 | 389 | try: | 388 | try: |
191 | 390 | 389 | ||
192 | === modified file 'breezy/git/workingtree.py' | |||
193 | --- breezy/git/workingtree.py 2021-05-30 17:12:41 +0000 | |||
194 | +++ breezy/git/workingtree.py 2022-01-04 23:27:18 +0000 | |||
195 | @@ -37,9 +37,6 @@ | |||
196 | 37 | validate_path, | 37 | validate_path, |
197 | 38 | write_index_dict, | 38 | write_index_dict, |
198 | 39 | ) | 39 | ) |
199 | 40 | from dulwich.object_store import ( | ||
200 | 41 | tree_lookup_path, | ||
201 | 42 | ) | ||
202 | 43 | from dulwich.objects import ( | 40 | from dulwich.objects import ( |
203 | 44 | S_ISGITLINK, | 41 | S_ISGITLINK, |
204 | 45 | ) | 42 | ) |
205 | @@ -75,6 +72,7 @@ | |||
206 | 75 | 72 | ||
207 | 76 | from .dir import ( | 73 | from .dir import ( |
208 | 77 | LocalGitDir, | 74 | LocalGitDir, |
209 | 75 | BareLocalGitControlDirFormat, | ||
210 | 78 | ) | 76 | ) |
211 | 79 | from .tree import ( | 77 | from .tree import ( |
212 | 80 | MutableGitIndexTree, | 78 | MutableGitIndexTree, |
213 | @@ -219,10 +217,11 @@ | |||
214 | 219 | info = self._submodule_info()[relpath] | 217 | info = self._submodule_info()[relpath] |
215 | 220 | except KeyError: | 218 | except KeyError: |
216 | 221 | submodule_transport = self.user_transport.clone(decode_git_path(relpath)) | 219 | submodule_transport = self.user_transport.clone(decode_git_path(relpath)) |
217 | 220 | submodule_dir = self._format._matchingcontroldir.open(submodule_transport) | ||
218 | 222 | else: | 221 | else: |
219 | 223 | submodule_transport = self.control_transport.clone( | 222 | submodule_transport = self.control_transport.clone( |
220 | 224 | posixpath.join('modules', decode_git_path(info[1]))) | 223 | posixpath.join('modules', decode_git_path(info[1]))) |
222 | 225 | submodule_dir = self._format._matchingcontroldir.open(submodule_transport) | 224 | submodule_dir = BareLocalGitControlDirFormat().open(submodule_transport) |
223 | 226 | return Index(submodule_dir.control_transport.local_abspath('index')) | 225 | return Index(submodule_dir.control_transport.local_abspath('index')) |
224 | 227 | 226 | ||
225 | 228 | def lock_read(self): | 227 | def lock_read(self): |
226 | 229 | 228 | ||
227 | === modified file 'breezy/tests/per_workingtree/test_get_file_mtime.py' | |||
228 | --- breezy/tests/per_workingtree/test_get_file_mtime.py 2018-11-16 18:33:17 +0000 | |||
229 | +++ breezy/tests/per_workingtree/test_get_file_mtime.py 2022-01-04 23:27:18 +0000 | |||
230 | @@ -20,6 +20,7 @@ | |||
231 | 20 | 20 | ||
232 | 21 | from breezy import errors | 21 | from breezy import errors |
233 | 22 | from breezy.tree import FileTimestampUnavailable | 22 | from breezy.tree import FileTimestampUnavailable |
234 | 23 | from breezy.tests import TestNotApplicable | ||
235 | 23 | from breezy.tests.per_workingtree import TestCaseWithWorkingTree | 24 | from breezy.tests.per_workingtree import TestCaseWithWorkingTree |
236 | 24 | 25 | ||
237 | 25 | 26 | ||
238 | @@ -36,6 +37,26 @@ | |||
239 | 36 | tree.add(['one']) | 37 | tree.add(['one']) |
240 | 37 | return tree | 38 | return tree |
241 | 38 | 39 | ||
242 | 40 | def test_get_file_mtime_nested(self): | ||
243 | 41 | tree = self.make_basic_tree() | ||
244 | 42 | subtree = self.make_branch_and_tree('tree/sub') | ||
245 | 43 | self.build_tree(['tree/sub/one']) | ||
246 | 44 | subtree.add(['one']) | ||
247 | 45 | subtree.commit('one') | ||
248 | 46 | try: | ||
249 | 47 | tree.add_reference(subtree) | ||
250 | 48 | except errors.UnsupportedOperation: | ||
251 | 49 | raise TestNotApplicable('subtrees not supported') | ||
252 | 50 | tree.commit('sub') | ||
253 | 51 | |||
254 | 52 | with tree.lock_read(), subtree.lock_read(): | ||
255 | 53 | self.assertEqual( | ||
256 | 54 | tree.get_file_mtime('sub/one'), | ||
257 | 55 | subtree.get_file_mtime('one')) | ||
258 | 56 | self.assertEqual( | ||
259 | 57 | tree.basis_tree().get_file_mtime('sub/one'), | ||
260 | 58 | subtree.basis_tree().get_file_mtime('one')) | ||
261 | 59 | |||
262 | 39 | def test_get_file_mtime(self): | 60 | def test_get_file_mtime(self): |
263 | 40 | tree = self.make_basic_tree() | 61 | tree = self.make_basic_tree() |
264 | 41 | 62 | ||
265 | 42 | 63 | ||
266 | === modified file 'byov.conf' | |||
267 | --- byov.conf 2021-08-19 18:07:03 +0000 | |||
268 | +++ byov.conf 2022-01-04 23:27:18 +0000 | |||
269 | @@ -5,7 +5,7 @@ | |||
270 | 5 | subunit.clone = (git clone https://github.com/testing-cabal/subunit.git ../subunit) | 5 | subunit.clone = (git clone https://github.com/testing-cabal/subunit.git ../subunit) |
271 | 6 | sphinx_epytext.install = (pip3 install sphinx_epytext) | 6 | sphinx_epytext.install = (pip3 install sphinx_epytext) |
272 | 7 | flake8.install3 = (pip3 install flake8) | 7 | flake8.install3 = (pip3 install flake8) |
274 | 8 | brz.extras = fastimport,launchpad,workspace,git,cext,doc | 8 | brz.extras = fastimport,launchpad,workspace,git,cext,doc,dulwich |
275 | 9 | 9 | ||
276 | 10 | [brz] | 10 | [brz] |
277 | 11 | # because paramiko 2.0.0 is broken: | 11 | # because paramiko 2.0.0 is broken: |
278 | 12 | 12 | ||
279 | === modified file 'setup.py' | |||
280 | --- setup.py 2021-11-16 11:09:01 +0000 | |||
281 | +++ setup.py 2022-01-04 23:27:18 +0000 | |||
282 | @@ -63,7 +63,7 @@ | |||
283 | 63 | 'patiencediff', | 63 | 'patiencediff', |
284 | 64 | # Technically, Breezy works without these two dependencies too. But there's | 64 | # Technically, Breezy works without these two dependencies too. But there's |
285 | 65 | # no way to enable them by default and let users opt out. | 65 | # no way to enable them by default and let users opt out. |
287 | 66 | 'dulwich>=0.20.23', | 66 | 'dulwich>=0.20.27', |
288 | 67 | ], | 67 | ], |
289 | 68 | 'extras_require': { | 68 | 'extras_require': { |
290 | 69 | 'cext': ['cython>=0.29'], | 69 | 'cext': ['cython>=0.29'], |
Running landing tests failed /ci.breezy- vcs.org/ job/brz- 3.2/job/ brz-3.2- land/80/
https:/