Merge lp:~jelmer/brz/commit-builder-fixes into lp:~jelmer/brz/foreign
- commit-builder-fixes
- Merge into foreign
Proposed by
Jelmer Vernooij
Status: | Superseded |
---|---|
Proposed branch: | lp:~jelmer/brz/commit-builder-fixes |
Merge into: | lp:~jelmer/brz/foreign |
Diff against target: |
5948 lines (+1655/-931) (has conflicts) 63 files modified
Makefile (+6/-0) breezy/branch.py (+8/-28) breezy/branchbuilder.py (+4/-4) breezy/builtins.py (+13/-14) breezy/bzr/branch.py (+31/-0) breezy/bzr/inventory.py (+2/-2) breezy/bzr/inventorytree.py (+179/-47) breezy/bzr/remote.py (+1/-0) breezy/bzr/workingtree.py (+5/-8) breezy/bzr/workingtree_4.py (+1/-1) breezy/config.py (+1/-1) breezy/filter_tree.py (+3/-3) breezy/filters/__init__.py (+4/-19) breezy/gpg.py (+6/-3) breezy/log.py (+1/-1) breezy/memorytree.py (+6/-1) breezy/merge.py (+168/-171) breezy/plugins/changelog_merge/changelog_merge.py (+23/-0) breezy/plugins/changelog_merge/tests/test_changelog_merge.py (+3/-2) breezy/plugins/launchpad/lp_registration.py (+2/-3) breezy/plugins/po_merge/po_merge.py (+1/-1) breezy/plugins/stats/cmds.py (+3/-2) breezy/plugins/stats/test_stats.py (+1/-0) breezy/rename_map.py (+9/-1) breezy/tests/__init__.py (+1/-1) breezy/tests/blackbox/test_config.py (+4/-4) breezy/tests/matchers.py (+74/-0) breezy/tests/per_branch/test_branch.py (+5/-0) breezy/tests/per_branch/test_commit.py (+15/-6) breezy/tests/per_intertree/test_compare.py (+3/-1) breezy/tests/per_intertree/test_file_content_matches.py (+14/-1) breezy/tests/per_repository/test_commit_builder.py (+136/-120) breezy/tests/per_repository_vf/test_fileid_involved.py (+1/-2) breezy/tests/per_tree/__init__.py (+0/-50) breezy/tests/per_tree/test_inv.py (+10/-4) breezy/tests/per_tree/test_test_trees.py (+157/-51) breezy/tests/per_tree/test_tree.py (+9/-1) breezy/tests/per_tree/test_walkdirs.py (+1/-1) breezy/tests/per_workingtree/test_check_state.py (+5/-2) breezy/tests/per_workingtree/test_inv.py (+1/-1) breezy/tests/per_workingtree/test_merge_from_branch.py (+1/-1) breezy/tests/per_workingtree/test_move.py (+230/-0) breezy/tests/per_workingtree/test_nested_specifics.py (+1/-1) breezy/tests/per_workingtree/test_paths2ids.py (+37/-0) breezy/tests/per_workingtree/test_pull.py (+1/-1) breezy/tests/per_workingtree/test_rename_one.py (+117/-0) breezy/tests/per_workingtree/test_revision_tree.py (+3/-3) breezy/tests/per_workingtree/test_workingtree.py (+8/-8) breezy/tests/test_bundle.py (+9/-9) breezy/tests/test_bzrdir.py (+1/-1) breezy/tests/test_matchers.py (+28/-0) breezy/tests/test_merge.py (+28/-10) breezy/tests/test_merge_core.py (+5/-5) breezy/tests/test_revert.py (+2/-2) breezy/tests/test_shelf.py (+2/-2) breezy/tests/test_transform.py (+49/-48) breezy/tests/test_workingtree.py (+2/-1) breezy/transform.py (+91/-101) breezy/transport/http/_urllib2_wrappers.py (+3/-1) breezy/transport/sftp.py (+2/-2) breezy/tree.py (+93/-177) breezy/workingtree.py (+18/-1) doc/en/release-notes/brz-3.0.txt (+7/-0) Text conflict in breezy/gpg.py Text conflict in breezy/merge.py Text conflict in breezy/plugins/changelog_merge/changelog_merge.py Text conflict in breezy/tests/matchers.py Text conflict in breezy/tests/per_intertree/test_file_content_matches.py Text conflict in breezy/tests/per_repository/test_commit_builder.py Text conflict in breezy/tests/per_workingtree/test_move.py Text conflict in breezy/tests/per_workingtree/test_rename_one.py Text conflict in breezy/tests/test_matchers.py Text conflict in breezy/transform.py Text conflict in breezy/tree.py Text conflict in breezy/workingtree.py |
To merge this branch: | bzr merge lp:~jelmer/brz/commit-builder-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Pending | ||
Review via email: mp+342046@code.launchpad.net |
This proposal has been superseded by a proposal from 2018-03-24.
Commit message
Description of the change
Some fixes for the commit builder tests.
* Add some entropy to commit messages.
* Skip tests that rely on empty versioned directories
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2017-11-21 01:01:11 +0000 |
3 | +++ Makefile 2018-03-24 17:11:56 +0000 |
4 | @@ -90,6 +90,12 @@ |
5 | # Check that there were no errors reported. |
6 | subunit-stats < selftest.log |
7 | |
8 | +check-ci: docs extensions |
9 | + # FIXME: Remove -Wignore::FutureWarning once |
10 | + # https://github.com/paramiko/paramiko/issues/713 is not a concern |
11 | + # anymore -- vila 2017-05-24 |
12 | + python -Werror -Wignore::FutureWarning -Wignore::ImportWarning -O ./brz selftest -v --parallel=fork -Oselftest.timeout=120 --subunit2 |
13 | + |
14 | # Run Python style checker (apt-get install pyflakes) |
15 | # |
16 | # Note that at present this gives many false warnings, because it doesn't |
17 | |
18 | === modified file 'breezy/branch.py' |
19 | --- breezy/branch.py 2018-03-04 02:57:55 +0000 |
20 | +++ breezy/branch.py 2018-03-24 17:11:56 +0000 |
21 | @@ -26,6 +26,7 @@ |
22 | config as _mod_config, |
23 | debug, |
24 | fetch, |
25 | + memorytree, |
26 | repository, |
27 | revision as _mod_revision, |
28 | tag as _mod_tag, |
29 | @@ -96,7 +97,6 @@ |
30 | self._revision_id_to_revno_cache = None |
31 | self._partial_revision_id_to_revno_cache = {} |
32 | self._partial_revision_history_cache = [] |
33 | - self._tags_bytes = None |
34 | self._last_revision_info_cache = None |
35 | self._master_branch_cache = None |
36 | self._merge_sorted_revisions_cache = None |
37 | @@ -258,23 +258,6 @@ |
38 | a_branch = Branch.open(url, possible_transports=possible_transports) |
39 | return a_branch.repository |
40 | |
41 | - def _get_tags_bytes(self): |
42 | - """Get the bytes of a serialised tags dict. |
43 | - |
44 | - Note that not all branches support tags, nor do all use the same tags |
45 | - logic: this method is specific to BasicTags. Other tag implementations |
46 | - may use the same method name and behave differently, safely, because |
47 | - of the double-dispatch via |
48 | - format.make_tags->tags_instance->get_tags_dict. |
49 | - |
50 | - :return: The bytes of the tags file. |
51 | - :seealso: Branch._set_tags_bytes. |
52 | - """ |
53 | - with self.lock_read(): |
54 | - if self._tags_bytes is None: |
55 | - self._tags_bytes = self._transport.get_bytes('tags') |
56 | - return self._tags_bytes |
57 | - |
58 | def _get_nick(self, local=False, possible_transports=None): |
59 | config = self.get_config() |
60 | # explicit overrides master, but don't look for master if local is True |
61 | @@ -908,15 +891,6 @@ |
62 | if_present_ids=tags_to_fetch, find_ghosts=True).execute() |
63 | self.repository.fetch(old_repository, fetch_spec=fetch_spec) |
64 | |
65 | - def _set_tags_bytes(self, bytes): |
66 | - """Mirror method for _get_tags_bytes. |
67 | - |
68 | - :seealso: Branch._get_tags_bytes. |
69 | - """ |
70 | - with self.lock_write(): |
71 | - self._tags_bytes = bytes |
72 | - return self._transport.put_bytes('tags', bytes) |
73 | - |
74 | def _cache_revision_history(self, rev_history): |
75 | """Set the cached revision history to rev_history. |
76 | |
77 | @@ -952,7 +926,6 @@ |
78 | self._merge_sorted_revisions_cache = None |
79 | self._partial_revision_history_cache = [] |
80 | self._partial_revision_id_to_revno_cache = {} |
81 | - self._tags_bytes = None |
82 | |
83 | def _gen_revision_history(self): |
84 | """Return sequence of revision hashes on to this branch. |
85 | @@ -1513,6 +1486,13 @@ |
86 | if_present_fetch.discard(_mod_revision.NULL_REVISION) |
87 | return must_fetch, if_present_fetch |
88 | |
89 | + def create_memorytree(self): |
90 | + """Create a memory tree for this branch. |
91 | + |
92 | + :return: An in-memory MutableTree instance |
93 | + """ |
94 | + return memorytree.MemoryTree.create_on_branch(self) |
95 | + |
96 | |
97 | class BranchFormat(controldir.ControlComponentFormat): |
98 | """An encapsulation of the initialization and open routines for a format. |
99 | |
100 | === modified file 'breezy/branchbuilder.py' |
101 | --- breezy/branchbuilder.py 2017-11-19 18:35:20 +0000 |
102 | +++ breezy/branchbuilder.py 2018-03-24 17:11:56 +0000 |
103 | @@ -112,7 +112,7 @@ |
104 | if base_id != self._branch.last_revision(): |
105 | self._move_branch_pointer(base_id, |
106 | allow_leftmost_as_ghost=allow_leftmost_as_ghost) |
107 | - tree = memorytree.MemoryTree.create_on_branch(self._branch) |
108 | + tree = self._branch.create_memorytree() |
109 | tree.lock_write() |
110 | try: |
111 | if parent_ids is not None: |
112 | @@ -157,7 +157,7 @@ |
113 | # We are cheating a little bit here, and locking the new tree |
114 | # before the old tree is unlocked. But that way the branch stays |
115 | # locked throughout. |
116 | - new_tree = memorytree.MemoryTree.create_on_branch(self._branch) |
117 | + new_tree = self._branch.create_memorytree() |
118 | new_tree.lock_write() |
119 | self._tree.unlock() |
120 | self._tree = new_tree |
121 | @@ -172,7 +172,7 @@ |
122 | if self._tree is not None: |
123 | raise AssertionError('You cannot start a new series while a' |
124 | ' series is already going.') |
125 | - self._tree = memorytree.MemoryTree.create_on_branch(self._branch) |
126 | + self._tree = self._branch.create_memorytree() |
127 | self._tree.lock_write() |
128 | |
129 | def finish_series(self): |
130 | @@ -223,7 +223,7 @@ |
131 | if self._tree is not None: |
132 | tree = self._tree |
133 | else: |
134 | - tree = memorytree.MemoryTree.create_on_branch(self._branch) |
135 | + tree = self._branch.create_memorytree() |
136 | tree.lock_write() |
137 | try: |
138 | if parent_ids is not None: |
139 | |
140 | === modified file 'breezy/builtins.py' |
141 | --- breezy/builtins.py 2018-03-12 05:18:13 +0000 |
142 | +++ breezy/builtins.py 2018-03-24 17:11:56 +0000 |
143 | @@ -53,6 +53,7 @@ |
144 | symbol_versioning, |
145 | timestamp, |
146 | transport, |
147 | + tree as _mod_tree, |
148 | ui, |
149 | urlutils, |
150 | views, |
151 | @@ -960,11 +961,11 @@ |
152 | |
153 | self.add_cleanup(tree.lock_read().unlock) |
154 | if file_list is not None: |
155 | - file_ids = tree.paths2ids(file_list, trees=extra_trees, |
156 | - require_versioned=True) |
157 | + paths = tree.find_related_paths_across_trees( |
158 | + file_list, extra_trees, require_versioned=True) |
159 | # find_ids_across_trees may include some paths that don't |
160 | # exist in 'tree'. |
161 | - entries = tree.iter_entries_by_dir(specific_file_ids=file_ids) |
162 | + entries = tree.iter_entries_by_dir(specific_files=paths) |
163 | else: |
164 | entries = tree.iter_entries_by_dir() |
165 | |
166 | @@ -4776,29 +4777,27 @@ |
167 | " merges. Not cherrypicking or" |
168 | " multi-merges.")) |
169 | repository = tree.branch.repository |
170 | - interesting_ids = None |
171 | + interesting_files = None |
172 | new_conflicts = [] |
173 | conflicts = tree.conflicts() |
174 | if file_list is not None: |
175 | - interesting_ids = set() |
176 | + interesting_files = set() |
177 | for filename in file_list: |
178 | - file_id = tree.path2id(filename) |
179 | - if file_id is None: |
180 | + if not tree.is_versioned(filename): |
181 | raise errors.NotVersionedError(filename) |
182 | - interesting_ids.add(file_id) |
183 | - if tree.kind(filename, file_id) != "directory": |
184 | + interesting_files.add(filename) |
185 | + if tree.kind(filename) != "directory": |
186 | continue |
187 | |
188 | - # FIXME: Support nested trees |
189 | - for name, ie in tree.root_inventory.iter_entries(file_id): |
190 | - interesting_ids.add(ie.file_id) |
191 | + for path, ie in tree.iter_entries_by_dir(specific_files=[filename]): |
192 | + interesting_files.add(path) |
193 | new_conflicts = conflicts.select_conflicts(tree, file_list)[0] |
194 | else: |
195 | # Remerge only supports resolving contents conflicts |
196 | allowed_conflicts = ('text conflict', 'contents conflict') |
197 | restore_files = [c.path for c in conflicts |
198 | if c.typestring in allowed_conflicts] |
199 | - _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids) |
200 | + _mod_merge.transform_tree(tree, tree.basis_tree(), interesting_files) |
201 | tree.set_conflicts(ConflictList(new_conflicts)) |
202 | if file_list is not None: |
203 | restore_files = file_list |
204 | @@ -4815,7 +4814,7 @@ |
205 | tree.set_parent_ids(parents[:1]) |
206 | try: |
207 | merger = _mod_merge.Merger.from_revision_ids(tree, parents[1]) |
208 | - merger.interesting_ids = interesting_ids |
209 | + merger.interesting_files = interesting_files |
210 | merger.merge_type = merge_type |
211 | merger.show_base = show_base |
212 | merger.reprocess = reprocess |
213 | |
214 | === modified file 'breezy/bzr/branch.py' |
215 | --- breezy/bzr/branch.py 2017-11-12 18:17:03 +0000 |
216 | +++ breezy/bzr/branch.py 2018-03-24 17:11:56 +0000 |
217 | @@ -97,6 +97,7 @@ |
218 | self.repository = _repository |
219 | self.conf_store = None |
220 | Branch.__init__(self, possible_transports) |
221 | + self._tags_bytes = None |
222 | |
223 | def __str__(self): |
224 | return '%s(%s)' % (self.__class__.__name__, self.user_url) |
225 | @@ -402,6 +403,36 @@ |
226 | self._format._update_feature_flags(updated_flags) |
227 | self.control_transport.put_bytes('format', self._format.as_string()) |
228 | |
229 | + def _get_tags_bytes(self): |
230 | + """Get the bytes of a serialised tags dict. |
231 | + |
232 | + Note that not all branches support tags, nor do all use the same tags |
233 | + logic: this method is specific to BasicTags. Other tag implementations |
234 | + may use the same method name and behave differently, safely, because |
235 | + of the double-dispatch via |
236 | + format.make_tags->tags_instance->get_tags_dict. |
237 | + |
238 | + :return: The bytes of the tags file. |
239 | + :seealso: Branch._set_tags_bytes. |
240 | + """ |
241 | + with self.lock_read(): |
242 | + if self._tags_bytes is None: |
243 | + self._tags_bytes = self._transport.get_bytes('tags') |
244 | + return self._tags_bytes |
245 | + |
246 | + def _set_tags_bytes(self, bytes): |
247 | + """Mirror method for _get_tags_bytes. |
248 | + |
249 | + :seealso: Branch._get_tags_bytes. |
250 | + """ |
251 | + with self.lock_write(): |
252 | + self._tags_bytes = bytes |
253 | + return self._transport.put_bytes('tags', bytes) |
254 | + |
255 | + def _clear_cached_state(self): |
256 | + super(BzrBranch, self)._clear_cached_state() |
257 | + self._tags_bytes = None |
258 | + |
259 | |
260 | class BzrBranch8(BzrBranch): |
261 | """A branch that stores tree-reference locations.""" |
262 | |
263 | === modified file 'breezy/bzr/inventory.py' |
264 | --- breezy/bzr/inventory.py 2018-03-10 15:17:30 +0000 |
265 | +++ breezy/bzr/inventory.py 2018-03-24 17:11:56 +0000 |
266 | @@ -720,12 +720,12 @@ |
267 | |
268 | def _preload_cache(self): |
269 | """Populate any caches, we are about to access all items. |
270 | - |
271 | + |
272 | The default implementation does nothing, because CommonInventory doesn't |
273 | have a cache. |
274 | """ |
275 | pass |
276 | - |
277 | + |
278 | def iter_entries_by_dir(self, from_dir=None, specific_file_ids=None, |
279 | yield_parents=False): |
280 | """Iterate over the entries in a directory first order. |
281 | |
282 | === modified file 'breezy/bzr/inventorytree.py' |
283 | --- breezy/bzr/inventorytree.py 2018-03-12 05:18:13 +0000 |
284 | +++ breezy/bzr/inventorytree.py 2018-03-24 17:11:56 +0000 |
285 | @@ -77,7 +77,8 @@ |
286 | adjusted to account for existing elements that match case |
287 | insensitively. |
288 | """ |
289 | - return list(self._yield_canonical_inventory_paths(paths)) |
290 | + with self.lock_read(): |
291 | + return list(self._yield_canonical_inventory_paths(paths)) |
292 | |
293 | def get_canonical_inventory_path(self, path): |
294 | """Returns the first inventory item that case-insensitively matches path. |
295 | @@ -97,7 +98,8 @@ |
296 | :return: The input path adjusted to account for existing elements |
297 | that match case insensitively. |
298 | """ |
299 | - return next(self._yield_canonical_inventory_paths([path])) |
300 | + with self.lock_read(): |
301 | + return next(self._yield_canonical_inventory_paths([path])) |
302 | |
303 | def _yield_canonical_inventory_paths(self, paths): |
304 | for path in paths: |
305 | @@ -112,31 +114,34 @@ |
306 | for elt in bit_iter: |
307 | lelt = elt.lower() |
308 | new_path = None |
309 | - for child in self.iter_children(cur_id): |
310 | - try: |
311 | - # XXX: it seem like if the child is known to be in the |
312 | - # tree, we shouldn't need to go from its id back to |
313 | - # its path -- mbp 2010-02-11 |
314 | - # |
315 | - # XXX: it seems like we could be more efficient |
316 | - # by just directly looking up the original name and |
317 | - # only then searching all children; also by not |
318 | - # chopping paths so much. -- mbp 2010-02-11 |
319 | - child_base = os.path.basename(self.id2path(child)) |
320 | - if (child_base == elt): |
321 | - # if we found an exact match, we can stop now; if |
322 | - # we found an approximate match we need to keep |
323 | - # searching because there might be an exact match |
324 | - # later. |
325 | - cur_id = child |
326 | - new_path = osutils.pathjoin(cur_path, child_base) |
327 | - break |
328 | - elif child_base.lower() == lelt: |
329 | - cur_id = child |
330 | - new_path = osutils.pathjoin(cur_path, child_base) |
331 | - except errors.NoSuchId: |
332 | - # before a change is committed we can see this error... |
333 | - continue |
334 | + try: |
335 | + for child in self.iter_child_entries(self.id2path(cur_id), cur_id): |
336 | + try: |
337 | + # XXX: it seem like if the child is known to be in the |
338 | + # tree, we shouldn't need to go from its id back to |
339 | + # its path -- mbp 2010-02-11 |
340 | + # |
341 | + # XXX: it seems like we could be more efficient |
342 | + # by just directly looking up the original name and |
343 | + # only then searching all children; also by not |
344 | + # chopping paths so much. -- mbp 2010-02-11 |
345 | + child_base = os.path.basename(self.id2path(child.file_id)) |
346 | + if (child_base == elt): |
347 | + # if we found an exact match, we can stop now; if |
348 | + # we found an approximate match we need to keep |
349 | + # searching because there might be an exact match |
350 | + # later. |
351 | + cur_id = child.file_id |
352 | + new_path = osutils.pathjoin(cur_path, child_base) |
353 | + break |
354 | + elif child_base.lower() == lelt: |
355 | + cur_id = child.file_id |
356 | + new_path = osutils.pathjoin(cur_path, child_base) |
357 | + except errors.NoSuchId: |
358 | + # before a change is committed we can see this error... |
359 | + continue |
360 | + except errors.NotADirectory: |
361 | + pass |
362 | if new_path: |
363 | cur_path = new_path |
364 | else: |
365 | @@ -165,6 +170,53 @@ |
366 | file_id = file_id[0] |
367 | return self.root_inventory, file_id |
368 | |
369 | + def find_related_paths_across_trees(self, paths, trees=[], |
370 | + require_versioned=True): |
371 | + """Find related paths in tree corresponding to specified filenames in any |
372 | + of `lookup_trees`. |
373 | + |
374 | + All matches in all trees will be used, and all children of matched |
375 | + directories will be used. |
376 | + |
377 | + :param paths: The filenames to find related paths for (if None, returns |
378 | + None) |
379 | + :param trees: The trees to find file_ids within |
380 | + :param require_versioned: if true, all specified filenames must occur in |
381 | + at least one tree. |
382 | + :return: a set of paths for the specified filenames and their children |
383 | + in `tree` |
384 | + """ |
385 | + if paths is None: |
386 | + return None; |
387 | + file_ids = self.paths2ids( |
388 | + paths, trees, require_versioned=require_versioned) |
389 | + ret = set() |
390 | + for file_id in file_ids: |
391 | + try: |
392 | + ret.add(self.id2path(file_id)) |
393 | + except errors.NoSuchId: |
394 | + pass |
395 | + return ret |
396 | + |
397 | + def paths2ids(self, paths, trees=[], require_versioned=True): |
398 | + """Return all the ids that can be reached by walking from paths. |
399 | + |
400 | + Each path is looked up in this tree and any extras provided in |
401 | + trees, and this is repeated recursively: the children in an extra tree |
402 | + of a directory that has been renamed under a provided path in this tree |
403 | + are all returned, even if none exist under a provided path in this |
404 | + tree, and vice versa. |
405 | + |
406 | + :param paths: An iterable of paths to start converting to ids from. |
407 | + Alternatively, if paths is None, no ids should be calculated and None |
408 | + will be returned. This is offered to make calling the api unconditional |
409 | + for code that *might* take a list of files. |
410 | + :param trees: Additional trees to consider. |
411 | + :param require_versioned: If False, do not raise NotVersionedError if |
412 | + an element of paths is not versioned in this tree and all of trees. |
413 | + """ |
414 | + return find_ids_across_trees(paths, [self] + list(trees), require_versioned) |
415 | + |
416 | def path2id(self, path): |
417 | """Return the id for path in this tree.""" |
418 | with self.lock_read(): |
419 | @@ -217,7 +269,7 @@ |
420 | # are not versioned. |
421 | return set((p for p in paths if self.path2id(p) is None)) |
422 | |
423 | - def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False): |
424 | + def iter_entries_by_dir(self, specific_files=None, yield_parents=False): |
425 | """Walk the tree in 'by_dir' order. |
426 | |
427 | This will yield each entry in the tree as a (path, entry) tuple. |
428 | @@ -226,20 +278,20 @@ |
429 | See Tree.iter_entries_by_dir for details. |
430 | |
431 | :param yield_parents: If True, yield the parents from the root leading |
432 | - down to specific_file_ids that have been requested. This has no |
433 | - impact if specific_file_ids is None. |
434 | + down to specific_files that have been requested. This has no |
435 | + impact if specific_files is None. |
436 | """ |
437 | with self.lock_read(): |
438 | - if specific_file_ids is None: |
439 | - inventory_file_ids = None |
440 | - else: |
441 | + if specific_files is not None: |
442 | inventory_file_ids = [] |
443 | - for tree_file_id in specific_file_ids: |
444 | - inventory, inv_file_id = self._unpack_file_id(tree_file_id) |
445 | + for path in specific_files: |
446 | + inventory, inv_file_id = self._path2inv_file_id(path) |
447 | if not inventory is self.root_inventory: # for now |
448 | raise AssertionError("%r != %r" % ( |
449 | inventory, self.root_inventory)) |
450 | inventory_file_ids.append(inv_file_id) |
451 | + else: |
452 | + inventory_file_ids = None |
453 | # FIXME: Handle nested trees |
454 | return self.root_inventory.iter_entries_by_dir( |
455 | specific_file_ids=inventory_file_ids, yield_parents=yield_parents) |
456 | @@ -248,15 +300,13 @@ |
457 | with self.lock_read(): |
458 | inv, inv_file_id = self._path2inv_file_id(path, file_id) |
459 | try: |
460 | - return iter(viewvalues(inv[inv_file_id].children)) |
461 | + ie = inv[inv_file_id] |
462 | except errors.NoSuchId: |
463 | raise errors.NoSuchFile(path) |
464 | - |
465 | - def iter_children(self, file_id, path=None): |
466 | - """See Tree.iter_children.""" |
467 | - entry = self.iter_entries_by_dir([file_id]).next()[1] |
468 | - for child in viewvalues(getattr(entry, 'children', {})): |
469 | - yield child.file_id |
470 | + else: |
471 | + if ie.kind != 'directory': |
472 | + raise errors.NotADirectory(path) |
473 | + return iter(viewvalues(ie.children)) |
474 | |
475 | def _get_plan_merge_data(self, file_id, other, base): |
476 | from . import versionedfile |
477 | @@ -316,6 +366,84 @@ |
478 | return last_revision |
479 | |
480 | |
481 | +def find_ids_across_trees(filenames, trees, require_versioned=True): |
482 | + """Find the ids corresponding to specified filenames. |
483 | + |
484 | + All matches in all trees will be used, and all children of matched |
485 | + directories will be used. |
486 | + |
487 | + :param filenames: The filenames to find file_ids for (if None, returns |
488 | + None) |
489 | + :param trees: The trees to find file_ids within |
490 | + :param require_versioned: if true, all specified filenames must occur in |
491 | + at least one tree. |
492 | + :return: a set of file ids for the specified filenames and their children. |
493 | + """ |
494 | + if not filenames: |
495 | + return None |
496 | + specified_path_ids = _find_ids_across_trees(filenames, trees, |
497 | + require_versioned) |
498 | + return _find_children_across_trees(specified_path_ids, trees) |
499 | + |
500 | + |
501 | +def _find_ids_across_trees(filenames, trees, require_versioned): |
502 | + """Find the ids corresponding to specified filenames. |
503 | + |
504 | + All matches in all trees will be used, but subdirectories are not scanned. |
505 | + |
506 | + :param filenames: The filenames to find file_ids for |
507 | + :param trees: The trees to find file_ids within |
508 | + :param require_versioned: if true, all specified filenames must occur in |
509 | + at least one tree. |
510 | + :return: a set of file ids for the specified filenames |
511 | + """ |
512 | + not_versioned = [] |
513 | + interesting_ids = set() |
514 | + for tree_path in filenames: |
515 | + not_found = True |
516 | + for tree in trees: |
517 | + file_id = tree.path2id(tree_path) |
518 | + if file_id is not None: |
519 | + interesting_ids.add(file_id) |
520 | + not_found = False |
521 | + if not_found: |
522 | + not_versioned.append(tree_path) |
523 | + if len(not_versioned) > 0 and require_versioned: |
524 | + raise errors.PathsNotVersionedError(not_versioned) |
525 | + return interesting_ids |
526 | + |
527 | + |
528 | +def _find_children_across_trees(specified_ids, trees): |
529 | + """Return a set including specified ids and their children. |
530 | + |
531 | + All matches in all trees will be used. |
532 | + |
533 | + :param trees: The trees to find file_ids within |
534 | + :return: a set containing all specified ids and their children |
535 | + """ |
536 | + interesting_ids = set(specified_ids) |
537 | + pending = interesting_ids |
538 | + # now handle children of interesting ids |
539 | + # we loop so that we handle all children of each id in both trees |
540 | + while len(pending) > 0: |
541 | + new_pending = set() |
542 | + for file_id in pending: |
543 | + for tree in trees: |
544 | + try: |
545 | + path = tree.id2path(file_id) |
546 | + except errors.NoSuchId: |
547 | + continue |
548 | + try: |
549 | + for child in tree.iter_child_entries(path, file_id): |
550 | + if child.file_id not in interesting_ids: |
551 | + new_pending.add(child.file_id) |
552 | + except errors.NotADirectory: |
553 | + pass |
554 | + interesting_ids.update(new_pending) |
555 | + pending = new_pending |
556 | + return interesting_ids |
557 | + |
558 | + |
559 | class MutableInventoryTree(MutableTree, InventoryTree): |
560 | |
561 | def apply_inventory_delta(self, changes): |
562 | @@ -439,10 +567,11 @@ |
563 | return entry[3] |
564 | # Find a 'best fit' match if the filesystem is case-insensitive |
565 | inv_path = self.tree._fix_case_of_inventory_path(inv_path) |
566 | - file_id = self.tree.path2id(inv_path) |
567 | - if file_id is not None: |
568 | - return self.tree.iter_entries_by_dir([file_id]).next()[1] |
569 | - return None |
570 | + try: |
571 | + return self.tree.iter_entries_by_dir( |
572 | + specific_files=[inv_path]).next()[1] |
573 | + except StopIteration: |
574 | + return None |
575 | |
576 | def _convert_to_directory(self, this_ie, inv_path): |
577 | """Convert an entry to a directory. |
578 | @@ -749,7 +878,10 @@ |
579 | |
580 | def kind(self, path, file_id=None): |
581 | inv, inv_file_id = self._path2inv_file_id(path, file_id) |
582 | - return inv[inv_file_id].kind |
583 | + try: |
584 | + return inv[inv_file_id].kind |
585 | + except errors.NoSuchId: |
586 | + raise errors.NoSuchFile(path) |
587 | |
588 | def path_content_summary(self, path): |
589 | """See Tree.path_content_summary.""" |
590 | |
591 | === modified file 'breezy/bzr/remote.py' |
592 | --- breezy/bzr/remote.py 2018-03-12 05:58:54 +0000 |
593 | +++ breezy/bzr/remote.py 2018-03-24 17:11:56 +0000 |
594 | @@ -3441,6 +3441,7 @@ |
595 | |
596 | def _clear_cached_state(self): |
597 | super(RemoteBranch, self)._clear_cached_state() |
598 | + self._tags_bytes = None |
599 | if self._real_branch is not None: |
600 | self._real_branch._clear_cached_state() |
601 | |
602 | |
603 | === modified file 'breezy/bzr/workingtree.py' |
604 | --- breezy/bzr/workingtree.py 2018-03-04 19:11:38 +0000 |
605 | +++ breezy/bzr/workingtree.py 2018-03-24 17:11:56 +0000 |
606 | @@ -652,10 +652,7 @@ |
607 | file_ids are in a WorkingTree if they are in the working inventory |
608 | and the working file exists. |
609 | """ |
610 | - ret = set() |
611 | - for path, ie in self.iter_entries_by_dir(): |
612 | - ret.add(ie.file_id) |
613 | - return ret |
614 | + return {ie.file_id for path, ie in self.iter_entries_by_dir()} |
615 | |
616 | def all_versioned_paths(self): |
617 | return {path for path, ie in self.iter_entries_by_dir()} |
618 | @@ -828,7 +825,7 @@ |
619 | |
620 | try: |
621 | kind = parent_tree.kind(path, file_id) |
622 | - except errors.NoSuchId: |
623 | + except errors.NoSuchFile: |
624 | continue |
625 | if kind != 'file': |
626 | # Note: this is slightly unnecessary, because symlinks and |
627 | @@ -1699,13 +1696,13 @@ |
628 | blocked_parent_ids.add(ie.file_id) |
629 | yield path, ie |
630 | |
631 | - def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False): |
632 | + def iter_entries_by_dir(self, specific_files=None, |
633 | + yield_parents=False): |
634 | """See Tree.iter_entries_by_dir()""" |
635 | # The only trick here is that if we supports_tree_reference then we |
636 | # need to detect if a directory becomes a tree-reference. |
637 | iterator = super(WorkingTree, self).iter_entries_by_dir( |
638 | - specific_file_ids=specific_file_ids, |
639 | - yield_parents=yield_parents) |
640 | + specific_files=specific_files, yield_parents=yield_parents) |
641 | if not self.supports_tree_reference(): |
642 | return iterator |
643 | else: |
644 | |
645 | === modified file 'breezy/bzr/workingtree_4.py' |
646 | --- breezy/bzr/workingtree_4.py 2018-03-12 05:18:13 +0000 |
647 | +++ breezy/bzr/workingtree_4.py 2018-03-24 17:11:56 +0000 |
648 | @@ -1963,7 +1963,7 @@ |
649 | def kind(self, path, file_id=None): |
650 | entry = self._get_entry(file_id=file_id, path=path)[1] |
651 | if entry is None: |
652 | - raise errors.NoSuchId(tree=self, file_id=file_id) |
653 | + raise errors.NoSuchFile(path) |
654 | parent_index = self._get_parent_index() |
655 | return dirstate.DirState._minikind_to_kind[entry[parent_index][0]] |
656 | |
657 | |
658 | === modified file 'breezy/config.py' |
659 | --- breezy/config.py 2017-10-26 11:10:38 +0000 |
660 | +++ breezy/config.py 2018-03-24 17:11:56 +0000 |
661 | @@ -2706,7 +2706,7 @@ |
662 | Whether revisions associated with tags should be fetched. |
663 | """)) |
664 | option_registry.register_lazy( |
665 | - 'bzr.transform.orphan_policy', 'breezy.transform', 'opt_transform_orphan') |
666 | + 'transform.orphan_policy', 'breezy.transform', 'opt_transform_orphan') |
667 | option_registry.register( |
668 | Option('bzr.workingtree.worth_saving_limit', default=10, |
669 | from_unicode=int_from_store, invalid='warning', |
670 | |
671 | === modified file 'breezy/filter_tree.py' |
672 | --- breezy/filter_tree.py 2017-11-12 17:53:35 +0000 |
673 | +++ breezy/filter_tree.py 2018-03-24 17:11:56 +0000 |
674 | @@ -47,7 +47,7 @@ |
675 | def get_file_text(self, path, file_id=None): |
676 | chunks = self.backing_tree.get_file_lines(path, file_id) |
677 | filters = self.filter_stack_callback(path) |
678 | - context = ContentFilterContext(path, self, None) |
679 | + context = ContentFilterContext(path, self) |
680 | contents = filtered_output_bytes(chunks, filters, context) |
681 | content = ''.join(contents) |
682 | return content |
683 | @@ -58,14 +58,14 @@ |
684 | def is_executable(self, path, file_id=None): |
685 | return self.backing_tree.is_executable(path, file_id) |
686 | |
687 | - def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=None): |
688 | + def iter_entries_by_dir(self, specific_files=None, yield_parents=None): |
689 | # NB: This simply returns the parent tree's entries; the length may be |
690 | # wrong but it can't easily be calculated without filtering the whole |
691 | # text. Currently all callers cope with this; perhaps they should be |
692 | # updated to a narrower interface that only provides things guaranteed |
693 | # cheaply available across all trees. -- mbp 20110705 |
694 | return self.backing_tree.iter_entries_by_dir( |
695 | - specific_file_ids=specific_file_ids, |
696 | + specific_files=specific_files, |
697 | yield_parents=yield_parents) |
698 | |
699 | def lock_read(self): |
700 | |
701 | === modified file 'breezy/filters/__init__.py' |
702 | --- breezy/filters/__init__.py 2017-11-12 13:53:51 +0000 |
703 | +++ breezy/filters/__init__.py 2018-03-24 17:11:56 +0000 |
704 | @@ -72,19 +72,16 @@ |
705 | class ContentFilterContext(object): |
706 | """Object providing information that filters can use.""" |
707 | |
708 | - def __init__(self, relpath=None, tree=None, entry=None): |
709 | + def __init__(self, relpath=None, tree=None): |
710 | """Create a context. |
711 | |
712 | :param relpath: the relative path or None if this context doesn't |
713 | support that information. |
714 | :param tree: the Tree providing this file or None if this context |
715 | doesn't support that information. |
716 | - :param entry: the InventoryEntry object if it is already known or |
717 | - None if it should be derived if possible |
718 | """ |
719 | self._relpath = relpath |
720 | self._tree = tree |
721 | - self._entry = entry |
722 | # Cached values |
723 | self._revision_id = None |
724 | self._revision = None |
725 | @@ -97,24 +94,12 @@ |
726 | """Source Tree object.""" |
727 | return self._tree |
728 | |
729 | - def file_id(self): |
730 | - """File-id of file.""" |
731 | - if self._entry is not None: |
732 | - return self._entry.file_id |
733 | - elif self._tree is None: |
734 | - return None |
735 | - else: |
736 | - return self._tree.path2id(self._relpath) |
737 | - |
738 | def revision_id(self): |
739 | """Id of revision that last changed this file.""" |
740 | if self._revision_id is None: |
741 | - if self._entry is not None: |
742 | - self._revision_id = self._entry.revision |
743 | - elif self._tree is not None: |
744 | - file_id = self._tree.path2id(self._relpath) |
745 | - self._entry = self._tree.inventory[file_id] |
746 | - self._revision_id = self._entry.revision |
747 | + if self._tree is not None: |
748 | + self._revision_id = self._tree.get_file_revision( |
749 | + self._relpath) |
750 | return self._revision_id |
751 | |
752 | def revision(self): |
753 | |
754 | === modified file 'breezy/gpg.py' |
755 | --- breezy/gpg.py 2018-03-12 05:59:58 +0000 |
756 | +++ breezy/gpg.py 2018-03-24 17:11:56 +0000 |
757 | @@ -193,12 +193,15 @@ |
758 | try: |
759 | import gpg |
760 | self.context = gpg.Context() |
761 | - self.context.armor = True |
762 | +<<<<<<< TREE |
763 | + self.context.armor = True |
764 | +======= |
765 | + self.context.armor = True |
766 | + self.context.signers = self._get_signing_keys() |
767 | +>>>>>>> MERGE-SOURCE |
768 | except ImportError as error: |
769 | pass # can't use verify() |
770 | |
771 | - self.context.signers = self._get_signing_keys() |
772 | - |
773 | def _get_signing_keys(self): |
774 | import gpg |
775 | keyname = self._config_stack.get('gpg_signing_key') |
776 | |
777 | === modified file 'breezy/log.py' |
778 | --- breezy/log.py 2018-03-12 05:56:13 +0000 |
779 | +++ breezy/log.py 2018-03-24 17:11:56 +0000 |
780 | @@ -64,7 +64,6 @@ |
781 | config, |
782 | controldir, |
783 | diff, |
784 | - errors, |
785 | foreign, |
786 | repository as _mod_repository, |
787 | revision as _mod_revision, |
788 | @@ -74,6 +73,7 @@ |
789 | """) |
790 | |
791 | from . import ( |
792 | + errors, |
793 | lazy_regex, |
794 | registry, |
795 | revisionspec, |
796 | |
797 | === modified file 'breezy/memorytree.py' |
798 | --- breezy/memorytree.py 2018-03-12 02:03:26 +0000 |
799 | +++ breezy/memorytree.py 2018-03-24 17:11:56 +0000 |
800 | @@ -270,7 +270,12 @@ |
801 | # is not relevant to memory tree. Until that is done in unlock by |
802 | # working tree, we cannot share the implementation. |
803 | if file_ids is None: |
804 | - file_ids = {self.path2id(path) for path in paths} |
805 | + file_ids = set() |
806 | + for path in paths: |
807 | + file_id = self.path2id(path) |
808 | + if file_id is None: |
809 | + raise errors.NoSuchFile(path) |
810 | + file_ids.add(file_id) |
811 | for file_id in file_ids: |
812 | if self._inventory.has_id(file_id): |
813 | self._inventory.remove_recursive_id(file_id) |
814 | |
815 | === modified file 'breezy/merge.py' |
816 | --- breezy/merge.py 2018-03-12 05:18:13 +0000 |
817 | +++ breezy/merge.py 2018-03-24 17:11:56 +0000 |
818 | @@ -56,12 +56,13 @@ |
819 | # TODO: Report back as changes are merged in |
820 | |
821 | |
822 | -def transform_tree(from_tree, to_tree, interesting_ids=None): |
823 | +def transform_tree(from_tree, to_tree, interesting_files=None): |
824 | from_tree.lock_tree_write() |
825 | operation = cleanup.OperationWithCleanups(merge_inner) |
826 | operation.add_cleanup(from_tree.unlock) |
827 | operation.run_simple(from_tree.branch, to_tree, from_tree, |
828 | - ignore_zero=True, interesting_ids=interesting_ids, this_tree=from_tree) |
829 | + ignore_zero=True, this_tree=from_tree, |
830 | + interesting_files=interesting_files) |
831 | |
832 | |
833 | class MergeHooks(hooks.Hooks): |
834 | @@ -130,20 +131,6 @@ |
835 | """ |
836 | raise NotImplementedError(self.file_matches) |
837 | |
838 | - def get_filename(self, params, tree): |
839 | - """Lookup the filename (i.e. basename, not path), given a Tree (e.g. |
840 | - self.merger.this_tree) and a MergeFileHookParams. |
841 | - """ |
842 | - return osutils.basename(tree.id2path(params.file_id)) |
843 | - |
844 | - def get_filepath(self, params, tree): |
845 | - """Calculate the path to the file in a tree. |
846 | - |
847 | - :param params: A MergeFileHookParams describing the file to merge |
848 | - :param tree: a Tree, e.g. self.merger.this_tree. |
849 | - """ |
850 | - return tree.id2path(params.file_id) |
851 | - |
852 | def merge_contents(self, params): |
853 | """Merge the contents of a single file.""" |
854 | # Check whether this custom merge logic should be used. |
855 | @@ -216,7 +203,7 @@ |
856 | affected_files = self.default_files |
857 | self.affected_files = affected_files |
858 | if affected_files: |
859 | - filepath = self.get_filepath(params, self.merger.this_tree) |
860 | + filepath = params.this_path |
861 | if filepath in affected_files: |
862 | return True |
863 | return False |
864 | @@ -240,16 +227,21 @@ |
865 | There are some fields hooks can access: |
866 | |
867 | :ivar file_id: the file ID of the file being merged |
868 | + :ivar base_path: Path in base tree |
869 | + :ivar other_path: Path in other tree |
870 | + :ivar this_path: Path in this tree |
871 | :ivar trans_id: the transform ID for the merge of this file |
872 | :ivar this_kind: kind of file_id in 'this' tree |
873 | :ivar other_kind: kind of file_id in 'other' tree |
874 | :ivar winner: one of 'this', 'other', 'conflict' |
875 | """ |
876 | |
877 | - def __init__(self, merger, file_id, trans_id, this_kind, other_kind, |
878 | + def __init__(self, merger, file_id, paths, trans_id, this_kind, other_kind, |
879 | winner): |
880 | self._merger = merger |
881 | self.file_id = file_id |
882 | + self.paths = paths |
883 | + self.base_path, self.other_path, self.this_path = paths |
884 | self.trans_id = trans_id |
885 | self.this_kind = this_kind |
886 | self.other_kind = other_kind |
887 | @@ -262,17 +254,17 @@ |
888 | @decorators.cachedproperty |
889 | def base_lines(self): |
890 | """The lines of the 'base' version of the file.""" |
891 | - return self._merger.get_lines(self._merger.base_tree, self.file_id) |
892 | + return self._merger.get_lines(self._merger.base_tree, self.base_path, self.file_id) |
893 | |
894 | @decorators.cachedproperty |
895 | def this_lines(self): |
896 | """The lines of the 'this' version of the file.""" |
897 | - return self._merger.get_lines(self._merger.this_tree, self.file_id) |
898 | + return self._merger.get_lines(self._merger.this_tree, self.this_path, self.file_id) |
899 | |
900 | @decorators.cachedproperty |
901 | def other_lines(self): |
902 | """The lines of the 'other' version of the file.""" |
903 | - return self._merger.get_lines(self._merger.other_tree, self.file_id) |
904 | + return self._merger.get_lines(self._merger.other_tree, self.other_path, self.file_id) |
905 | |
906 | |
907 | class Merger(object): |
908 | @@ -295,7 +287,6 @@ |
909 | self.base_tree = base_tree |
910 | self.ignore_zero = False |
911 | self.backup_files = False |
912 | - self.interesting_ids = None |
913 | self.interesting_files = None |
914 | self.show_base = False |
915 | self.reprocess = False |
916 | @@ -610,7 +601,6 @@ |
917 | def make_merger(self): |
918 | kwargs = {'working_tree': self.this_tree, 'this_tree': self.this_tree, |
919 | 'other_tree': self.other_tree, |
920 | - 'interesting_ids': self.interesting_ids, |
921 | 'interesting_files': self.interesting_files, |
922 | 'this_branch': self.this_branch, |
923 | 'other_branch': self.other_branch, |
924 | @@ -722,7 +712,7 @@ |
925 | requires_file_merge_plan = False |
926 | |
927 | def __init__(self, working_tree, this_tree, base_tree, other_tree, |
928 | - interesting_ids=None, reprocess=False, show_base=False, |
929 | + reprocess=False, show_base=False, |
930 | change_reporter=None, interesting_files=None, do_merge=True, |
931 | cherrypick=False, lca_trees=None, this_branch=None, |
932 | other_branch=None): |
933 | @@ -735,30 +725,22 @@ |
934 | :param this_branch: The branch associated with this_tree. Defaults to |
935 | this_tree.branch if not supplied. |
936 | :param other_branch: The branch associated with other_tree, if any. |
937 | - :param interesting_ids: The file_ids of files that should be |
938 | - participate in the merge. May not be combined with |
939 | - interesting_files. |
940 | :param: reprocess If True, perform conflict-reduction processing. |
941 | :param show_base: If True, show the base revision in text conflicts. |
942 | (incompatible with reprocess) |
943 | :param change_reporter: An object that should report changes made |
944 | :param interesting_files: The tree-relative paths of files that should |
945 | participate in the merge. If these paths refer to directories, |
946 | - the contents of those directories will also be included. May not |
947 | - be combined with interesting_ids. If neither interesting_files nor |
948 | - interesting_ids is specified, all files may participate in the |
949 | + the contents of those directories will also be included. If not |
950 | + specified, all files may participate in the |
951 | merge. |
952 | :param lca_trees: Can be set to a dictionary of {revision_id:rev_tree} |
953 | if the ancestry was found to include a criss-cross merge. |
954 | Otherwise should be None. |
955 | """ |
956 | object.__init__(self) |
957 | - if interesting_files is not None and interesting_ids is not None: |
958 | - raise ValueError( |
959 | - 'specify either interesting_ids or interesting_files') |
960 | if this_branch is None: |
961 | this_branch = this_tree.branch |
962 | - self.interesting_ids = interesting_ids |
963 | self.interesting_files = interesting_files |
964 | self.working_tree = working_tree |
965 | self.this_tree = this_tree |
966 | @@ -830,18 +812,18 @@ |
967 | hooks = [factory(self) for factory in factories] + [self] |
968 | self.active_hooks = [hook for hook in hooks if hook is not None] |
969 | with ui.ui_factory.nested_progress_bar() as child_pb: |
970 | - for num, (file_id, changed, parents3, names3, |
971 | + for num, (file_id, changed, paths3, parents3, names3, |
972 | executable3) in enumerate(entries): |
973 | # Try merging each entry |
974 | child_pb.update(gettext('Preparing file merge'), |
975 | num, len(entries)) |
976 | - self._merge_names(file_id, parents3, names3, resolver=resolver) |
977 | + self._merge_names(file_id, paths3, parents3, names3, resolver=resolver) |
978 | if changed: |
979 | - file_status = self._do_merge_contents(file_id) |
980 | + file_status = self._do_merge_contents(paths3, file_id) |
981 | else: |
982 | file_status = 'unmodified' |
983 | - self._merge_executable(file_id, |
984 | - executable3, file_status, resolver=resolver) |
985 | + self._merge_executable(paths3, file_id, executable3, |
986 | + file_status, resolver=resolver) |
987 | self.tt.fixup_new_roots() |
988 | self._finish_computing_transform() |
989 | |
990 | @@ -874,27 +856,32 @@ |
991 | iterator = self.other_tree.iter_changes(self.base_tree, |
992 | specific_files=self.interesting_files, |
993 | extra_trees=[self.this_tree]) |
994 | - this_entries = dict((e.file_id, e) for p, e in |
995 | - self.this_tree.iter_entries_by_dir( |
996 | - self.interesting_ids)) |
997 | + this_interesting_files = self.this_tree.find_related_paths_across_trees( |
998 | + self.interesting_files, trees=[self.other_tree]) |
999 | + this_entries = dict(self.this_tree.iter_entries_by_dir( |
1000 | + specific_files=this_interesting_files)) |
1001 | for (file_id, paths, changed, versioned, parents, names, kind, |
1002 | executable) in iterator: |
1003 | - if (self.interesting_ids is not None and |
1004 | - file_id not in self.interesting_ids): |
1005 | - continue |
1006 | - entry = this_entries.get(file_id) |
1007 | - if entry is not None: |
1008 | - this_name = entry.name |
1009 | - this_parent = entry.parent_id |
1010 | - this_executable = entry.executable |
1011 | + if paths[0] is not None: |
1012 | + this_path = _mod_tree.find_previous_path( |
1013 | + self.base_tree, self.this_tree, paths[0]) |
1014 | + else: |
1015 | + this_path = _mod_tree.find_previous_path( |
1016 | + self.other_tree, self.this_tree, paths[1]) |
1017 | + this_entry = this_entries.get(this_path) |
1018 | + if this_entry is not None: |
1019 | + this_name = this_entry.name |
1020 | + this_parent = this_entry.parent_id |
1021 | + this_executable = this_entry.executable |
1022 | else: |
1023 | this_name = None |
1024 | this_parent = None |
1025 | this_executable = None |
1026 | parents3 = parents + (this_parent,) |
1027 | names3 = names + (this_name,) |
1028 | + paths3 = paths + (this_path, ) |
1029 | executable3 = executable + (this_executable,) |
1030 | - result.append((file_id, changed, parents3, names3, executable3)) |
1031 | + result.append((file_id, changed, paths3, parents3, names3, executable3)) |
1032 | return result |
1033 | |
1034 | def _entries_lca(self): |
1035 | @@ -905,10 +892,11 @@ |
1036 | |
1037 | For the multi-valued entries, the format will be (BASE, [lca1, lca2]) |
1038 | |
1039 | - :return: [(file_id, changed, parents, names, executable)], where: |
1040 | + :return: [(file_id, changed, paths, parents, names, executable)], where: |
1041 | |
1042 | * file_id: Simple file_id of the entry |
1043 | * changed: Boolean, True if the kind or contents changed else False |
1044 | + * paths: ((base, [path, in, lcas]), path_other, path_this) |
1045 | * parents: ((base, [parent_id, in, lcas]), parent_id_other, |
1046 | parent_id_this) |
1047 | * names: ((base, [name, in, lcas]), name_in_other, name_in_this) |
1048 | @@ -919,10 +907,10 @@ |
1049 | lookup_trees = [self.this_tree, self.base_tree] |
1050 | lookup_trees.extend(self._lca_trees) |
1051 | # I think we should include the lca trees as well |
1052 | - interesting_ids = self.other_tree.paths2ids(self.interesting_files, |
1053 | - lookup_trees) |
1054 | + interesting_files = self.other_tree.find_related_paths_across_trees( |
1055 | + self.interesting_files, lookup_trees) |
1056 | else: |
1057 | - interesting_ids = self.interesting_ids |
1058 | + interesting_files = None |
1059 | result = [] |
1060 | walker = _mod_tree.MultiWalker(self.other_tree, self._lca_trees) |
1061 | |
1062 | @@ -932,7 +920,10 @@ |
1063 | # Is this modified at all from any of the other trees? |
1064 | if other_ie is None: |
1065 | other_ie = _none_entry |
1066 | - if interesting_ids is not None and file_id not in interesting_ids: |
1067 | + other_path = None |
1068 | + else: |
1069 | + other_path = self.other_tree.id2path(file_id) |
1070 | + if interesting_files is not None and other_path not in interesting_files: |
1071 | continue |
1072 | |
1073 | # If other_revision is found in any of the lcas, that means this |
1074 | @@ -955,21 +946,30 @@ |
1075 | continue |
1076 | |
1077 | lca_entries = [] |
1078 | + lca_paths = [] |
1079 | for lca_path, lca_ie in lca_values: |
1080 | if lca_ie is None: |
1081 | lca_entries.append(_none_entry) |
1082 | + lca_paths.append(None) |
1083 | else: |
1084 | lca_entries.append(lca_ie) |
1085 | + lca_paths.append(path) |
1086 | |
1087 | try: |
1088 | base_ie = base_inventory[file_id] |
1089 | except errors.NoSuchId: |
1090 | base_ie = _none_entry |
1091 | + base_path = None |
1092 | + else: |
1093 | + base_path = self.base_tree.id2path(file_id) |
1094 | |
1095 | try: |
1096 | this_ie = this_inventory[file_id] |
1097 | except errors.NoSuchId: |
1098 | this_ie = _none_entry |
1099 | + this_path = None |
1100 | + else: |
1101 | + this_path = self.this_tree.id2path(file_id) |
1102 | |
1103 | lca_kinds = [] |
1104 | lca_parent_ids = [] |
1105 | @@ -1000,15 +1000,18 @@ |
1106 | continue |
1107 | content_changed = False |
1108 | elif other_ie.kind is None or other_ie.kind == 'file': |
1109 | - def get_sha1(ie, tree): |
1110 | - if ie.kind != 'file': |
1111 | - return None |
1112 | - return tree.get_file_sha1(tree.id2path(file_id), file_id) |
1113 | - base_sha1 = get_sha1(base_ie, self.base_tree) |
1114 | - lca_sha1s = [get_sha1(ie, tree) for ie, tree |
1115 | - in zip(lca_entries, self._lca_trees)] |
1116 | - this_sha1 = get_sha1(this_ie, self.this_tree) |
1117 | - other_sha1 = get_sha1(other_ie, self.other_tree) |
1118 | + def get_sha1(tree, path): |
1119 | + if path is None: |
1120 | + return None |
1121 | + try: |
1122 | + return tree.get_file_sha1(path, file_id) |
1123 | + except errors.NoSuchFile: |
1124 | + return None |
1125 | + base_sha1 = get_sha1(self.base_tree, base_path) |
1126 | + lca_sha1s = [get_sha1(tree, lca_path) for tree, lca_path |
1127 | + in zip(self._lca_trees, lca_paths)] |
1128 | + this_sha1 = get_sha1(self.this_tree, this_path) |
1129 | + other_sha1 = get_sha1(self.other_tree, other_path) |
1130 | sha1_winner = self._lca_multi_way( |
1131 | (base_sha1, lca_sha1s), other_sha1, this_sha1, |
1132 | allow_overriding_lca=False) |
1133 | @@ -1023,16 +1026,15 @@ |
1134 | if sha1_winner == 'this': |
1135 | content_changed = False |
1136 | elif other_ie.kind == 'symlink': |
1137 | - def get_target(ie, tree): |
1138 | + def get_target(ie, tree, path): |
1139 | if ie.kind != 'symlink': |
1140 | return None |
1141 | - path = tree.id2path(file_id) |
1142 | return tree.get_symlink_target(path, file_id) |
1143 | - base_target = get_target(base_ie, self.base_tree) |
1144 | - lca_targets = [get_target(ie, tree) for ie, tree |
1145 | - in zip(lca_entries, self._lca_trees)] |
1146 | - this_target = get_target(this_ie, self.this_tree) |
1147 | - other_target = get_target(other_ie, self.other_tree) |
1148 | + base_target = get_target(base_ie, self.base_tree, base_path) |
1149 | + lca_targets = [get_target(ie, tree, lca_path) for ie, tree, lca_path |
1150 | + in zip(lca_entries, self._lca_trees, lca_paths)] |
1151 | + this_target = get_target(this_ie, self.this_tree, this_path) |
1152 | + other_target = get_target(other_ie, self.other_tree, other_path) |
1153 | target_winner = self._lca_multi_way( |
1154 | (base_target, lca_targets), |
1155 | other_target, this_target) |
1156 | @@ -1056,6 +1058,8 @@ |
1157 | |
1158 | # If we have gotten this far, that means something has changed |
1159 | result.append((file_id, content_changed, |
1160 | + ((base_path, lca_paths), |
1161 | + other_path, this_path), |
1162 | ((base_ie.parent_id, lca_parent_ids), |
1163 | other_ie.parent_id, this_ie.parent_id), |
1164 | ((base_ie.name, lca_names), |
1165 | @@ -1066,6 +1070,8 @@ |
1166 | return result |
1167 | |
1168 | def write_modified(self, results): |
1169 | + if not self.working_tree.supports_merge_modified(): |
1170 | + return |
1171 | modified_hashes = {} |
1172 | for path in results.modified_paths: |
1173 | wt_relpath = self.working_tree.relpath(path) |
1174 | @@ -1076,10 +1082,7 @@ |
1175 | if hash is None: |
1176 | continue |
1177 | modified_hashes[file_id] = hash |
1178 | - try: |
1179 | - self.working_tree.set_merge_modified(modified_hashes) |
1180 | - except errors.UnsupportedOperation: |
1181 | - pass # Well, whatever. |
1182 | + self.working_tree.set_merge_modified(modified_hashes) |
1183 | |
1184 | @staticmethod |
1185 | def parent(entry, file_id): |
1186 | @@ -1096,33 +1099,30 @@ |
1187 | return entry.name |
1188 | |
1189 | @staticmethod |
1190 | - def contents_sha1(tree, file_id): |
1191 | + def contents_sha1(tree, path, file_id=None): |
1192 | """Determine the sha1 of the file contents (used as a key method).""" |
1193 | try: |
1194 | - path = tree.id2path(file_id) |
1195 | - except errors.NoSuchId: |
1196 | + return tree.get_file_sha1(path, file_id) |
1197 | + except errors.NoSuchFile: |
1198 | return None |
1199 | - return tree.get_file_sha1(path, file_id) |
1200 | |
1201 | @staticmethod |
1202 | - def executable(tree, file_id): |
1203 | + def executable(tree, path, file_id=None): |
1204 | """Determine the executability of a file-id (used as a key method).""" |
1205 | try: |
1206 | - path = tree.id2path(file_id) |
1207 | - except errors.NoSuchId: |
1208 | + if tree.kind(path, file_id) != "file": |
1209 | + return False |
1210 | + except errors.NoSuchFile: |
1211 | return None |
1212 | - if tree.kind(path, file_id) != "file": |
1213 | - return False |
1214 | return tree.is_executable(path, file_id) |
1215 | |
1216 | @staticmethod |
1217 | - def kind(tree, path, file_id): |
1218 | + def kind(tree, path, file_id=None): |
1219 | """Determine the kind of a file-id (used as a key method).""" |
1220 | try: |
1221 | - path = tree.id2path(file_id) |
1222 | - except errors.NoSuchId: |
1223 | + return tree.kind(path, file_id) |
1224 | + except errors.NoSuchFile: |
1225 | return None |
1226 | - return tree.kind(path, file_id) |
1227 | |
1228 | @staticmethod |
1229 | def _three_way(base, other, this): |
1230 | @@ -1209,13 +1209,14 @@ |
1231 | else: |
1232 | names.append(entry.name) |
1233 | parents.append(entry.parent_id) |
1234 | - return self._merge_names(file_id, parents, names, |
1235 | + return self._merge_names(file_id, paths, parents, names, |
1236 | resolver=self._three_way) |
1237 | |
1238 | - def _merge_names(self, file_id, parents, names, resolver): |
1239 | + def _merge_names(self, file_id, paths, parents, names, resolver): |
1240 | """Perform a merge on file_id names and parents""" |
1241 | base_name, other_name, this_name = names |
1242 | base_parent, other_parent, this_parent = parents |
1243 | + unused_base_path, other_path, this_path = paths |
1244 | |
1245 | name_winner = resolver(*names) |
1246 | |
1247 | @@ -1235,7 +1236,7 @@ |
1248 | self._raw_conflicts.append(('path conflict', trans_id, file_id, |
1249 | this_parent, this_name, |
1250 | other_parent, other_name)) |
1251 | - if not self.other_tree.has_id(file_id): |
1252 | + if other_path is None: |
1253 | # it doesn't matter whether the result was 'other' or |
1254 | # 'conflict'-- if it has no file id, we leave it alone. |
1255 | return |
1256 | @@ -1257,12 +1258,10 @@ |
1257 | self.tt.adjust_path(name, parent_trans_id, |
1258 | self.tt.trans_id_file_id(file_id)) |
1259 | |
1260 | - def _do_merge_contents(self, file_id): |
1261 | + def _do_merge_contents(self, paths, file_id): |
1262 | """Performs a merge on file_id contents.""" |
1263 | - def contents_pair(tree): |
1264 | - try: |
1265 | - path = tree.id2path(file_id) |
1266 | - except errors.NoSuchId: |
1267 | + def contents_pair(tree, path): |
1268 | + if path is None: |
1269 | return (None, None) |
1270 | try: |
1271 | kind = tree.kind(path, file_id) |
1272 | @@ -1276,23 +1275,27 @@ |
1273 | contents = None |
1274 | return kind, contents |
1275 | |
1276 | + base_path, other_path, this_path = paths |
1277 | # See SPOT run. run, SPOT, run. |
1278 | # So we're not QUITE repeating ourselves; we do tricky things with |
1279 | # file kind... |
1280 | - base_pair = contents_pair(self.base_tree) |
1281 | - other_pair = contents_pair(self.other_tree) |
1282 | + other_pair = contents_pair(self.other_tree, other_path) |
1283 | + this_pair = contents_pair(self.this_tree, this_path) |
1284 | if self._lca_trees: |
1285 | - this_pair = contents_pair(self.this_tree) |
1286 | - lca_pairs = [contents_pair(tree) for tree in self._lca_trees] |
1287 | + (base_path, lca_paths) = base_path |
1288 | + base_pair = contents_pair(self.base_tree, base_path) |
1289 | + lca_pairs = [contents_pair(tree, path) |
1290 | + for tree, path in zip(self._lca_trees, lca_paths)] |
1291 | winner = self._lca_multi_way((base_pair, lca_pairs), other_pair, |
1292 | this_pair, allow_overriding_lca=False) |
1293 | else: |
1294 | + base_pair = contents_pair(self.base_tree, base_path) |
1295 | if base_pair == other_pair: |
1296 | winner = 'this' |
1297 | else: |
1298 | # We delayed evaluating this_pair as long as we can to avoid |
1299 | # unnecessary sha1 calculation |
1300 | - this_pair = contents_pair(self.this_tree) |
1301 | + this_pair = contents_pair(self.this_tree, this_path) |
1302 | winner = self._three_way(base_pair, other_pair, this_pair) |
1303 | if winner == 'this': |
1304 | # No interesting changes introduced by OTHER |
1305 | @@ -1300,7 +1303,9 @@ |
1306 | # We have a hypothetical conflict, but if we have files, then we |
1307 | # can try to merge the content |
1308 | trans_id = self.tt.trans_id_file_id(file_id) |
1309 | - params = MergeFileHookParams(self, file_id, trans_id, this_pair[0], |
1310 | + params = MergeFileHookParams( |
1311 | + self, file_id, (base_path, other_path, |
1312 | + this_path), trans_id, this_pair[0], |
1313 | other_pair[0], winner) |
1314 | hooks = self.active_hooks |
1315 | hook_status = 'not_applicable' |
1316 | @@ -1324,9 +1329,7 @@ |
1317 | inhibit_content_conflict = False |
1318 | if params.this_kind is None: # file_id is not in THIS |
1319 | # Is the name used for a different file_id ? |
1320 | - dupe_path = self.other_tree.id2path(file_id) |
1321 | - this_id = self.this_tree.path2id(dupe_path) |
1322 | - if this_id is not None: |
1323 | + if self.this_tree.is_versioned(other_path): |
1324 | # Two entries for the same path |
1325 | keep_this = True |
1326 | # versioning the merged file will trigger a duplicate |
1327 | @@ -1334,14 +1337,12 @@ |
1328 | self.tt.version_file(file_id, trans_id) |
1329 | transform.create_from_tree( |
1330 | self.tt, trans_id, self.other_tree, |
1331 | - self.other_tree.id2path(file_id), file_id=file_id, |
1332 | + other_path, file_id=file_id, |
1333 | filter_tree_path=self._get_filter_tree_path(file_id)) |
1334 | inhibit_content_conflict = True |
1335 | elif params.other_kind is None: # file_id is not in OTHER |
1336 | # Is the name used for a different file_id ? |
1337 | - dupe_path = self.this_tree.id2path(file_id) |
1338 | - other_id = self.other_tree.path2id(dupe_path) |
1339 | - if other_id is not None: |
1340 | + if self.other_tree.is_versioned(this_path): |
1341 | # Two entries for the same path again, but here, the other |
1342 | # entry will also be merged. We simply inhibit the |
1343 | # 'content' conflict creation because we know OTHER will |
1344 | @@ -1355,7 +1356,7 @@ |
1345 | self.tt.unversion_file(trans_id) |
1346 | # This is a contents conflict, because none of the available |
1347 | # functions could merge it. |
1348 | - file_group = self._dump_conflicts(name, parent_id, file_id, |
1349 | + file_group = self._dump_conflicts(name, paths, parent_id, file_id, |
1350 | set_version=True) |
1351 | self._raw_conflicts.append(('contents conflict', file_group)) |
1352 | elif hook_status == 'success': |
1353 | @@ -1367,7 +1368,7 @@ |
1354 | self._raw_conflicts.append(('text conflict', trans_id)) |
1355 | name = self.tt.final_name(trans_id) |
1356 | parent_id = self.tt.final_parent(trans_id) |
1357 | - self._dump_conflicts(name, parent_id, file_id) |
1358 | + self._dump_conflicts(name, paths, parent_id, file_id) |
1359 | elif hook_status == 'delete': |
1360 | self.tt.unversion_file(trans_id) |
1361 | result = "deleted" |
1362 | @@ -1377,7 +1378,7 @@ |
1363 | pass |
1364 | else: |
1365 | raise AssertionError('unknown hook_status: %r' % (hook_status,)) |
1366 | - if not self.this_tree.has_id(file_id) and result == "modified": |
1367 | + if not this_path and result == "modified": |
1368 | self.tt.version_file(file_id, trans_id) |
1369 | if not keep_this: |
1370 | # The merge has been performed and produced a new content, so the |
1371 | @@ -1389,14 +1390,14 @@ |
1372 | """Replace this contents with other.""" |
1373 | file_id = merge_hook_params.file_id |
1374 | trans_id = merge_hook_params.trans_id |
1375 | - if self.other_tree.has_id(file_id): |
1376 | + if merge_hook_params.other_path is not None: |
1377 | # OTHER changed the file |
1378 | transform.create_from_tree( |
1379 | self.tt, trans_id, self.other_tree, |
1380 | - self.other_tree.id2path(file_id), file_id=file_id, |
1381 | + merge_hook_params.other_path, file_id=file_id, |
1382 | filter_tree_path=self._get_filter_tree_path(file_id)) |
1383 | return 'done', None |
1384 | - elif self.this_tree.has_id(file_id): |
1385 | + elif merge_hook_params.this_path is not None: |
1386 | # OTHER deleted the file |
1387 | return 'delete', None |
1388 | else: |
1389 | @@ -1417,38 +1418,35 @@ |
1390 | # BASE is a file, or both converted to files, so at least we |
1391 | # have agreement that output should be a file. |
1392 | try: |
1393 | - self.text_merge(merge_hook_params.file_id, |
1394 | - merge_hook_params.trans_id) |
1395 | + self.text_merge(merge_hook_params.trans_id, |
1396 | + merge_hook_params.paths, merge_hook_params.file_id) |
1397 | except errors.BinaryFile: |
1398 | return 'not_applicable', None |
1399 | return 'done', None |
1400 | else: |
1401 | return 'not_applicable', None |
1402 | |
1403 | - def get_lines(self, tree, file_id): |
1404 | + def get_lines(self, tree, path, file_id=None): |
1405 | """Return the lines in a file, or an empty list.""" |
1406 | + if path is None: |
1407 | + return [] |
1408 | try: |
1409 | - path = tree.id2path(file_id) |
1410 | - except errors.NoSuchId: |
1411 | + kind = tree.kind(path, file_id) |
1412 | + except errors.NoSuchFile: |
1413 | return [] |
1414 | else: |
1415 | + if kind != 'file': |
1416 | + return [] |
1417 | return tree.get_file_lines(path, file_id) |
1418 | |
1419 | - def text_merge(self, file_id, trans_id): |
1420 | + def text_merge(self, trans_id, paths, file_id): |
1421 | """Perform a three-way text merge on a file_id""" |
1422 | # it's possible that we got here with base as a different type. |
1423 | # if so, we just want two-way text conflicts. |
1424 | - try: |
1425 | - base_path = self.base_tree.id2path(file_id) |
1426 | - except errors.NoSuchId: |
1427 | - base_lines = [] |
1428 | - else: |
1429 | - if self.base_tree.kind(base_path, file_id) == "file": |
1430 | - base_lines = self.get_lines(self.base_tree, file_id) |
1431 | - else: |
1432 | - base_lines = [] |
1433 | - other_lines = self.get_lines(self.other_tree, file_id) |
1434 | - this_lines = self.get_lines(self.this_tree, file_id) |
1435 | + base_path, other_path, this_path = paths |
1436 | + base_lines = self.get_lines(self.base_tree, base_path, file_id) |
1437 | + other_lines = self.get_lines(self.other_tree, other_path, file_id) |
1438 | + this_lines = self.get_lines(self.this_tree, this_path, file_id) |
1439 | m3 = merge3.Merge3(base_lines, this_lines, other_lines, |
1440 | is_cherrypick=self.cherrypick) |
1441 | start_marker = "!START OF MERGE CONFLICT!" + "I HOPE THIS IS UNIQUE" |
1442 | @@ -1477,7 +1475,7 @@ |
1443 | self._raw_conflicts.append(('text conflict', trans_id)) |
1444 | name = self.tt.final_name(trans_id) |
1445 | parent_id = self.tt.final_parent(trans_id) |
1446 | - file_group = self._dump_conflicts(name, parent_id, file_id, |
1447 | + file_group = self._dump_conflicts(name, paths, parent_id, file_id, |
1448 | this_lines, base_lines, |
1449 | other_lines) |
1450 | file_group.append(trans_id) |
1451 | @@ -1495,7 +1493,7 @@ |
1452 | # Skip the id2path lookup for older formats |
1453 | return None |
1454 | |
1455 | - def _dump_conflicts(self, name, parent_id, file_id, this_lines=None, |
1456 | + def _dump_conflicts(self, name, paths, parent_id, file_id, this_lines=None, |
1457 | base_lines=None, other_lines=None, set_version=False, |
1458 | no_base=False): |
1459 | """Emit conflict files. |
1460 | @@ -1503,10 +1501,11 @@ |
1461 | determined automatically. If set_version is true, the .OTHER, .THIS |
1462 | or .BASE (in that order) will be created as versioned files. |
1463 | """ |
1464 | - data = [('OTHER', self.other_tree, other_lines), |
1465 | - ('THIS', self.this_tree, this_lines)] |
1466 | + base_path, other_path, this_path = paths |
1467 | + data = [('OTHER', self.other_tree, other_path, other_lines), |
1468 | + ('THIS', self.this_tree, this_path, this_lines)] |
1469 | if not no_base: |
1470 | - data.append(('BASE', self.base_tree, base_lines)) |
1471 | + data.append(('BASE', self.base_tree, base_path, base_lines)) |
1472 | |
1473 | # We need to use the actual path in the working tree of the file here, |
1474 | # ignoring the conflict suffixes |
1475 | @@ -1523,12 +1522,8 @@ |
1476 | |
1477 | versioned = False |
1478 | file_group = [] |
1479 | - for suffix, tree, lines in data: |
1480 | - try: |
1481 | - path = tree.id2path(file_id) |
1482 | - except errors.NoSuchId: |
1483 | - pass |
1484 | - else: |
1485 | + for suffix, tree, path, lines in data: |
1486 | + if path is not None: |
1487 | trans_id = self._conflict_file( |
1488 | name, parent_id, path, tree, file_id, suffix, lines, |
1489 | filter_tree_path) |
1490 | @@ -1549,24 +1544,25 @@ |
1491 | filter_tree_path=filter_tree_path) |
1492 | return trans_id |
1493 | |
1494 | - def merge_executable(self, file_id, file_status): |
1495 | + def merge_executable(self, paths, file_id, file_status): |
1496 | """Perform a merge on the execute bit.""" |
1497 | - executable = [self.executable(t, file_id) for t in (self.base_tree, |
1498 | - self.other_tree, self.this_tree)] |
1499 | - self._merge_executable(file_id, executable, file_status, |
1500 | + executable = [self.executable(t, p, file_id) for t, p in zip([self.base_tree, |
1501 | + self.other_tree, self.this_tree], paths)] |
1502 | + self._merge_executable(paths, file_id, executable, file_status, |
1503 | resolver=self._three_way) |
1504 | |
1505 | - def _merge_executable(self, file_id, executable, file_status, |
1506 | + def _merge_executable(self, paths, file_id, executable, file_status, |
1507 | resolver): |
1508 | """Perform a merge on the execute bit.""" |
1509 | base_executable, other_executable, this_executable = executable |
1510 | + base_path, other_path, this_path = paths |
1511 | if file_status == "deleted": |
1512 | return |
1513 | winner = resolver(*executable) |
1514 | if winner == "conflict": |
1515 | # There must be a None in here, if we have a conflict, but we |
1516 | # need executability since file status was not deleted. |
1517 | - if self.executable(self.other_tree, file_id) is None: |
1518 | + if self.executable(self.other_tree, other_path, file_id) is None: |
1519 | winner = "this" |
1520 | else: |
1521 | winner = "other" |
1522 | @@ -1578,11 +1574,11 @@ |
1523 | if winner == "this": |
1524 | executability = this_executable |
1525 | else: |
1526 | - if self.other_tree.has_id(file_id): |
1527 | + if other_path is not None: |
1528 | executability = other_executable |
1529 | - elif self.this_tree.has_id(file_id): |
1530 | + elif this_path is not None: |
1531 | executability = this_executable |
1532 | - elif self.base_tree_has_id(file_id): |
1533 | + elif base_path is not None: |
1534 | executability = base_executable |
1535 | if executability is not None: |
1536 | trans_id = self.tt.trans_id_file_id(file_id) |
1537 | @@ -1696,11 +1692,12 @@ |
1538 | base_lines = None |
1539 | return lines, base_lines |
1540 | |
1541 | - def text_merge(self, file_id, trans_id): |
1542 | + def text_merge(self, trans_id, paths, file_id): |
1543 | """Perform a (weave) text merge for a given file and file-id. |
1544 | If conflicts are encountered, .THIS and .OTHER files will be emitted, |
1545 | and a conflict will be noted. |
1546 | """ |
1547 | + base_path, other_path, this_path = paths |
1548 | lines, base_lines = self._merged_lines(file_id) |
1549 | lines = list(lines) |
1550 | # Note we're checking whether the OUTPUT is binary in this case, |
1551 | @@ -1712,7 +1709,7 @@ |
1552 | self._raw_conflicts.append(('text conflict', trans_id)) |
1553 | name = self.tt.final_name(trans_id) |
1554 | parent_id = self.tt.final_parent(trans_id) |
1555 | - file_group = self._dump_conflicts(name, parent_id, file_id, |
1556 | + file_group = self._dump_conflicts(name, paths, parent_id, file_id, |
1557 | no_base=False, |
1558 | base_lines=base_lines) |
1559 | file_group.append(trans_id) |
1560 | @@ -1731,26 +1728,27 @@ |
1561 | |
1562 | requires_file_merge_plan = False |
1563 | |
1564 | - def dump_file(self, temp_dir, name, tree, file_id): |
1565 | + def dump_file(self, temp_dir, name, tree, path, file_id=None): |
1566 | out_path = osutils.pathjoin(temp_dir, name) |
1567 | with open(out_path, "wb") as out_file: |
1568 | - in_file = tree.get_file(tree.id2path(file_id), file_id) |
1569 | + in_file = tree.get_file(path, file_id=None) |
1570 | for line in in_file: |
1571 | out_file.write(line) |
1572 | return out_path |
1573 | |
1574 | - def text_merge(self, file_id, trans_id): |
1575 | + def text_merge(self, trans_id, paths, file_id): |
1576 | """Perform a diff3 merge using a specified file-id and trans-id. |
1577 | If conflicts are encountered, .BASE, .THIS. and .OTHER conflict files |
1578 | will be dumped, and a will be conflict noted. |
1579 | """ |
1580 | import breezy.patch |
1581 | + base_path, other_path, this_path = paths |
1582 | temp_dir = osutils.mkdtemp(prefix="bzr-") |
1583 | try: |
1584 | new_file = osutils.pathjoin(temp_dir, "new") |
1585 | - this = self.dump_file(temp_dir, "this", self.this_tree, file_id) |
1586 | - base = self.dump_file(temp_dir, "base", self.base_tree, file_id) |
1587 | - other = self.dump_file(temp_dir, "other", self.other_tree, file_id) |
1588 | + this = self.dump_file(temp_dir, "this", self.this_tree, this_path, file_id) |
1589 | + base = self.dump_file(temp_dir, "base", self.base_tree, base_path, file_id) |
1590 | + other = self.dump_file(temp_dir, "other", self.other_tree, other_path, file_id) |
1591 | status = breezy.patch.diff3(new_file, this, base, other) |
1592 | if status not in (0, 1): |
1593 | raise errors.BzrError("Unhandled diff3 exit code") |
1594 | @@ -1759,7 +1757,7 @@ |
1595 | if status == 1: |
1596 | name = self.tt.final_name(trans_id) |
1597 | parent_id = self.tt.final_parent(trans_id) |
1598 | - self._dump_conflicts(name, parent_id, file_id) |
1599 | + self._dump_conflicts(name, paths, parent_id, file_id) |
1600 | self._raw_conflicts.append(('text conflict', trans_id)) |
1601 | finally: |
1602 | osutils.rmtree(temp_dir) |
1603 | @@ -1816,7 +1814,7 @@ |
1604 | self.merge_type = Merge3Merger |
1605 | self.show_base = False |
1606 | self.reprocess = False |
1607 | - self.interesting_ids = None |
1608 | + self.interesting_files = None |
1609 | self.merge_type = _MergeTypeParameterizer(MergeIntoMergeType, |
1610 | target_subdir=self._target_subdir, |
1611 | source_subpath=self._source_subpath) |
1612 | @@ -1878,11 +1876,16 @@ |
1613 | with ui.ui_factory.nested_progress_bar() as child_pb: |
1614 | entries = self._entries_to_incorporate() |
1615 | entries = list(entries) |
1616 | - for num, (entry, parent_id, path) in enumerate(entries): |
1617 | + for num, (entry, parent_id, relpath) in enumerate(entries): |
1618 | child_pb.update(gettext('Preparing file merge'), num, len(entries)) |
1619 | parent_trans_id = self.tt.trans_id_file_id(parent_id) |
1620 | +<<<<<<< TREE |
1621 | trans_id = transform.new_by_entry( |
1622 | self.other_tree.id2path(entry.file_id), self.tt, entry, |
1623 | +======= |
1624 | + path = osutils.pathjoin(self._source_subpath, relpath) |
1625 | + trans_id = transform.new_by_entry(path, self.tt, entry, |
1626 | +>>>>>>> MERGE-SOURCE |
1627 | parent_trans_id, self.other_tree) |
1628 | self._finish_computing_transform() |
1629 | |
1630 | @@ -1928,7 +1931,6 @@ |
1631 | def merge_inner(this_branch, other_tree, base_tree, ignore_zero=False, |
1632 | backup_files=False, |
1633 | merge_type=Merge3Merger, |
1634 | - interesting_ids=None, |
1635 | show_base=False, |
1636 | reprocess=False, |
1637 | other_rev_id=None, |
1638 | @@ -1949,13 +1951,8 @@ |
1639 | change_reporter=change_reporter) |
1640 | merger.backup_files = backup_files |
1641 | merger.merge_type = merge_type |
1642 | - merger.interesting_ids = interesting_ids |
1643 | merger.ignore_zero = ignore_zero |
1644 | - if interesting_files: |
1645 | - if interesting_ids: |
1646 | - raise ValueError('Only supply interesting_ids' |
1647 | - ' or interesting_files') |
1648 | - merger.interesting_files = interesting_files |
1649 | + merger.interesting_files = interesting_files |
1650 | merger.show_base = show_base |
1651 | merger.reprocess = reprocess |
1652 | merger.other_rev_id = other_rev_id |
1653 | |
1654 | === modified file 'breezy/plugins/changelog_merge/changelog_merge.py' |
1655 | --- breezy/plugins/changelog_merge/changelog_merge.py 2018-03-09 19:28:43 +0000 |
1656 | +++ breezy/plugins/changelog_merge/changelog_merge.py 2018-03-24 17:11:56 +0000 |
1657 | @@ -23,6 +23,7 @@ |
1658 | from ... import ( |
1659 | debug, |
1660 | merge, |
1661 | + osutils, |
1662 | urlutils, |
1663 | ) |
1664 | from ...merge3 import Merge3 |
1665 | @@ -63,6 +64,7 @@ |
1666 | |
1667 | name_prefix = "changelog" |
1668 | |
1669 | +<<<<<<< TREE |
1670 | def get_filepath(self, params, tree): |
1671 | """Calculate the path to the file in a tree. |
1672 | |
1673 | @@ -75,6 +77,27 @@ |
1674 | :param tree: a Tree, e.g. self.merger.this_tree. |
1675 | """ |
1676 | return self.get_filename(params, tree) |
1677 | +======= |
1678 | + def file_matches(self, params): |
1679 | + affected_files = self.affected_files |
1680 | + if affected_files is None: |
1681 | + config = self.merger.this_branch.get_config() |
1682 | + # Until bzr provides a better policy for caching the config, we |
1683 | + # just add the part we're interested in to the params to avoid |
1684 | + # reading the config files repeatedly (breezy.conf, location.conf, |
1685 | + # branch.conf). |
1686 | + config_key = self.name_prefix + '_merge_files' |
1687 | + affected_files = config.get_user_option_as_list(config_key) |
1688 | + if affected_files is None: |
1689 | + # If nothing was specified in the config, use the default. |
1690 | + affected_files = self.default_files |
1691 | + self.affected_files = affected_files |
1692 | + if affected_files: |
1693 | + filepath = osutils.basename(params.this_path) |
1694 | + if filepath in affected_files: |
1695 | + return True |
1696 | + return False |
1697 | +>>>>>>> MERGE-SOURCE |
1698 | |
1699 | def merge_text(self, params): |
1700 | """Merge changelog changes. |
1701 | |
1702 | === modified file 'breezy/plugins/changelog_merge/tests/test_changelog_merge.py' |
1703 | --- breezy/plugins/changelog_merge/tests/test_changelog_merge.py 2017-05-21 18:10:28 +0000 |
1704 | +++ breezy/plugins/changelog_merge/tests/test_changelog_merge.py 2018-03-24 17:11:56 +0000 |
1705 | @@ -191,8 +191,9 @@ |
1706 | # won't write the new value to disk where get_user_option can get it). |
1707 | merger.this_branch.get_config().set_user_option( |
1708 | 'changelog_merge_files', 'ChangeLog') |
1709 | - merge_hook_params = merge.MergeFileHookParams(merger, 'clog-id', None, |
1710 | - 'file', 'file', 'conflict') |
1711 | + merge_hook_params = merge.MergeFileHookParams(merger, 'clog-id', |
1712 | + ['ChangeLog', 'ChangeLog', 'ChangeLog'], None, |
1713 | + 'file', 'file', 'conflict') |
1714 | changelog_merger = changelog_merge.ChangeLogMerger(merger) |
1715 | return changelog_merger, merge_hook_params |
1716 | |
1717 | |
1718 | === modified file 'breezy/plugins/launchpad/lp_registration.py' |
1719 | --- breezy/plugins/launchpad/lp_registration.py 2017-09-26 00:55:04 +0000 |
1720 | +++ breezy/plugins/launchpad/lp_registration.py 2018-03-24 17:11:56 +0000 |
1721 | @@ -74,8 +74,7 @@ |
1722 | self.verbose = verbose |
1723 | url = self._scheme + "://" + host + handler |
1724 | request = _urllib2_wrappers.Request("POST", url, request_body) |
1725 | - # FIXME: _urllib2_wrappers will override user-agent with its own |
1726 | - # request.add_header("User-Agent", self.user_agent) |
1727 | + request.add_header("User-Agent", self.user_agent) |
1728 | request.add_header("Content-Type", "text/xml") |
1729 | |
1730 | response = self._opener.open(request) |
1731 | @@ -122,7 +121,7 @@ |
1732 | if transport is None: |
1733 | uri_type = urllib.splittype(self.service_url)[0] |
1734 | transport = XMLRPCTransport(uri_type) |
1735 | - transport.user_agent = 'bzr/%s (xmlrpclib/%s)' \ |
1736 | + transport.user_agent = 'Breezy/%s (xmlrpclib/%s)' \ |
1737 | % (_breezy_version, xmlrpclib.__version__) |
1738 | self.transport = transport |
1739 | |
1740 | |
1741 | === modified file 'breezy/plugins/po_merge/po_merge.py' |
1742 | --- breezy/plugins/po_merge/po_merge.py 2017-05-22 00:56:52 +0000 |
1743 | +++ breezy/plugins/po_merge/po_merge.py 2018-03-24 17:11:56 +0000 |
1744 | @@ -99,7 +99,7 @@ |
1745 | # Return early if there is no options defined |
1746 | return False |
1747 | po_dir = None |
1748 | - po_path = self.get_filepath(params, self.merger.this_tree) |
1749 | + po_path = params.this_path |
1750 | for po_dir in self.po_dirs: |
1751 | glob = osutils.pathjoin(po_dir, self.po_glob) |
1752 | if fnmatch.fnmatch(po_path, glob): |
1753 | |
1754 | === modified file 'breezy/plugins/stats/cmds.py' |
1755 | --- breezy/plugins/stats/cmds.py 2018-02-24 15:50:23 +0000 |
1756 | +++ breezy/plugins/stats/cmds.py 2018-03-24 17:11:56 +0000 |
1757 | @@ -145,7 +145,7 @@ |
1758 | combo_count = {} |
1759 | with ui.ui_factory.nested_progress_bar() as pb: |
1760 | trace.note('getting revisions') |
1761 | - revisions = a_repo.iter_revisions(revids) |
1762 | + revisions = list(a_repo.iter_revisions(revids)) |
1763 | for count, (revid, rev) in enumerate(revisions): |
1764 | pb.update('checking', count, len(revids)) |
1765 | for author in rev.get_apparent_authors(): |
1766 | @@ -155,7 +155,8 @@ |
1767 | email_users.setdefault(email, set()).add(username) |
1768 | combo = (username, email) |
1769 | combo_count[combo] = combo_count.setdefault(combo, 0) + 1 |
1770 | - return revisions, collapse_email_and_users(email_users, combo_count) |
1771 | + return ((rev for (revid, rev) in revisions), |
1772 | + collapse_email_and_users(email_users, combo_count)) |
1773 | |
1774 | |
1775 | def get_info(a_repo, revision): |
1776 | |
1777 | === modified file 'breezy/plugins/stats/test_stats.py' |
1778 | --- breezy/plugins/stats/test_stats.py 2017-06-01 23:52:12 +0000 |
1779 | +++ breezy/plugins/stats/test_stats.py 2018-03-24 17:11:56 +0000 |
1780 | @@ -45,6 +45,7 @@ |
1781 | self.assertEqual({('Fero', ''): ('Fero', ''), |
1782 | ('FERO', ''): ('Fero', ''), |
1783 | }, committers) |
1784 | + self.assertEquals(['1', '2', '3'], sorted([r.revision_id for r in revs])) |
1785 | |
1786 | |
1787 | class TestCollapseByPerson(TestCase): |
1788 | |
1789 | === modified file 'breezy/rename_map.py' |
1790 | --- breezy/rename_map.py 2018-03-12 05:18:13 +0000 |
1791 | +++ breezy/rename_map.py 2018-03-24 17:11:56 +0000 |
1792 | @@ -26,6 +26,7 @@ |
1793 | from .sixish import ( |
1794 | BytesIO, |
1795 | viewitems, |
1796 | + viewvalues, |
1797 | ) |
1798 | from .ui import ui_factory |
1799 | |
1800 | @@ -237,7 +238,14 @@ |
1801 | def _make_inventory_delta(self, matches): |
1802 | delta = [] |
1803 | file_id_matches = dict((f, p) for p, f in viewitems(matches)) |
1804 | - for old_path, entry in self.tree.iter_entries_by_dir(file_id_matches): |
1805 | + file_id_query = [] |
1806 | + for f in viewvalues(matches): |
1807 | + try: |
1808 | + file_id_query.append(self.tree.id2path(f)) |
1809 | + except errors.NoSuchId: |
1810 | + pass |
1811 | + for old_path, entry in self.tree.iter_entries_by_dir( |
1812 | + specific_files=file_id_query): |
1813 | new_path = file_id_matches[entry.file_id] |
1814 | parent_path, new_name = osutils.split(new_path) |
1815 | parent_id = matches.get(parent_path) |
1816 | |
1817 | === modified file 'breezy/tests/__init__.py' |
1818 | --- breezy/tests/__init__.py 2018-02-15 19:38:33 +0000 |
1819 | +++ breezy/tests/__init__.py 2018-03-24 17:11:56 +0000 |
1820 | @@ -2693,7 +2693,7 @@ |
1821 | def make_branch_and_memory_tree(self, relpath, format=None): |
1822 | """Create a branch on the default transport and a MemoryTree for it.""" |
1823 | b = self.make_branch(relpath, format=format) |
1824 | - return memorytree.MemoryTree.create_on_branch(b) |
1825 | + return b.create_memorytree() |
1826 | |
1827 | def make_branch_builder(self, relpath, format=None): |
1828 | branch = self.make_branch(relpath, format=format) |
1829 | |
1830 | === modified file 'breezy/tests/blackbox/test_config.py' |
1831 | --- breezy/tests/blackbox/test_config.py 2017-07-30 18:38:48 +0000 |
1832 | +++ breezy/tests/blackbox/test_config.py 2018-03-24 17:11:56 +0000 |
1833 | @@ -116,20 +116,20 @@ |
1834 | ''') |
1835 | |
1836 | def test_registry_value_all(self): |
1837 | - self.breezy_config.set_user_option('bzr.transform.orphan_policy', |
1838 | + self.breezy_config.set_user_option('transform.orphan_policy', |
1839 | u'move') |
1840 | script.run_script(self, '''\ |
1841 | $ brz config -d tree |
1842 | breezy: |
1843 | [DEFAULT] |
1844 | - bzr.transform.orphan_policy = move |
1845 | + transform.orphan_policy = move |
1846 | ''') |
1847 | |
1848 | def test_registry_value_one(self): |
1849 | - self.breezy_config.set_user_option('bzr.transform.orphan_policy', |
1850 | + self.breezy_config.set_user_option('transform.orphan_policy', |
1851 | u'move') |
1852 | script.run_script(self, '''\ |
1853 | - $ brz config -d tree bzr.transform.orphan_policy |
1854 | + $ brz config -d tree transform.orphan_policy |
1855 | move |
1856 | ''') |
1857 | |
1858 | |
1859 | === modified file 'breezy/tests/matchers.py' |
1860 | --- breezy/tests/matchers.py 2018-03-12 02:33:32 +0000 |
1861 | +++ breezy/tests/matchers.py 2018-03-24 17:11:56 +0000 |
1862 | @@ -184,6 +184,7 @@ |
1863 | return Equals(entries).match(actual) |
1864 | |
1865 | |
1866 | +<<<<<<< TREE |
1867 | class HasPathRelations(Matcher): |
1868 | """Matcher verifies that paths have a relation to those in another tree. |
1869 | |
1870 | @@ -241,6 +242,79 @@ |
1871 | return Equals(entries).match(actual) |
1872 | |
1873 | |
1874 | +======= |
1875 | +class HasPathRelations(Matcher): |
1876 | + """Matcher verifies that paths have a relation to those in another tree. |
1877 | + |
1878 | + :ivar previous_tree: tree to compare to |
1879 | + :ivar previous_entries: List of expected entries, as (path, previous_path) pairs. |
1880 | + """ |
1881 | + |
1882 | + def __init__(self, previous_tree, previous_entries): |
1883 | + Matcher.__init__(self) |
1884 | + self.previous_tree = previous_tree |
1885 | + self.previous_entries = previous_entries |
1886 | + |
1887 | + def get_path_map(self, tree): |
1888 | + """Get the (path, previous_path) pairs for the current tree.""" |
1889 | + with tree.lock_read(), self.previous_tree.lock_read(): |
1890 | + for path, ie in tree.iter_entries_by_dir(): |
1891 | + if tree.supports_rename_tracking(): |
1892 | + previous_path = find_previous_path(tree, self.previous_tree, path) |
1893 | + else: |
1894 | + if self.previous_tree.is_versioned(path): |
1895 | + previous_path = path |
1896 | + else: |
1897 | + previous_path = None |
1898 | + if previous_path: |
1899 | + kind = self.previous_tree.kind(previous_path) |
1900 | + if kind == 'directory': |
1901 | + previous_path += '/' |
1902 | + if ie.parent_id is None: |
1903 | + yield (u"", previous_path) |
1904 | + else: |
1905 | + yield (path+ie.kind_character(), previous_path) |
1906 | + |
1907 | + @staticmethod |
1908 | + def _strip_unreferenced_directories(entries): |
1909 | + """Strip all directories that don't (in)directly contain any files. |
1910 | + |
1911 | + :param entries: List of path strings or (path, previous_path) tuples to process |
1912 | + """ |
1913 | + directories = [] |
1914 | + for entry in entries: |
1915 | + if isinstance(entry, (str, text_type)): |
1916 | + path = entry |
1917 | + else: |
1918 | + path = entry[0] |
1919 | + if not path or path[-1] == "/": |
1920 | + # directory |
1921 | + directories.append((path, entry)) |
1922 | + else: |
1923 | + # Yield the referenced parent directories |
1924 | + for dirpath, direntry in directories: |
1925 | + if osutils.is_inside(dirpath, path): |
1926 | + yield direntry |
1927 | + directories = [] |
1928 | + yield entry |
1929 | + |
1930 | + def __str__(self): |
1931 | + return 'HasPathRelations(%r, %r)' % (self.previous_tree, self.previous_entries) |
1932 | + |
1933 | + def match(self, tree): |
1934 | + actual = list(self.get_path_map(tree)) |
1935 | + if not tree.has_versioned_directories(): |
1936 | + entries = list(self._strip_unreferenced_directories(self.previous_entries)) |
1937 | + else: |
1938 | + entries = self.previous_entries |
1939 | + if not tree.supports_rename_tracking(): |
1940 | + entries = [ |
1941 | + (path, path if self.previous_tree.is_versioned(path) else None) |
1942 | + for (path, previous_path) in entries] |
1943 | + return Equals(entries).match(actual) |
1944 | + |
1945 | + |
1946 | +>>>>>>> MERGE-SOURCE |
1947 | class RevisionHistoryMatches(Matcher): |
1948 | """A matcher that checks if a branch has a specific revision history. |
1949 | |
1950 | |
1951 | === modified file 'breezy/tests/per_branch/test_branch.py' |
1952 | --- breezy/tests/per_branch/test_branch.py 2018-03-07 01:11:19 +0000 |
1953 | +++ breezy/tests/per_branch/test_branch.py 2018-03-24 17:11:56 +0000 |
1954 | @@ -34,6 +34,7 @@ |
1955 | revision, |
1956 | shelf, |
1957 | tests, |
1958 | + tree as _mod_tree, |
1959 | ) |
1960 | from breezy.bzr import ( |
1961 | branch as _mod_bzrbranch, |
1962 | @@ -497,6 +498,10 @@ |
1963 | self.assertFalse(revision.NULL_REVISION in must_fetch) |
1964 | self.assertFalse(revision.NULL_REVISION in should_fetch) |
1965 | |
1966 | + def test_create_memorytree(self): |
1967 | + tree = self.make_branch_and_tree('a') |
1968 | + self.assertIsInstance(tree.branch.create_memorytree(), _mod_tree.Tree) |
1969 | + |
1970 | |
1971 | class TestBranchFormat(per_branch.TestCaseWithBranch): |
1972 | |
1973 | |
1974 | === modified file 'breezy/tests/per_branch/test_commit.py' |
1975 | --- breezy/tests/per_branch/test_commit.py 2018-01-12 08:52:43 +0000 |
1976 | +++ breezy/tests/per_branch/test_commit.py 2018-03-24 17:11:56 +0000 |
1977 | @@ -194,7 +194,8 @@ |
1978 | dir_id = tree.path2id('dir') |
1979 | tree.add('dir/subfile') |
1980 | dir_subfile_id = tree.path2id('dir/subfile') |
1981 | - tree.mkdir('to_be_unversioned') |
1982 | + tree.put_file_bytes_non_atomic('to_be_unversioned', 'blah') |
1983 | + tree.add(['to_be_unversioned']) |
1984 | to_be_unversioned_id = tree.path2id('to_be_unversioned') |
1985 | tree.put_file_bytes_non_atomic('dir/subfile', 'def') |
1986 | revid1 = tree.commit('first revision') |
1987 | @@ -212,11 +213,19 @@ |
1988 | revid2 = tree.commit('second revision') |
1989 | |
1990 | expected_delta = delta.TreeDelta() |
1991 | - expected_delta.added = [('added_dir', added_dir_id, 'directory')] |
1992 | - expected_delta.removed = [('to_be_unversioned', |
1993 | - to_be_unversioned_id, 'directory')] |
1994 | - expected_delta.renamed = [('dir/subfile', 'dir/subfile_renamed', |
1995 | - dir_subfile_id, 'file', False, False)] |
1996 | + if tree.has_versioned_directories(): |
1997 | + expected_delta.added.append(('added_dir', added_dir_id, 'directory')) |
1998 | + if tree.supports_rename_tracking(): |
1999 | + expected_delta.removed = [('to_be_unversioned', |
2000 | + to_be_unversioned_id, 'file')] |
2001 | + expected_delta.renamed = [('dir/subfile', 'dir/subfile_renamed', |
2002 | + dir_subfile_id, 'file', False, False)] |
2003 | + else: |
2004 | + expected_delta.added.append(('dir/subfile_renamed', |
2005 | + tree.path2id('dir/subfile_renamed'), 'file')) |
2006 | + expected_delta.removed = [ |
2007 | + ('dir/subfile', dir_subfile_id, 'file'), |
2008 | + ('to_be_unversioned', to_be_unversioned_id, 'file')] |
2009 | expected_delta.modified=[('rootfile', rootfile_id, 'file', True, |
2010 | False)] |
2011 | self.assertEqual([('pre_commit', 1, revid1, 2, revid2, |
2012 | |
2013 | === modified file 'breezy/tests/per_controldir/test_controldir.py' |
2014 | === modified file 'breezy/tests/per_controldir_colo/test_supported.py' |
2015 | === modified file 'breezy/tests/per_intertree/test_compare.py' |
2016 | --- breezy/tests/per_intertree/test_compare.py 2017-11-21 20:37:41 +0000 |
2017 | +++ breezy/tests/per_intertree/test_compare.py 2018-03-24 17:11:56 +0000 |
2018 | @@ -557,7 +557,9 @@ |
2019 | |
2020 | @staticmethod |
2021 | def get_path_entry(tree, file_id): |
2022 | - iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id]) |
2023 | + with tree.lock_read(): |
2024 | + path = tree.id2path(file_id) |
2025 | + iterator = tree.iter_entries_by_dir(specific_files=[path]) |
2026 | try: |
2027 | return next(iterator) |
2028 | except StopIteration: |
2029 | |
2030 | === modified file 'breezy/tests/per_intertree/test_file_content_matches.py' |
2031 | --- breezy/tests/per_intertree/test_file_content_matches.py 2018-03-09 18:27:46 +0000 |
2032 | +++ breezy/tests/per_intertree/test_file_content_matches.py 2018-03-24 17:11:56 +0000 |
2033 | @@ -32,7 +32,13 @@ |
2034 | tree2.add('file', 'file-id-2') |
2035 | tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2) |
2036 | inter = self.intertree_class(tree1, tree2) |
2037 | - self.assertTrue(inter.file_content_matches('file', 'file')) |
2038 | +<<<<<<< TREE |
2039 | + self.assertTrue(inter.file_content_matches('file', 'file')) |
2040 | +======= |
2041 | + self.assertTrue(inter.file_content_matches( |
2042 | + 'file', 'file', 'file-id-1', 'file-id-2')) |
2043 | + self.assertTrue(inter.file_content_matches('file', 'file')) |
2044 | +>>>>>>> MERGE-SOURCE |
2045 | |
2046 | def test_different_contents_and_same_verifier(self): |
2047 | tree1 = self.make_branch_and_tree('1') |
2048 | @@ -45,4 +51,11 @@ |
2049 | tree2.add('file', 'file-id-2') |
2050 | tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2) |
2051 | inter = self.intertree_class(tree1, tree2) |
2052 | +<<<<<<< TREE |
2053 | self.assertFalse(inter.file_content_matches('file', 'file')) |
2054 | +======= |
2055 | + self.assertFalse(inter.file_content_matches( |
2056 | + 'file', 'file', 'file-id-1', 'file-id-2')) |
2057 | + self.assertFalse(inter.file_content_matches( |
2058 | + 'file', 'file')) |
2059 | +>>>>>>> MERGE-SOURCE |
2060 | |
2061 | === modified file 'breezy/tests/per_repository/test_commit_builder.py' |
2062 | --- breezy/tests/per_repository/test_commit_builder.py 2018-03-09 00:05:39 +0000 |
2063 | +++ breezy/tests/per_repository/test_commit_builder.py 2018-03-24 17:11:56 +0000 |
2064 | @@ -181,7 +181,7 @@ |
2065 | |
2066 | def test_commit_unchanged_root_record_iter_changes(self): |
2067 | tree = self.make_branch_and_tree(".") |
2068 | - old_revision_id = tree.commit('') |
2069 | + old_revision_id = tree.commit('oldrev') |
2070 | tree.lock_write() |
2071 | builder = tree.branch.get_commit_builder([old_revision_id]) |
2072 | try: |
2073 | @@ -190,7 +190,7 @@ |
2074 | # pointless commit. |
2075 | self.assertFalse(builder.any_changes()) |
2076 | builder.finish_inventory() |
2077 | - builder.commit('') |
2078 | + builder.commit('rev') |
2079 | builder_tree = builder.revision_tree() |
2080 | new_root_id = builder_tree.get_root_id() |
2081 | new_root_revision = builder_tree.get_file_revision(u'') |
2082 | @@ -284,8 +284,8 @@ |
2083 | # commiting without changing the root does not change the |
2084 | # last modified except on non-rich-root-repositories. |
2085 | tree = self.make_branch_and_tree('.') |
2086 | - rev1 = tree.commit('') |
2087 | - rev2 = tree.commit('') |
2088 | + rev1 = tree.commit('rev1') |
2089 | + rev2 = tree.commit('rev2') |
2090 | tree1, tree2 = self._get_revtrees(tree, [rev1, rev2]) |
2091 | self.assertEqual(rev1, tree1.get_file_revision(u'')) |
2092 | if tree.branch.repository.supports_rich_root(): |
2093 | @@ -293,14 +293,13 @@ |
2094 | else: |
2095 | self.assertEqual(rev2, tree2.get_file_revision(u'')) |
2096 | |
2097 | - def _add_commit_check_unchanged(self, tree, name, mini_commit=None): |
2098 | + def _add_commit_check_unchanged(self, tree, name): |
2099 | tree.add([name]) |
2100 | - self._commit_check_unchanged(tree, name, tree.path2id(name), |
2101 | - mini_commit=mini_commit) |
2102 | + self._commit_check_unchanged(tree, name, tree.path2id(name)) |
2103 | |
2104 | - def _commit_check_unchanged(self, tree, name, file_id, mini_commit=None): |
2105 | - rev1 = tree.commit('') |
2106 | - rev2 = mini_commit(tree, name, name, False, False) |
2107 | + def _commit_check_unchanged(self, tree, name, file_id): |
2108 | + rev1 = tree.commit('rev1') |
2109 | + rev2 = self.mini_commit_record_iter_changes(tree, name, name, False, False) |
2110 | tree1, tree2 = self._get_revtrees(tree, [rev1, rev2]) |
2111 | self.assertEqual(rev1, tree1.get_file_revision(tree1.id2path(file_id))) |
2112 | self.assertEqual(rev1, tree2.get_file_revision(tree2.id2path(file_id))) |
2113 | @@ -315,8 +314,7 @@ |
2114 | raise tests.TestNotApplicable( |
2115 | 'Format does not support versioned directories') |
2116 | self.build_tree(['dir/']) |
2117 | - self._add_commit_check_unchanged(tree, 'dir', |
2118 | - mini_commit=self.mini_commit_record_iter_changes) |
2119 | + self._add_commit_check_unchanged(tree, 'dir') |
2120 | |
2121 | def test_last_modified_revision_after_commit_dir_contents_unchanged(self): |
2122 | # committing without changing a dir does not change the last modified |
2123 | @@ -325,10 +323,10 @@ |
2124 | self.build_tree(['dir/', 'dir/orig']) |
2125 | tree.add(['dir', 'dir/orig']) |
2126 | dir_id = tree.path2id('dir') |
2127 | - rev1 = tree.commit('') |
2128 | + rev1 = tree.commit('rev1') |
2129 | self.build_tree(['dir/content']) |
2130 | tree.add(['dir/content']) |
2131 | - rev2 = tree.commit('') |
2132 | + rev2 = tree.commit('rev2') |
2133 | tree1, tree2 = self._get_revtrees(tree, [rev1, rev2]) |
2134 | self.assertEqual(rev1, tree1.get_file_revision('dir')) |
2135 | self.assertEqual(rev1, tree2.get_file_revision('dir')) |
2136 | @@ -339,16 +337,14 @@ |
2137 | # committing without changing a file does not change the last modified. |
2138 | tree = self.make_branch_and_tree('.') |
2139 | self.build_tree(['file']) |
2140 | - self._add_commit_check_unchanged(tree, 'file', |
2141 | - mini_commit=self.mini_commit_record_iter_changes) |
2142 | + self._add_commit_check_unchanged(tree, 'file') |
2143 | |
2144 | def test_last_modified_revision_after_commit_link_unchanged(self): |
2145 | # committing without changing a link does not change the last modified. |
2146 | self.requireFeature(features.SymlinkFeature) |
2147 | tree = self.make_branch_and_tree('.') |
2148 | os.symlink('target', 'link') |
2149 | - self._add_commit_check_unchanged(tree, 'link', |
2150 | - mini_commit=self.mini_commit_record_iter_changes) |
2151 | + self._add_commit_check_unchanged(tree, 'link') |
2152 | |
2153 | def test_last_modified_revision_after_commit_reference_unchanged(self): |
2154 | # committing without changing a subtree does not change the last |
2155 | @@ -358,47 +354,47 @@ |
2156 | try: |
2157 | tree.add_reference(subtree) |
2158 | self._commit_check_unchanged(tree, 'reference', |
2159 | - subtree.get_root_id(), |
2160 | - mini_commit=self.mini_commit_record_iter_changes) |
2161 | + subtree.get_root_id()) |
2162 | except errors.UnsupportedOperation: |
2163 | return |
2164 | |
2165 | def _add_commit_renamed_check_changed(self, tree, name, |
2166 | - expect_fs_hash=False, mini_commit=None): |
2167 | + expect_fs_hash=False): |
2168 | def rename(): |
2169 | tree.rename_one(name, 'new_' + name) |
2170 | - self._add_commit_change_check_changed(tree, name, rename, |
2171 | - expect_fs_hash=expect_fs_hash, mini_commit=mini_commit) |
2172 | + self._add_commit_change_check_changed(tree, |
2173 | + (name, 'new_' + name), rename, |
2174 | + expect_fs_hash=expect_fs_hash) |
2175 | |
2176 | - def _commit_renamed_check_changed(self, tree, name, file_id, |
2177 | - expect_fs_hash=False, mini_commit=None): |
2178 | + def _commit_renamed_check_changed(self, tree, name, |
2179 | + expect_fs_hash=False): |
2180 | def rename(): |
2181 | tree.rename_one(name, 'new_' + name) |
2182 | - self._commit_change_check_changed(tree, name, file_id, rename, |
2183 | - expect_fs_hash=expect_fs_hash, mini_commit=mini_commit) |
2184 | + self._commit_change_check_changed(tree, [name, 'new_' + name], |
2185 | + rename, expect_fs_hash=expect_fs_hash) |
2186 | |
2187 | def test_last_modified_revision_after_rename_dir_changes(self): |
2188 | # renaming a dir changes the last modified. |
2189 | tree = self.make_branch_and_tree('.') |
2190 | + if not tree.has_versioned_directories(): |
2191 | + raise tests.TestNotApplicable( |
2192 | + 'Format does not support versioned directories') |
2193 | self.build_tree(['dir/']) |
2194 | - self._add_commit_renamed_check_changed(tree, 'dir', |
2195 | - mini_commit=self.mini_commit_record_iter_changes) |
2196 | + self._add_commit_renamed_check_changed(tree, 'dir') |
2197 | |
2198 | def test_last_modified_revision_after_rename_file_changes(self): |
2199 | # renaming a file changes the last modified. |
2200 | tree = self.make_branch_and_tree('.') |
2201 | self.build_tree(['file']) |
2202 | self._add_commit_renamed_check_changed(tree, 'file', |
2203 | - expect_fs_hash=True, |
2204 | - mini_commit=self.mini_commit_record_iter_changes) |
2205 | + expect_fs_hash=True) |
2206 | |
2207 | def test_last_modified_revision_after_rename_link_changes(self): |
2208 | # renaming a link changes the last modified. |
2209 | self.requireFeature(features.SymlinkFeature) |
2210 | tree = self.make_branch_and_tree('.') |
2211 | os.symlink('target', 'link') |
2212 | - self._add_commit_renamed_check_changed(tree, 'link', |
2213 | - mini_commit=self.mini_commit_record_iter_changes) |
2214 | + self._add_commit_renamed_check_changed(tree, 'link') |
2215 | |
2216 | def test_last_modified_revision_after_rename_ref_changes(self): |
2217 | # renaming a reference changes the last modified. |
2218 | @@ -406,62 +402,58 @@ |
2219 | subtree = self.make_reference('reference') |
2220 | try: |
2221 | tree.add_reference(subtree) |
2222 | - self._commit_renamed_check_changed(tree, 'reference', |
2223 | - subtree.get_root_id(), |
2224 | - mini_commit=self.mini_commit_record_iter_changes) |
2225 | + self._commit_renamed_check_changed(tree, 'reference') |
2226 | except errors.UnsupportedOperation: |
2227 | return |
2228 | |
2229 | def _add_commit_reparent_check_changed(self, tree, name, |
2230 | - expect_fs_hash=False, mini_commit=None): |
2231 | + expect_fs_hash=False): |
2232 | self.build_tree(['newparent/']) |
2233 | tree.add(['newparent']) |
2234 | def reparent(): |
2235 | tree.rename_one(name, 'newparent/new_' + name) |
2236 | - self._add_commit_change_check_changed(tree, name, reparent, |
2237 | - expect_fs_hash=expect_fs_hash, mini_commit=mini_commit) |
2238 | + self._add_commit_change_check_changed( |
2239 | + tree, (name, 'newparent/new_' + name), reparent, |
2240 | + expect_fs_hash=expect_fs_hash) |
2241 | |
2242 | def test_last_modified_revision_after_reparent_dir_changes(self): |
2243 | # reparenting a dir changes the last modified. |
2244 | tree = self.make_branch_and_tree('.') |
2245 | self.build_tree(['dir/']) |
2246 | - self._add_commit_reparent_check_changed(tree, 'dir', |
2247 | - mini_commit=self.mini_commit_record_iter_changes) |
2248 | + self._add_commit_reparent_check_changed(tree, 'dir') |
2249 | |
2250 | def test_last_modified_revision_after_reparent_file_changes(self): |
2251 | # reparenting a file changes the last modified. |
2252 | tree = self.make_branch_and_tree('.') |
2253 | self.build_tree(['file']) |
2254 | self._add_commit_reparent_check_changed(tree, 'file', |
2255 | - expect_fs_hash=True, |
2256 | - mini_commit=self.mini_commit_record_iter_changes) |
2257 | + expect_fs_hash=True) |
2258 | |
2259 | def test_last_modified_revision_after_reparent_link_changes(self): |
2260 | # reparenting a link changes the last modified. |
2261 | self.requireFeature(features.SymlinkFeature) |
2262 | tree = self.make_branch_and_tree('.') |
2263 | os.symlink('target', 'link') |
2264 | - self._add_commit_reparent_check_changed(tree, 'link', |
2265 | - mini_commit=self.mini_commit_record_iter_changes) |
2266 | + self._add_commit_reparent_check_changed(tree, 'link') |
2267 | |
2268 | - def _add_commit_change_check_changed(self, tree, name, changer, |
2269 | - expect_fs_hash=False, mini_commit=None): |
2270 | - tree.add([name]) |
2271 | - file_id = tree.path2id(name) |
2272 | - self.assertIsNot(None, file_id) |
2273 | + def _add_commit_change_check_changed(self, tree, names, changer, |
2274 | + expect_fs_hash=False): |
2275 | + tree.add([names[0]]) |
2276 | + self.assertTrue(tree.is_versioned(names[0])) |
2277 | self._commit_change_check_changed( |
2278 | - tree, name, file_id, |
2279 | - changer, expect_fs_hash=expect_fs_hash, mini_commit=mini_commit) |
2280 | + tree, names, |
2281 | + changer, expect_fs_hash=expect_fs_hash) |
2282 | |
2283 | - def _commit_change_check_changed(self, tree, name, file_id, changer, |
2284 | - expect_fs_hash=False, mini_commit=None): |
2285 | - rev1 = tree.commit('') |
2286 | + def _commit_change_check_changed(self, tree, names, changer, |
2287 | + expect_fs_hash=False): |
2288 | + rev1 = tree.commit('rev1') |
2289 | changer() |
2290 | - rev2 = mini_commit(tree, name, tree.id2path(file_id), |
2291 | - expect_fs_hash=expect_fs_hash) |
2292 | + rev2 = self.mini_commit_record_iter_changes( |
2293 | + tree, names[0], names[1], expect_fs_hash=expect_fs_hash) |
2294 | tree1, tree2 = self._get_revtrees(tree, [rev1, rev2]) |
2295 | - self.assertEqual(rev1, tree1.get_file_revision(tree1.id2path(file_id))) |
2296 | - self.assertEqual(rev2, tree2.get_file_revision(tree2.id2path(file_id))) |
2297 | + self.assertEqual(rev1, tree1.get_file_revision(names[0])) |
2298 | + self.assertEqual(rev2, tree2.get_file_revision(names[1])) |
2299 | + file_id = tree1.path2id(names[0]) |
2300 | expected_graph = {} |
2301 | expected_graph[(file_id, rev1)] = () |
2302 | expected_graph[(file_id, rev2)] = ((file_id, rev1),) |
2303 | @@ -488,6 +480,7 @@ |
2304 | # record_iter_changes |
2305 | parent_ids = tree.get_parent_ids() |
2306 | builder = tree.branch.get_commit_builder(parent_ids) |
2307 | +<<<<<<< TREE |
2308 | try: |
2309 | parent_tree = tree.basis_tree() |
2310 | parent_tree.lock_read() |
2311 | @@ -521,6 +514,36 @@ |
2312 | except: |
2313 | builder.abort() |
2314 | raise |
2315 | +======= |
2316 | + try: |
2317 | + parent_tree = tree.basis_tree() |
2318 | + with parent_tree.lock_read(): |
2319 | + changes = list(tree.iter_changes(parent_tree)) |
2320 | + result = list(builder.record_iter_changes(tree, parent_ids[0], |
2321 | + changes)) |
2322 | + file_id = tree.path2id(new_name) |
2323 | + self.assertIsNot(None, file_id) |
2324 | + if expect_fs_hash: |
2325 | + tree_file_stat = tree.get_file_with_stat(new_name) |
2326 | + tree_file_stat[0].close() |
2327 | + self.assertLength(1, result) |
2328 | + result = result[0] |
2329 | + self.assertEqual(result[:2], (file_id, new_name)) |
2330 | + self.assertEqual(result[2][0], tree.get_file_sha1(new_name)) |
2331 | + self.assertEqualStat(result[2][1], tree_file_stat[1]) |
2332 | + else: |
2333 | + self.assertEqual([], result) |
2334 | + builder.finish_inventory() |
2335 | + if tree.branch.repository._format.supports_full_versioned_files: |
2336 | + inv_key = (builder._new_revision_id,) |
2337 | + inv_sha1 = tree.branch.repository.inventories.get_sha1s( |
2338 | + [inv_key])[inv_key] |
2339 | + self.assertEqual(inv_sha1, builder.inv_sha1) |
2340 | + rev2 = builder.commit('rev2') |
2341 | + except BaseException: |
2342 | + builder.abort() |
2343 | + raise |
2344 | +>>>>>>> MERGE-SOURCE |
2345 | delta = builder.get_basis_delta() |
2346 | delta_dict = dict((change[2], change) for change in delta) |
2347 | version_recorded = (file_id in delta_dict and |
2348 | @@ -531,11 +554,20 @@ |
2349 | else: |
2350 | self.assertFalse(version_recorded) |
2351 | |
2352 | +<<<<<<< TREE |
2353 | revtree = builder.revision_tree() |
2354 | new_entry = revtree.iter_entries_by_dir(specific_file_ids=[file_id]).next()[1] |
2355 | |
2356 | +======= |
2357 | + revtree = builder.revision_tree() |
2358 | + new_entry = revtree.iter_entries_by_dir(specific_files=[new_name]).next()[1] |
2359 | + |
2360 | +>>>>>>> MERGE-SOURCE |
2361 | if delta_against_basis: |
2362 | - expected_delta = (name, new_name, file_id, new_entry) |
2363 | + if tree.supports_rename_tracking() or name == new_name: |
2364 | + expected_delta = (name, new_name, file_id, new_entry) |
2365 | + else: |
2366 | + expected_delta = (None, new_name, file_id, new_entry) |
2367 | self.assertEqual(expected_delta, delta_dict[file_id]) |
2368 | else: |
2369 | expected_delta = None |
2370 | @@ -557,9 +589,8 @@ |
2371 | self.build_tree(['file']) |
2372 | def change_file(): |
2373 | tree.put_file_bytes_non_atomic('file', 'new content') |
2374 | - self._add_commit_change_check_changed(tree, 'file', change_file, |
2375 | - expect_fs_hash=True, |
2376 | - mini_commit=self.mini_commit_record_iter_changes) |
2377 | + self._add_commit_change_check_changed(tree, ('file', 'file'), change_file, |
2378 | + expect_fs_hash=True) |
2379 | |
2380 | def _test_last_mod_rev_after_content_link_changes( |
2381 | self, link, target, newtarget): |
2382 | @@ -571,8 +602,7 @@ |
2383 | os.unlink(link) |
2384 | os.symlink(newtarget, link) |
2385 | self._add_commit_change_check_changed( |
2386 | - tree, link, change_link, |
2387 | - mini_commit=self.mini_commit_record_iter_changes) |
2388 | + tree, (link, link), change_link) |
2389 | |
2390 | def test_last_modified_rev_after_content_link_changes(self): |
2391 | self._test_last_mod_rev_after_content_link_changes( |
2392 | @@ -585,24 +615,23 @@ |
2393 | |
2394 | def _commit_sprout(self, tree, name): |
2395 | tree.add([name]) |
2396 | - rev_id = tree.commit('') |
2397 | + rev_id = tree.commit('rev') |
2398 | return rev_id, tree.controldir.sprout('t2').open_workingtree() |
2399 | |
2400 | - def _rename_in_tree(self, tree, name): |
2401 | + def _rename_in_tree(self, tree, name, message): |
2402 | tree.rename_one(name, 'new_' + name) |
2403 | - return tree.commit('') |
2404 | + return tree.commit(message) |
2405 | |
2406 | - def _commit_sprout_rename_merge(self, tree1, name, expect_fs_hash=False, |
2407 | - mini_commit=None): |
2408 | + def _commit_sprout_rename_merge(self, tree1, name, expect_fs_hash=False): |
2409 | """Do a rename in both trees.""" |
2410 | rev1, tree2 = self._commit_sprout(tree1, name) |
2411 | file_id = tree2.path2id(name) |
2412 | self.assertIsNot(None, file_id) |
2413 | # change both sides equally |
2414 | - rev2 = self._rename_in_tree(tree1, name) |
2415 | - rev3 = self._rename_in_tree(tree2, name) |
2416 | + rev2 = self._rename_in_tree(tree1, name, 'rev2') |
2417 | + rev3 = self._rename_in_tree(tree2, name, 'rev3') |
2418 | tree1.merge_from_branch(tree2.branch) |
2419 | - rev4 = mini_commit(tree1, 'new_' + name, 'new_' + name, |
2420 | + rev4 = self.mini_commit_record_iter_changes(tree1, 'new_' + name, 'new_' + name, |
2421 | expect_fs_hash=expect_fs_hash) |
2422 | tree3, = self._get_revtrees(tree1, [rev4]) |
2423 | self.assertEqual(rev4, tree3.get_file_revision(tree3.id2path(file_id))) |
2424 | @@ -620,26 +649,22 @@ |
2425 | raise tests.TestNotApplicable( |
2426 | 'Format does not support versioned directories') |
2427 | self.build_tree(['t1/dir/']) |
2428 | - self._commit_sprout_rename_merge(tree1, 'dir', |
2429 | - mini_commit=self.mini_commit_record_iter_changes) |
2430 | + self._commit_sprout_rename_merge(tree1, 'dir') |
2431 | |
2432 | def test_last_modified_revision_after_merge_file_changes(self): |
2433 | # merge a file changes the last modified. |
2434 | tree1 = self.make_branch_and_tree('t1') |
2435 | self.build_tree(['t1/file']) |
2436 | - self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True, |
2437 | - mini_commit=self.mini_commit_record_iter_changes) |
2438 | + self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True) |
2439 | |
2440 | def test_last_modified_revision_after_merge_link_changes(self): |
2441 | # merge a link changes the last modified. |
2442 | self.requireFeature(features.SymlinkFeature) |
2443 | tree1 = self.make_branch_and_tree('t1') |
2444 | os.symlink('target', 't1/link') |
2445 | - self._commit_sprout_rename_merge(tree1, 'link', |
2446 | - mini_commit=self.mini_commit_record_iter_changes) |
2447 | + self._commit_sprout_rename_merge(tree1, 'link') |
2448 | |
2449 | - def _commit_sprout_rename_merge_converged(self, tree1, name, |
2450 | - mini_commit=None): |
2451 | + def _commit_sprout_rename_merge_converged(self, tree1, name): |
2452 | # Make a merge which just incorporates a change from a branch: |
2453 | # The per-file graph is straight line, and no alteration occurs |
2454 | # in the inventory. |
2455 | @@ -648,11 +673,12 @@ |
2456 | file_id = tree2.path2id(name) |
2457 | self.assertIsNot(None, file_id) |
2458 | # change on the other side to merge back |
2459 | - rev2 = self._rename_in_tree(tree2, name) |
2460 | + rev2 = self._rename_in_tree(tree2, name, 'rev2') |
2461 | tree1.merge_from_branch(tree2.branch) |
2462 | def _check_graph(in_tree, changed_in_tree): |
2463 | - rev3 = mini_commit(in_tree, name, 'new_' + name, False, |
2464 | - delta_against_basis=changed_in_tree) |
2465 | + rev3 = self.mini_commit_record_iter_changes( |
2466 | + in_tree, name, 'new_' + name, False, |
2467 | + delta_against_basis=changed_in_tree) |
2468 | tree3, = self._get_revtrees(in_tree, [rev2]) |
2469 | self.assertEqual( |
2470 | rev2, |
2471 | @@ -666,27 +692,27 @@ |
2472 | # change to name, branch tree1 and give it an unrelated change, then |
2473 | # merge that to t2. |
2474 | other_tree = tree1.controldir.sprout('t3').open_workingtree() |
2475 | - other_rev = other_tree.commit('') |
2476 | + other_rev = other_tree.commit('other_rev') |
2477 | tree2.merge_from_branch(other_tree.branch) |
2478 | _check_graph(tree2, False) |
2479 | |
2480 | - def _commit_sprout_make_merge(self, tree1, make, mini_commit=None): |
2481 | + def _commit_sprout_make_merge(self, tree1, make): |
2482 | # Make a merge which incorporates the addition of a new object to |
2483 | # another branch. The per-file graph shows no additional change |
2484 | # in the merge because its a straight line. |
2485 | - rev1 = tree1.commit('') |
2486 | + rev1 = tree1.commit('rev1') |
2487 | tree2 = tree1.controldir.sprout('t2').open_workingtree() |
2488 | # make and commit on the other side to merge back |
2489 | make('t2/name') |
2490 | tree2.add(['name']) |
2491 | - file_id = tree2.path2id('name') |
2492 | - self.assertIsNot(None, file_id) |
2493 | - rev2 = tree2.commit('') |
2494 | + self.assertTrue(tree2.is_versioned('name')) |
2495 | + rev2 = tree2.commit('rev2') |
2496 | tree1.merge_from_branch(tree2.branch) |
2497 | - rev3 = mini_commit(tree1, None, 'name', False) |
2498 | + rev3 = self.mini_commit_record_iter_changes(tree1, None, 'name', False) |
2499 | tree3, = self._get_revtrees(tree1, [rev2]) |
2500 | # in rev2, name should be only changed in rev2 |
2501 | - self.assertEqual(rev2, tree3.get_file_revision(tree3.id2path(file_id))) |
2502 | + self.assertEqual(rev2, tree3.get_file_revision('name')) |
2503 | + file_id = tree2.path2id('name') |
2504 | expected_graph = {} |
2505 | expected_graph[(file_id, rev2)] = () |
2506 | self.assertFileGraph(expected_graph, tree1, (file_id, rev2)) |
2507 | @@ -698,41 +724,38 @@ |
2508 | raise tests.TestNotApplicable( |
2509 | 'Format does not support versioned directories') |
2510 | self.build_tree(['t1/dir/']) |
2511 | - self._commit_sprout_rename_merge_converged(tree1, 'dir', |
2512 | - mini_commit=self.mini_commit_record_iter_changes) |
2513 | + self._commit_sprout_rename_merge_converged(tree1, 'dir') |
2514 | |
2515 | def test_last_modified_revision_after_converged_merge_file_unchanged(self): |
2516 | # merge a file that changed preserves the last modified. |
2517 | tree1 = self.make_branch_and_tree('t1') |
2518 | self.build_tree(['t1/file']) |
2519 | - self._commit_sprout_rename_merge_converged(tree1, 'file', |
2520 | - mini_commit=self.mini_commit_record_iter_changes) |
2521 | + self._commit_sprout_rename_merge_converged(tree1, 'file') |
2522 | |
2523 | def test_last_modified_revision_after_converged_merge_link_unchanged(self): |
2524 | # merge a link that changed preserves the last modified. |
2525 | self.requireFeature(features.SymlinkFeature) |
2526 | tree1 = self.make_branch_and_tree('t1') |
2527 | os.symlink('target', 't1/link') |
2528 | - self._commit_sprout_rename_merge_converged(tree1, 'link', |
2529 | - mini_commit=self.mini_commit_record_iter_changes) |
2530 | + self._commit_sprout_rename_merge_converged(tree1, 'link') |
2531 | |
2532 | def test_last_modified_revision_after_merge_new_dir_unchanged(self): |
2533 | # merge a new dir does not change the last modified. |
2534 | tree1 = self.make_branch_and_tree('t1') |
2535 | - self._commit_sprout_make_merge(tree1, self.make_dir, |
2536 | - mini_commit=self.mini_commit_record_iter_changes) |
2537 | + if not tree1.has_versioned_directories(): |
2538 | + raise tests.TestNotApplicable( |
2539 | + 'Format does not support versioned directories') |
2540 | + self._commit_sprout_make_merge(tree1, self.make_dir) |
2541 | |
2542 | def test_last_modified_revision_after_merge_new_file_unchanged(self): |
2543 | # merge a new file does not change the last modified. |
2544 | tree1 = self.make_branch_and_tree('t1') |
2545 | - self._commit_sprout_make_merge(tree1, self.make_file, |
2546 | - mini_commit=self.mini_commit_record_iter_changes) |
2547 | + self._commit_sprout_make_merge(tree1, self.make_file) |
2548 | |
2549 | def test_last_modified_revision_after_merge_new_link_unchanged(self): |
2550 | # merge a new link does not change the last modified. |
2551 | tree1 = self.make_branch_and_tree('t1') |
2552 | - self._commit_sprout_make_merge(tree1, self.make_link, |
2553 | - mini_commit=self.mini_commit_record_iter_changes) |
2554 | + self._commit_sprout_make_merge(tree1, self.make_link) |
2555 | |
2556 | def make_dir(self, name): |
2557 | self.build_tree([name + '/']) |
2558 | @@ -749,8 +772,7 @@ |
2559 | tree.commit('foo') |
2560 | return tree |
2561 | |
2562 | - def _check_kind_change(self, make_before, make_after, expect_fs_hash=False, |
2563 | - mini_commit=None): |
2564 | + def _check_kind_change(self, make_before, make_after, expect_fs_hash=False): |
2565 | tree = self.make_branch_and_tree('.') |
2566 | path = 'name' |
2567 | make_before(path) |
2568 | @@ -762,8 +784,8 @@ |
2569 | osutils.delete_any(path) |
2570 | make_after(path) |
2571 | |
2572 | - self._add_commit_change_check_changed(tree, path, change_kind, |
2573 | - expect_fs_hash=expect_fs_hash, mini_commit=mini_commit) |
2574 | + self._add_commit_change_check_changed(tree, (path, path), change_kind, |
2575 | + expect_fs_hash=expect_fs_hash) |
2576 | |
2577 | def test_last_modified_dir_file(self): |
2578 | if not self.repository_format.supports_versioned_directories: |
2579 | @@ -773,8 +795,7 @@ |
2580 | 'format does not support versioned directories') |
2581 | try: |
2582 | self._check_kind_change(self.make_dir, self.make_file, |
2583 | - expect_fs_hash=True, |
2584 | - mini_commit=self.mini_commit_record_iter_changes) |
2585 | + expect_fs_hash=True) |
2586 | except errors.UnsupportedKindChange: |
2587 | raise tests.TestSkipped( |
2588 | "tree does not support changing entry kind from " |
2589 | @@ -787,8 +808,7 @@ |
2590 | raise tests.TestNotApplicable( |
2591 | 'format does not support versioned directories') |
2592 | try: |
2593 | - self._check_kind_change(self.make_dir, self.make_link, |
2594 | - mini_commit=self.mini_commit_record_iter_changes) |
2595 | + self._check_kind_change(self.make_dir, self.make_link) |
2596 | except errors.UnsupportedKindChange: |
2597 | raise tests.TestSkipped( |
2598 | "tree does not support changing entry kind from " |
2599 | @@ -796,8 +816,7 @@ |
2600 | |
2601 | def test_last_modified_link_file(self): |
2602 | self._check_kind_change(self.make_link, self.make_file, |
2603 | - expect_fs_hash=True, |
2604 | - mini_commit=self.mini_commit_record_iter_changes) |
2605 | + expect_fs_hash=True) |
2606 | |
2607 | def test_last_modified_link_dir(self): |
2608 | if not self.repository_format.supports_versioned_directories: |
2609 | @@ -806,8 +825,7 @@ |
2610 | raise tests.TestNotApplicable( |
2611 | 'format does not support versioned directories') |
2612 | |
2613 | - self._check_kind_change(self.make_link, self.make_dir, |
2614 | - mini_commit=self.mini_commit_record_iter_changes) |
2615 | + self._check_kind_change(self.make_link, self.make_dir) |
2616 | |
2617 | def test_last_modified_file_dir(self): |
2618 | if not self.repository_format.supports_versioned_directories: |
2619 | @@ -816,12 +834,10 @@ |
2620 | raise tests.TestNotApplicable( |
2621 | 'format does not support versioned directories') |
2622 | |
2623 | - self._check_kind_change(self.make_file, self.make_dir, |
2624 | - mini_commit=self.mini_commit_record_iter_changes) |
2625 | + self._check_kind_change(self.make_file, self.make_dir) |
2626 | |
2627 | def test_last_modified_file_link(self): |
2628 | - self._check_kind_change(self.make_file, self.make_link, |
2629 | - mini_commit=self.mini_commit_record_iter_changes) |
2630 | + self._check_kind_change(self.make_file, self.make_link) |
2631 | |
2632 | def test_get_commit_builder_with_invalid_revprops(self): |
2633 | branch = self.make_branch('.') |
2634 | |
2635 | === modified file 'breezy/tests/per_repository_vf/test_fileid_involved.py' |
2636 | --- breezy/tests/per_repository_vf/test_fileid_involved.py 2017-11-16 10:35:32 +0000 |
2637 | +++ breezy/tests/per_repository_vf/test_fileid_involved.py 2018-03-24 17:11:56 +0000 |
2638 | @@ -429,10 +429,9 @@ |
2639 | os.chmod() doesn't work on windows. But TreeTransform can mark or |
2640 | unmark a file as executable. |
2641 | """ |
2642 | - file_id = wt.path2id(path) |
2643 | tt = transform.TreeTransform(wt) |
2644 | try: |
2645 | - tt.set_executability(executable, tt.trans_id_tree_file_id(file_id)) |
2646 | + tt.set_executability(executable, tt.trans_id_tree_path(path)) |
2647 | tt.apply() |
2648 | finally: |
2649 | tt.finalize() |
2650 | |
2651 | === modified file 'breezy/tests/per_tree/__init__.py' |
2652 | --- breezy/tests/per_tree/__init__.py 2018-02-21 02:35:42 +0000 |
2653 | +++ breezy/tests/per_tree/__init__.py 2018-03-24 17:11:56 +0000 |
2654 | @@ -277,56 +277,6 @@ |
2655 | tt.apply() |
2656 | return self.workingtree_to_test_tree(tree) |
2657 | |
2658 | - def get_tree_with_utf8(self, tree): |
2659 | - """Generate a tree with a utf8 revision and unicode paths.""" |
2660 | - self._create_tree_with_utf8(tree) |
2661 | - return self.workingtree_to_test_tree(tree) |
2662 | - |
2663 | - def _create_tree_with_utf8(self, tree): |
2664 | - """Generate a tree with a utf8 revision and unicode paths.""" |
2665 | - self.requireFeature(features.UnicodeFilenameFeature) |
2666 | - # We avoid combining characters in file names here, normalization |
2667 | - # checks (as performed by some file systems (OSX) are outside the scope |
2668 | - # of these tests). We use the euro sign \N{Euro Sign} or \u20ac in |
2669 | - # unicode strings or '\xe2\x82\ac' (its utf-8 encoding) in raw strings. |
2670 | - paths = [u'', |
2671 | - u'fo\N{Euro Sign}o', |
2672 | - u'ba\N{Euro Sign}r/', |
2673 | - u'ba\N{Euro Sign}r/ba\N{Euro Sign}z', |
2674 | - ] |
2675 | - # bzr itself does not create unicode file ids, but we want them for |
2676 | - # testing. |
2677 | - file_ids = ['TREE_ROOT', |
2678 | - 'fo\xe2\x82\xaco-id', |
2679 | - 'ba\xe2\x82\xacr-id', |
2680 | - 'ba\xe2\x82\xacz-id', |
2681 | - ] |
2682 | - self.build_tree(paths[1:]) |
2683 | - if tree.get_root_id() is None: |
2684 | - # Some trees do not have a root yet. |
2685 | - tree.add(paths, file_ids) |
2686 | - else: |
2687 | - # Some trees will already have a root |
2688 | - tree.set_root_id(file_ids[0]) |
2689 | - tree.add(paths[1:], file_ids[1:]) |
2690 | - try: |
2691 | - tree.commit(u'in\xedtial', rev_id=u'r\xe9v-1'.encode('utf8')) |
2692 | - except errors.NonAsciiRevisionId: |
2693 | - raise tests.TestSkipped('non-ascii revision ids not supported') |
2694 | - |
2695 | - def get_tree_with_merged_utf8(self, tree): |
2696 | - """Generate a tree with utf8 ancestors.""" |
2697 | - self._create_tree_with_utf8(tree) |
2698 | - tree2 = tree.controldir.sprout('tree2').open_workingtree() |
2699 | - self.build_tree([u'tree2/ba\N{Euro Sign}r/qu\N{Euro Sign}x']) |
2700 | - tree2.add([u'ba\N{Euro Sign}r/qu\N{Euro Sign}x'], |
2701 | - [u'qu\N{Euro Sign}x-id'.encode('utf-8')]) |
2702 | - tree2.commit(u'to m\xe9rge', rev_id=u'r\xe9v-2'.encode('utf8')) |
2703 | - |
2704 | - tree.merge_from_branch(tree2.branch) |
2705 | - tree.commit(u'm\xe9rge', rev_id=u'r\xe9v-3'.encode('utf8')) |
2706 | - return self.workingtree_to_test_tree(tree) |
2707 | - |
2708 | |
2709 | def make_scenarios(transport_server, transport_readonly_server, formats): |
2710 | """Generate test suites for each Tree implementation in breezy. |
2711 | |
2712 | === modified file 'breezy/tests/per_tree/test_inv.py' |
2713 | --- breezy/tests/per_tree/test_inv.py 2017-08-01 01:44:41 +0000 |
2714 | +++ breezy/tests/per_tree/test_inv.py 2018-03-24 17:11:56 +0000 |
2715 | @@ -33,8 +33,8 @@ |
2716 | ) |
2717 | |
2718 | |
2719 | -def get_entry(tree, file_id): |
2720 | - return tree.iter_entries_by_dir([file_id]).next()[1] |
2721 | +def get_entry(tree, path): |
2722 | + return tree.iter_entries_by_dir(specific_files=[path]).next()[1] |
2723 | |
2724 | |
2725 | class TestInventoryWithSymlinks(per_tree.TestCaseWithTree): |
2726 | @@ -52,7 +52,7 @@ |
2727 | raise TestSkipped( |
2728 | 'symlinks not accurately represented in working trees and' |
2729 | ' preview trees') |
2730 | - entry = get_entry(self.tree, self.tree.path2id('symlink')) |
2731 | + entry = get_entry(self.tree, 'symlink') |
2732 | self.assertEqual(entry.symlink_target, 'link-target') |
2733 | |
2734 | def test_symlink_target_tree(self): |
2735 | @@ -64,7 +64,7 @@ |
2736 | self.assertIs(None, self.tree.get_file_size('symlink')) |
2737 | |
2738 | def test_symlink(self): |
2739 | - entry = get_entry(self.tree, self.tree.path2id('symlink')) |
2740 | + entry = get_entry(self.tree, 'symlink') |
2741 | self.assertEqual(entry.kind, 'symlink') |
2742 | self.assertEqual(None, entry.text_size) |
2743 | |
2744 | @@ -76,6 +76,9 @@ |
2745 | self.build_tree(['tree/dir/', 'tree/dir/file']) |
2746 | work_tree.add(['dir', 'dir/file']) |
2747 | tree = self._convert_tree(work_tree) |
2748 | + if not isinstance(tree, InventoryTree): |
2749 | + raise tests.TestNotApplicable( |
2750 | + "test not applicable on non-inventory tests") |
2751 | tree.lock_read() |
2752 | self.addCleanup(tree.unlock) |
2753 | self.assertEqual({tree.path2id('dir'), tree.path2id('dir/file')}, |
2754 | @@ -88,6 +91,9 @@ |
2755 | work_tree.commit('commit old state') |
2756 | work_tree.remove('file') |
2757 | tree = self._convert_tree(work_tree) |
2758 | + if not isinstance(tree, InventoryTree): |
2759 | + raise tests.TestNotApplicable( |
2760 | + "test not applicable on non-inventory tests") |
2761 | tree.lock_read() |
2762 | self.addCleanup(tree.unlock) |
2763 | self.assertEqual(set([]), tree.paths2ids(['file'], |
2764 | |
2765 | === modified file 'breezy/tests/per_tree/test_test_trees.py' |
2766 | --- breezy/tests/per_tree/test_test_trees.py 2018-03-02 16:32:39 +0000 |
2767 | +++ breezy/tests/per_tree/test_test_trees.py 2018-03-24 17:11:56 +0000 |
2768 | @@ -16,9 +16,11 @@ |
2769 | |
2770 | """Tests for the test trees used by the per_tree tests.""" |
2771 | |
2772 | +from breezy import errors |
2773 | from breezy.tests import per_tree |
2774 | from breezy.tests import ( |
2775 | TestNotApplicable, |
2776 | + TestSkipped, |
2777 | features, |
2778 | ) |
2779 | |
2780 | @@ -138,7 +140,10 @@ |
2781 | self.addCleanup(tree.unlock) |
2782 | self.assertEqual([], tree.get_parent_ids()) |
2783 | self.assertEqual([], tree.conflicts()) |
2784 | - self.assertEqual([], list(tree.unknowns())) |
2785 | + if tree.has_versioned_directories(): |
2786 | + self.assertEqual([], list(tree.unknowns())) |
2787 | + else: |
2788 | + self.assertEqual(['b'], list(tree.unknowns())) |
2789 | # __iter__ has no strongly defined order |
2790 | expected_paths = ( |
2791 | ['', 'a'] + |
2792 | @@ -163,25 +168,45 @@ |
2793 | self.addCleanup(tree.unlock) |
2794 | self.assertEqual([], tree.get_parent_ids()) |
2795 | self.assertEqual([], tree.conflicts()) |
2796 | - self.assertEqual([], list(tree.unknowns())) |
2797 | + if tree.has_versioned_directories(): |
2798 | + self.assertEqual([], list(tree.unknowns())) |
2799 | + else: |
2800 | + self.assertEqual(['1top-dir/1dir-in-1topdir'], list(tree.unknowns())) |
2801 | # __iter__ has no strongly defined order |
2802 | tree_root = tree.path2id('') |
2803 | - self.assertEqual( |
2804 | - {tree.path2id(p) for p in [ |
2805 | - '', '0file', '1top-dir', '1top-dir/1dir-in-1topdir', |
2806 | - '1top-dir/0file-in-1topdir', 'symlink', u'2utf\u1234file']}, |
2807 | - set(tree.all_file_ids())) |
2808 | - # note that the order of the paths and fileids is deliberately |
2809 | - # mismatched to ensure that the result order is path based. |
2810 | - self.assertEqual( |
2811 | - [('', 'directory'), |
2812 | - ('0file', 'file'), |
2813 | - ('1top-dir', 'directory'), |
2814 | - (u'2utf\u1234file', 'file'), |
2815 | - ('symlink', 'symlink'), |
2816 | - ('1top-dir/0file-in-1topdir', 'file'), |
2817 | - ('1top-dir/1dir-in-1topdir', 'directory')], |
2818 | - [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2819 | + if tree.has_versioned_directories(): |
2820 | + self.assertEqual( |
2821 | + {tree.path2id(p) for p in [ |
2822 | + '', '0file', '1top-dir', '1top-dir/1dir-in-1topdir', |
2823 | + '1top-dir/0file-in-1topdir', 'symlink', u'2utf\u1234file']}, |
2824 | + set(tree.all_file_ids())) |
2825 | + # note that the order of the paths and fileids is deliberately |
2826 | + # mismatched to ensure that the result order is path based. |
2827 | + self.assertEqual( |
2828 | + [('', 'directory'), |
2829 | + ('0file', 'file'), |
2830 | + ('1top-dir', 'directory'), |
2831 | + (u'2utf\u1234file', 'file'), |
2832 | + ('symlink', 'symlink'), |
2833 | + ('1top-dir/0file-in-1topdir', 'file'), |
2834 | + ('1top-dir/1dir-in-1topdir', 'directory')], |
2835 | + [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2836 | + else: |
2837 | + self.assertEqual( |
2838 | + {tree.path2id(p) for p in [ |
2839 | + '', '0file', '1top-dir', |
2840 | + '1top-dir/0file-in-1topdir', 'symlink', u'2utf\u1234file']}, |
2841 | + set(tree.all_file_ids())) |
2842 | + # note that the order of the paths and fileids is deliberately |
2843 | + # mismatched to ensure that the result order is path based. |
2844 | + self.assertEqual( |
2845 | + [('', 'directory'), |
2846 | + ('0file', 'file'), |
2847 | + ('1top-dir', 'directory'), |
2848 | + (u'2utf\u1234file', 'file'), |
2849 | + ('symlink', 'symlink'), |
2850 | + ('1top-dir/0file-in-1topdir', 'file')], |
2851 | + [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2852 | |
2853 | def test_tree_with_subdirs_and_all_content_types_wo_symlinks(self): |
2854 | # currently this test tree requires unicode. It might be good |
2855 | @@ -192,30 +217,90 @@ |
2856 | self.addCleanup(tree.unlock) |
2857 | self.assertEqual([], tree.get_parent_ids()) |
2858 | self.assertEqual([], tree.conflicts()) |
2859 | - self.assertEqual([], list(tree.unknowns())) |
2860 | + if tree.has_versioned_directories(): |
2861 | + self.assertEqual([], list(tree.unknowns())) |
2862 | + else: |
2863 | + self.assertEqual(['1top-dir/1dir-in-1topdir'], list(tree.unknowns())) |
2864 | # __iter__ has no strongly defined order |
2865 | tree_root = tree.path2id('') |
2866 | - self.assertEqual( |
2867 | - {'', '0file', '1top-dir', '1top-dir/0file-in-1topdir', |
2868 | - '1top-dir/1dir-in-1topdir', u'2utf\u1234file'}, |
2869 | - set(tree.all_versioned_paths())) |
2870 | - # note that the order of the paths and fileids is deliberately |
2871 | - # mismatched to ensure that the result order is path based. |
2872 | - self.assertEqual( |
2873 | - [('', 'directory'), |
2874 | - ('0file', 'file'), |
2875 | - ('1top-dir', 'directory'), |
2876 | - (u'2utf\u1234file', 'file'), |
2877 | - ('1top-dir/0file-in-1topdir', 'file'), |
2878 | - ('1top-dir/1dir-in-1topdir', 'directory')], |
2879 | - [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2880 | + if tree.has_versioned_directories(): |
2881 | + self.assertEqual( |
2882 | + {'', '0file', '1top-dir', '1top-dir/0file-in-1topdir', |
2883 | + '1top-dir/1dir-in-1topdir', u'2utf\u1234file'}, |
2884 | + set(tree.all_versioned_paths())) |
2885 | + # note that the order of the paths and fileids is deliberately |
2886 | + # mismatched to ensure that the result order is path based. |
2887 | + self.assertEqual( |
2888 | + [('', 'directory'), |
2889 | + ('0file', 'file'), |
2890 | + ('1top-dir', 'directory'), |
2891 | + (u'2utf\u1234file', 'file'), |
2892 | + ('1top-dir/0file-in-1topdir', 'file'), |
2893 | + ('1top-dir/1dir-in-1topdir', 'directory')], |
2894 | + [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2895 | + else: |
2896 | + self.assertEqual( |
2897 | + {'', '0file', '1top-dir', '1top-dir/0file-in-1topdir', |
2898 | + u'2utf\u1234file'}, |
2899 | + set(tree.all_versioned_paths())) |
2900 | + # note that the order of the paths and fileids is deliberately |
2901 | + # mismatched to ensure that the result order is path based. |
2902 | + self.assertEqual( |
2903 | + [('', 'directory'), |
2904 | + ('0file', 'file'), |
2905 | + ('1top-dir', 'directory'), |
2906 | + (u'2utf\u1234file', 'file'), |
2907 | + ('1top-dir/0file-in-1topdir', 'file')], |
2908 | + [(path, node.kind) for path, node in tree.iter_entries_by_dir()]) |
2909 | + |
2910 | + def _create_tree_with_utf8(self, tree): |
2911 | + self.requireFeature(features.UnicodeFilenameFeature) |
2912 | + |
2913 | + # We avoid combining characters in file names here, normalization |
2914 | + # checks (as performed by some file systems (OSX) are outside the scope |
2915 | + # of these tests). We use the euro sign \N{Euro Sign} or \u20ac in |
2916 | + # unicode strings or '\xe2\x82\ac' (its utf-8 encoding) in raw strings. |
2917 | + paths = [u'', |
2918 | + u'fo\N{Euro Sign}o', |
2919 | + u'ba\N{Euro Sign}r/', |
2920 | + u'ba\N{Euro Sign}r/ba\N{Euro Sign}z', |
2921 | + ] |
2922 | + # bzr itself does not create unicode file ids, but we want them for |
2923 | + # testing. |
2924 | + file_ids = ['TREE_ROOT', |
2925 | + 'fo\xe2\x82\xaco-id', |
2926 | + 'ba\xe2\x82\xacr-id', |
2927 | + 'ba\xe2\x82\xacz-id', |
2928 | + ] |
2929 | + self.build_tree(paths[1:]) |
2930 | + if tree.get_root_id() is None: |
2931 | + # Some trees do not have a root yet. |
2932 | + tree.add(paths, file_ids) |
2933 | + else: |
2934 | + # Some trees will already have a root |
2935 | + if tree.supports_setting_file_ids(): |
2936 | + tree.set_root_id(file_ids[0]) |
2937 | + tree.add(paths[1:], file_ids[1:]) |
2938 | + else: |
2939 | + tree.add(paths[1:]) |
2940 | + if tree.branch.repository._format.supports_setting_revision_ids: |
2941 | + try: |
2942 | + tree.commit(u'in\xedtial', rev_id=u'r\xe9v-1'.encode('utf8')) |
2943 | + except errors.NonAsciiRevisionId: |
2944 | + raise TestSkipped('non-ascii revision ids not supported') |
2945 | + else: |
2946 | + tree.commit(u'in\xedtial') |
2947 | + |
2948 | + return tree |
2949 | |
2950 | def test_tree_with_utf8(self): |
2951 | tree = self.make_branch_and_tree('.') |
2952 | if not tree.supports_setting_file_ids(): |
2953 | raise TestNotApplicable( |
2954 | 'format does not support custom file ids') |
2955 | - tree = self.get_tree_with_utf8(tree) |
2956 | + self._create_tree_with_utf8(tree) |
2957 | + |
2958 | + tree = self.workingtree_to_test_tree(tree) |
2959 | |
2960 | revision_id = u'r\xe9v-1'.encode('utf8') |
2961 | root_id = 'TREE_ROOT' |
2962 | @@ -228,11 +313,8 @@ |
2963 | (u'ba\N{Euro Sign}r/ba\N{Euro Sign}z', |
2964 | baz_id, bar_id, revision_id), |
2965 | ] |
2966 | - tree.lock_read() |
2967 | - try: |
2968 | + with tree.lock_read(): |
2969 | path_entries = list(tree.iter_entries_by_dir()) |
2970 | - finally: |
2971 | - tree.unlock() |
2972 | |
2973 | for expected, (path, ie) in zip(path_and_ids, path_entries): |
2974 | self.assertEqual(expected[0], path) # Paths should match |
2975 | @@ -258,8 +340,31 @@ |
2976 | self.assertIsInstance(last_revision(), str) |
2977 | |
2978 | def test_tree_with_merged_utf8(self): |
2979 | - tree = self.make_branch_and_tree('.') |
2980 | - tree = self.get_tree_with_merged_utf8(tree) |
2981 | + wt = self.make_branch_and_tree('.') |
2982 | + |
2983 | + self._create_tree_with_utf8(wt) |
2984 | + |
2985 | + tree2 = wt.controldir.sprout('tree2').open_workingtree() |
2986 | + self.build_tree([u'tree2/ba\N{Euro Sign}r/qu\N{Euro Sign}x']) |
2987 | + if wt.supports_setting_file_ids(): |
2988 | + tree2.add([u'ba\N{Euro Sign}r/qu\N{Euro Sign}x'], |
2989 | + [u'qu\N{Euro Sign}x-id'.encode('utf-8')]) |
2990 | + else: |
2991 | + tree2.add([u'ba\N{Euro Sign}r/qu\N{Euro Sign}x']) |
2992 | + if wt.branch.repository._format.supports_setting_revision_ids: |
2993 | + tree2.commit(u'to m\xe9rge', rev_id=u'r\xe9v-2'.encode('utf8')) |
2994 | + else: |
2995 | + tree2.commit(u'to m\xe9rge') |
2996 | + |
2997 | + self.assertTrue(tree2.is_versioned(u'ba\N{Euro Sign}r/qu\N{Euro Sign}x')) |
2998 | + wt.merge_from_branch(tree2.branch) |
2999 | + self.assertTrue(wt.is_versioned(u'ba\N{Euro Sign}r/qu\N{Euro Sign}x')) |
3000 | + |
3001 | + if wt.branch.repository._format.supports_setting_revision_ids: |
3002 | + wt.commit(u'm\xe9rge', rev_id=u'r\xe9v-3'.encode('utf8')) |
3003 | + else: |
3004 | + wt.commit(u'm\xe9rge') |
3005 | + tree = self.workingtree_to_test_tree(wt) |
3006 | |
3007 | revision_id_1 = u'r\xe9v-1'.encode('utf8') |
3008 | revision_id_2 = u'r\xe9v-2'.encode('utf8') |
3009 | @@ -276,21 +381,19 @@ |
3010 | (u'ba\N{Euro Sign}r/qu\N{Euro Sign}x', |
3011 | qux_id, bar_id, revision_id_2), |
3012 | ] |
3013 | - tree.lock_read() |
3014 | - try: |
3015 | + with tree.lock_read(): |
3016 | path_entries = list(tree.iter_entries_by_dir()) |
3017 | - finally: |
3018 | - tree.unlock() |
3019 | |
3020 | for (epath, efid, eparent, erev), (path, ie) in zip(path_and_ids, |
3021 | path_entries): |
3022 | self.assertEqual(epath, path) # Paths should match |
3023 | self.assertIsInstance(path, unicode) |
3024 | - self.assertEqual(efid, ie.file_id) |
3025 | - self.assertIsInstance(ie.file_id, str) |
3026 | - self.assertEqual(eparent, ie.parent_id) |
3027 | + self.assertIsInstance(ie.file_id, bytes) |
3028 | + if wt.supports_setting_file_ids(): |
3029 | + self.assertEqual(efid, ie.file_id) |
3030 | + self.assertEqual(eparent, ie.parent_id) |
3031 | if eparent is not None: |
3032 | - self.assertIsInstance(ie.parent_id, str) |
3033 | + self.assertIsInstance(ie.parent_id, bytes) |
3034 | # WorkingTree's return None for the last modified revision |
3035 | if ie.revision is not None: |
3036 | self.assertIsInstance(ie.revision, str) |
3037 | @@ -299,10 +402,13 @@ |
3038 | # but not all will |
3039 | continue |
3040 | self.assertEqual(erev, ie.revision) |
3041 | - self.assertEqual(len(path_and_ids), len(path_entries)) |
3042 | + self.assertEqual(len(path_and_ids), len(path_entries), |
3043 | + "%r vs %r" % ( |
3044 | + [p for (p, f, pf, r) in path_and_ids], |
3045 | + [p for (p, e) in path_entries])) |
3046 | get_revision_id = getattr(tree, 'get_revision_id', None) |
3047 | if get_revision_id is not None: |
3048 | - self.assertIsInstance(get_revision_id(), str) |
3049 | + self.assertIsInstance(get_revision_id(), bytes) |
3050 | last_revision = getattr(tree, 'last_revision', None) |
3051 | if last_revision is not None: |
3052 | - self.assertIsInstance(last_revision(), str) |
3053 | + self.assertIsInstance(last_revision(), bytes) |
3054 | |
3055 | === modified file 'breezy/tests/per_tree/test_tree.py' |
3056 | --- breezy/tests/per_tree/test_tree.py 2018-03-04 17:22:37 +0000 |
3057 | +++ breezy/tests/per_tree/test_tree.py 2018-03-24 17:11:56 +0000 |
3058 | @@ -359,4 +359,12 @@ |
3059 | def test_has_versioned_directories(self): |
3060 | work_tree = self.make_branch_and_tree('tree') |
3061 | tree = self._convert_tree(work_tree) |
3062 | - self.assertSubset([tree.has_versioned_directories()], (True, False)) |
3063 | + self.assertIn(tree.has_versioned_directories(), (True, False)) |
3064 | + |
3065 | + |
3066 | +class TestSupportsRenameTracking(TestCaseWithTree): |
3067 | + |
3068 | + def test_supports_rename_tracking(self): |
3069 | + work_tree = self.make_branch_and_tree('tree') |
3070 | + tree = self._convert_tree(work_tree) |
3071 | + self.assertSubset([tree.supports_rename_tracking()], (True, False)) |
3072 | |
3073 | === modified file 'breezy/tests/per_tree/test_walkdirs.py' |
3074 | --- breezy/tests/per_tree/test_walkdirs.py 2018-03-12 05:56:02 +0000 |
3075 | +++ breezy/tests/per_tree/test_walkdirs.py 2018-03-24 17:11:56 +0000 |
3076 | @@ -48,7 +48,7 @@ |
3077 | ] |
3078 | if symlinks: |
3079 | dirblocks[0][1].append(('symlink', 'symlink', 'symlink', None, |
3080 | - 'symlink', 'symlink')) |
3081 | + tree.path2id('symlink'), 'symlink')) |
3082 | return dirblocks |
3083 | |
3084 | def test_walkdir_root(self): |
3085 | |
3086 | === modified file 'breezy/tests/per_workingtree/test_check_state.py' |
3087 | --- breezy/tests/per_workingtree/test_check_state.py 2017-05-21 18:10:28 +0000 |
3088 | +++ breezy/tests/per_workingtree/test_check_state.py 2018-03-24 17:11:56 +0000 |
3089 | @@ -81,8 +81,11 @@ |
3090 | tree = self.make_initial_tree() |
3091 | foo_id = tree.path2id('foo') |
3092 | tree.rename_one('foo', 'baz') |
3093 | - self.assertEqual(None, tree.path2id('foo')) |
3094 | - self.assertEqual(foo_id, tree.path2id('baz')) |
3095 | + self.assertFalse(tree.is_versioned('foo')) |
3096 | + if tree.supports_rename_tracking(): |
3097 | + self.assertEqual(foo_id, tree.path2id('baz')) |
3098 | + else: |
3099 | + self.assertTrue(tree.is_versioned('baz')) |
3100 | tree.reset_state() |
3101 | # After reset, we should have forgotten about the rename, but we won't |
3102 | # have |
3103 | |
3104 | === modified file 'breezy/tests/per_workingtree/test_executable.py' |
3105 | === modified file 'breezy/tests/per_workingtree/test_inv.py' |
3106 | --- breezy/tests/per_workingtree/test_inv.py 2018-02-15 19:38:33 +0000 |
3107 | +++ breezy/tests/per_workingtree/test_inv.py 2018-03-24 17:11:56 +0000 |
3108 | @@ -178,6 +178,6 @@ |
3109 | # wt.current_dirstate()'s idea about what files are where. |
3110 | ie = base.inventory['subdir-id'] |
3111 | self.assertEqual('directory', ie.kind) |
3112 | - path, ie = next(base.iter_entries_by_dir(['subdir-id'])) |
3113 | + path, ie = next(base.iter_entries_by_dir(specific_files=['subdir'])) |
3114 | self.assertEqual('subdir', path) |
3115 | self.assertEqual('tree-reference', ie.kind) |
3116 | |
3117 | === modified file 'breezy/tests/per_workingtree/test_merge_from_branch.py' |
3118 | --- breezy/tests/per_workingtree/test_merge_from_branch.py 2018-03-08 02:01:07 +0000 |
3119 | +++ breezy/tests/per_workingtree/test_merge_from_branch.py 2018-03-24 17:11:56 +0000 |
3120 | @@ -111,7 +111,7 @@ |
3121 | self.build_tree_contents([('this/foo', 'baz')]) |
3122 | this.commit('content -> baz') |
3123 | class QuxMerge(merge.Merge3Merger): |
3124 | - def text_merge(self, file_id, trans_id): |
3125 | + def text_merge(self, trans_id, paths, file_id): |
3126 | self.tt.create_file('qux', trans_id) |
3127 | this.merge_from_branch(other.branch, merge_type=QuxMerge) |
3128 | self.assertEqual('qux', this.get_file_text('foo')) |
3129 | |
3130 | === modified file 'breezy/tests/per_workingtree/test_move.py' |
3131 | --- breezy/tests/per_workingtree/test_move.py 2018-03-12 05:18:13 +0000 |
3132 | +++ breezy/tests/per_workingtree/test_move.py 2018-03-24 17:11:56 +0000 |
3133 | @@ -137,13 +137,25 @@ |
3134 | tree.move, ['d', 'c', 'b'], 'a') |
3135 | if osutils.lexists('a/c'): |
3136 | # If 'c' was actually moved, then 'd' should have also been moved |
3137 | +<<<<<<< TREE |
3138 | self.assertPathRelations( |
3139 | tree.basis_tree(), tree, |
3140 | [('', ''), ('a/', 'a'), ('a/c', 'c'), ('a/d', 'd')]) |
3141 | +======= |
3142 | + self.assertPathRelations( |
3143 | + tree.basis_tree(), tree, |
3144 | + [('', ''), ('a/', 'a/'), ('a/c', 'c'), ('a/d', 'd')]) |
3145 | +>>>>>>> MERGE-SOURCE |
3146 | else: |
3147 | +<<<<<<< TREE |
3148 | self.assertPathRelations( |
3149 | tree.basis_tree(), tree, |
3150 | [('', ''), ( 'a/', 'a'), ('c', 'c'), ('d', 'd')]) |
3151 | +======= |
3152 | + self.assertPathRelations( |
3153 | + tree.basis_tree(), tree, |
3154 | + [('', ''), ( 'a/', 'a/'), ('c', 'c'), ('d', 'd')]) |
3155 | +>>>>>>> MERGE-SOURCE |
3156 | tree._validate() |
3157 | |
3158 | def test_move_over_deleted(self): |
3159 | @@ -154,9 +166,15 @@ |
3160 | |
3161 | tree.remove(['a/b'], keep_files=False) |
3162 | self.assertEqual([('b', 'a/b')], tree.move(['b'], 'a')) |
3163 | +<<<<<<< TREE |
3164 | self.assertPathRelations( |
3165 | tree.basis_tree(), tree, |
3166 | [('', ''), ('a/', 'a'), ('a/b', 'b')]) |
3167 | +======= |
3168 | + self.assertPathRelations( |
3169 | + tree.basis_tree(), tree, |
3170 | + [('', ''), ('a/', 'a/'), ('a/b', 'b')]) |
3171 | +>>>>>>> MERGE-SOURCE |
3172 | tree._validate() |
3173 | |
3174 | def test_move_subdir(self): |
3175 | @@ -164,6 +182,7 @@ |
3176 | self.build_tree(['a', 'b/', 'b/c']) |
3177 | tree.add(['a', 'b', 'b/c']) |
3178 | tree.commit('initial') |
3179 | +<<<<<<< TREE |
3180 | self.assertPathRelations( |
3181 | tree.basis_tree(), tree, |
3182 | [('', ''), ('a', 'a'), ('b/', 'b'), ('b/c', 'b/c')]) |
3183 | @@ -172,6 +191,16 @@ |
3184 | self.assertPathRelations( |
3185 | tree.basis_tree(), tree, |
3186 | [('', ''), ('b/', 'b'), ('b/a', 'a'), ('b/c', 'b/c')]) |
3187 | +======= |
3188 | + self.assertPathRelations( |
3189 | + tree.basis_tree(), tree, |
3190 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('b/c', 'b/c')]) |
3191 | + a_contents = tree.get_file_text('a') |
3192 | + self.assertEqual([('a', 'b/a')], tree.move(['a'], 'b')) |
3193 | + self.assertPathRelations( |
3194 | + tree.basis_tree(), tree, |
3195 | + [('', ''), ('b/', 'b/'), ('b/a', 'a'), ('b/c', 'b/c')]) |
3196 | +>>>>>>> MERGE-SOURCE |
3197 | self.assertPathDoesNotExist('a') |
3198 | self.assertFileEqual(a_contents, 'b/a') |
3199 | tree._validate() |
3200 | @@ -184,9 +213,15 @@ |
3201 | c_contents = tree.get_file_text('b/c') |
3202 | self.assertEqual([('b/c', 'c')], |
3203 | tree.move(['b/c'], '')) |
3204 | +<<<<<<< TREE |
3205 | self.assertPathRelations( |
3206 | tree.basis_tree(), tree, |
3207 | [('', ''), ('a', 'a'), ('b/', 'b'), ('c', 'b/c')]) |
3208 | +======= |
3209 | + self.assertPathRelations( |
3210 | + tree.basis_tree(), tree, |
3211 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('c', 'b/c')]) |
3212 | +>>>>>>> MERGE-SOURCE |
3213 | self.assertPathDoesNotExist('b/c') |
3214 | self.assertFileEqual(c_contents, 'c') |
3215 | tree._validate() |
3216 | @@ -202,14 +237,26 @@ |
3217 | # 'c' may or may not have been moved, but either way the tree should |
3218 | # maintain a consistent state. |
3219 | if osutils.lexists('c'): |
3220 | +<<<<<<< TREE |
3221 | self.assertPathRelations( |
3222 | tree.basis_tree(), tree, |
3223 | [('', ''), ('a', 'a'), ('b/', 'b'), ('c', 'c')]) |
3224 | +======= |
3225 | + self.assertPathRelations( |
3226 | + tree.basis_tree(), tree, |
3227 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('c', 'c')]) |
3228 | +>>>>>>> MERGE-SOURCE |
3229 | else: |
3230 | self.assertPathExists('b/c') |
3231 | +<<<<<<< TREE |
3232 | self.assertPathRelations( |
3233 | tree.basis_tree(), tree, |
3234 | [('', ''), ('a', 'a'), ('b/', 'b'), ('b/c', 'c')]) |
3235 | +======= |
3236 | + self.assertPathRelations( |
3237 | + tree.basis_tree(), tree, |
3238 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('b/c', 'c')]) |
3239 | +>>>>>>> MERGE-SOURCE |
3240 | tree._validate() |
3241 | |
3242 | def test_move_onto_self(self): |
3243 | @@ -239,16 +286,28 @@ |
3244 | tree.commit('initial') |
3245 | os.rename('a', 'b/a') |
3246 | |
3247 | +<<<<<<< TREE |
3248 | self.assertPathRelations( |
3249 | tree.basis_tree(), tree, |
3250 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3251 | +======= |
3252 | + self.assertPathRelations( |
3253 | + tree.basis_tree(), tree, |
3254 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3255 | +>>>>>>> MERGE-SOURCE |
3256 | # We don't need after=True as long as source is missing and target |
3257 | # exists. |
3258 | self.assertEqual([('a', 'b/a')], |
3259 | tree.move(['a'], 'b')) |
3260 | +<<<<<<< TREE |
3261 | self.assertPathRelations( |
3262 | tree.basis_tree(), tree, |
3263 | [('', ''), ('b/', 'b'), ('b/a', 'a')]) |
3264 | +======= |
3265 | + self.assertPathRelations( |
3266 | + tree.basis_tree(), tree, |
3267 | + [('', ''), ('b/', 'b/'), ('b/a', 'a')]) |
3268 | +>>>>>>> MERGE-SOURCE |
3269 | tree._validate() |
3270 | |
3271 | def test_move_after_with_after(self): |
3272 | @@ -258,14 +317,27 @@ |
3273 | tree.commit('initial') |
3274 | os.rename('a', 'b/a') |
3275 | |
3276 | +<<<<<<< TREE |
3277 | self.assertPathRelations( |
3278 | tree.basis_tree(), tree, |
3279 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3280 | +======= |
3281 | + self.assertPathRelations( |
3282 | + tree.basis_tree(), tree, |
3283 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3284 | +>>>>>>> MERGE-SOURCE |
3285 | # Passing after=True should work as well |
3286 | +<<<<<<< TREE |
3287 | self.assertEqual([('a', 'b/a')], tree.move(['a'], 'b', after=True)) |
3288 | self.assertPathRelations( |
3289 | tree.basis_tree(), tree, |
3290 | [('', ''), ('b/', 'b'), ('b/a', 'a')]) |
3291 | +======= |
3292 | + self.assertEqual([('a', 'b/a')], tree.move(['a'], 'b', after=True)) |
3293 | + self.assertPathRelations( |
3294 | + tree.basis_tree(), tree, |
3295 | + [('', ''), ('b/', 'b/'), ('b/a', 'a')]) |
3296 | +>>>>>>> MERGE-SOURCE |
3297 | tree._validate() |
3298 | |
3299 | def test_move_after_no_target(self): |
3300 | @@ -303,9 +375,15 @@ |
3301 | # But you can pass after=True |
3302 | self.assertEqual([('a', 'b/a')], |
3303 | tree.move(['a'], 'b', after=True)) |
3304 | +<<<<<<< TREE |
3305 | self.assertPathRelations( |
3306 | tree.basis_tree(), tree, |
3307 | [('', ''), ('b/', 'b'), ('b/a', 'a')]) |
3308 | +======= |
3309 | + self.assertPathRelations( |
3310 | + tree.basis_tree(), tree, |
3311 | + [('', ''), ('b/', 'b/'), ('b/a', 'a')]) |
3312 | +>>>>>>> MERGE-SOURCE |
3313 | # But it shouldn't actually move anything |
3314 | self.assertFileEqual(a_text, 'a') |
3315 | self.assertFileEqual(ba_text, 'b/a') |
3316 | @@ -317,11 +395,19 @@ |
3317 | tree.add(['a', 'a/b', 'a/c', 'a/c/d', 'e']) |
3318 | tree.commit('initial') |
3319 | |
3320 | +<<<<<<< TREE |
3321 | self.assertEqual([('a', 'e/a')], tree.move(['a'], 'e')) |
3322 | self.assertPathRelations( |
3323 | tree.basis_tree(), tree, |
3324 | [('', ''), ('e/', 'e'), ('e/a/', 'a'), ('e/a/b', 'a/b'), |
3325 | ('e/a/c/', 'a/c'), ('e/a/c/d', 'a/c/d')]) |
3326 | +======= |
3327 | + self.assertEqual([('a', 'e/a')], tree.move(['a'], 'e')) |
3328 | + self.assertPathRelations( |
3329 | + tree.basis_tree(), tree, |
3330 | + [('', ''), ('e/', 'e/'), ('e/a/', 'a/'), ('e/a/b', 'a/b'), |
3331 | + ('e/a/c/', 'a/c/'), ('e/a/c/d', 'a/c/d')]) |
3332 | +>>>>>>> MERGE-SOURCE |
3333 | tree._validate() |
3334 | |
3335 | def test_move_directory_into_parent(self): |
3336 | @@ -335,12 +421,21 @@ |
3337 | |
3338 | self.assertEqual([('c/b', 'b')], |
3339 | tree.move(['c/b'], '')) |
3340 | +<<<<<<< TREE |
3341 | self.assertPathRelations( |
3342 | tree.basis_tree(), tree, |
3343 | [('', ''), |
3344 | ('b/', 'c/b'), |
3345 | ('c/', 'c'), |
3346 | ('b/d/', 'c/b/d')]) |
3347 | +======= |
3348 | + self.assertPathRelations( |
3349 | + tree.basis_tree(), tree, |
3350 | + [('', ''), |
3351 | + ('b/', 'c/b/'), |
3352 | + ('c/', 'c/'), |
3353 | + ('b/d/', 'c/b/d/')]) |
3354 | +>>>>>>> MERGE-SOURCE |
3355 | tree._validate() |
3356 | |
3357 | def test_move_directory_with_children_in_subdir(self): |
3358 | @@ -350,6 +445,7 @@ |
3359 | tree.commit('initial') |
3360 | |
3361 | tree.rename_one('a/b', 'a/c/b') |
3362 | +<<<<<<< TREE |
3363 | self.assertPathRelations( |
3364 | tree.basis_tree(), tree, |
3365 | [('', ''), |
3366 | @@ -358,8 +454,19 @@ |
3367 | ('a/c/', 'a/c'), |
3368 | ('a/c/b', 'a/b'), |
3369 | ]) |
3370 | +======= |
3371 | + self.assertPathRelations( |
3372 | + tree.basis_tree(), tree, |
3373 | + [('', ''), |
3374 | + ('a/', 'a/'), |
3375 | + ('d/', 'd/'), |
3376 | + ('a/c/', 'a/c/'), |
3377 | + ('a/c/b', 'a/b'), |
3378 | + ]) |
3379 | +>>>>>>> MERGE-SOURCE |
3380 | self.assertEqual([('a', 'd/a')], |
3381 | tree.move(['a'], 'd')) |
3382 | +<<<<<<< TREE |
3383 | self.assertPathRelations( |
3384 | tree.basis_tree(), tree, |
3385 | [('', ''), |
3386 | @@ -368,6 +475,16 @@ |
3387 | ('d/a/c/', 'a/c'), |
3388 | ('d/a/c/b', 'a/b'), |
3389 | ]) |
3390 | +======= |
3391 | + self.assertPathRelations( |
3392 | + tree.basis_tree(), tree, |
3393 | + [('', ''), |
3394 | + ('d/', 'd/'), |
3395 | + ('d/a/', 'a/'), |
3396 | + ('d/a/c/', 'a/c/'), |
3397 | + ('d/a/c/b', 'a/b'), |
3398 | + ]) |
3399 | +>>>>>>> MERGE-SOURCE |
3400 | tree._validate() |
3401 | |
3402 | def test_move_directory_with_deleted_children(self): |
3403 | @@ -380,12 +497,21 @@ |
3404 | |
3405 | self.assertEqual([('a', 'b/a')], |
3406 | tree.move(['a'], 'b')) |
3407 | +<<<<<<< TREE |
3408 | self.assertPathRelations( |
3409 | tree.basis_tree(), tree, |
3410 | [('', ''), |
3411 | ('b/', 'b'), |
3412 | ('b/a/', 'a'), |
3413 | ('b/a/c', 'a/c')]) |
3414 | +======= |
3415 | + self.assertPathRelations( |
3416 | + tree.basis_tree(), tree, |
3417 | + [('', ''), |
3418 | + ('b/', 'b/'), |
3419 | + ('b/a/', 'a/'), |
3420 | + ('b/a/c', 'a/c')]) |
3421 | +>>>>>>> MERGE-SOURCE |
3422 | tree._validate() |
3423 | |
3424 | def test_move_directory_with_new_children(self): |
3425 | @@ -398,6 +524,7 @@ |
3426 | tree.add(['a/b', 'a/d']) |
3427 | |
3428 | self.assertEqual([('a', 'b/a')], tree.move(['a'], 'b')) |
3429 | +<<<<<<< TREE |
3430 | self.assertPathRelations( |
3431 | tree.basis_tree(), tree, |
3432 | [('', ''), |
3433 | @@ -407,6 +534,17 @@ |
3434 | ('b/a/c', 'a/c'), |
3435 | ('b/a/d', None), |
3436 | ]) |
3437 | +======= |
3438 | + self.assertPathRelations( |
3439 | + tree.basis_tree(), tree, |
3440 | + [('', ''), |
3441 | + ('b/', 'b/'), |
3442 | + ('b/a/', 'a/'), |
3443 | + ('b/a/b', None), |
3444 | + ('b/a/c', 'a/c'), |
3445 | + ('b/a/d', None), |
3446 | + ]) |
3447 | +>>>>>>> MERGE-SOURCE |
3448 | tree._validate() |
3449 | |
3450 | def test_move_directory_with_moved_children(self): |
3451 | @@ -417,6 +555,7 @@ |
3452 | |
3453 | self.assertEqual([('a/b', 'b')], |
3454 | tree.move(['a/b'], '')) |
3455 | +<<<<<<< TREE |
3456 | self.assertPathRelations( |
3457 | tree.basis_tree(), tree, |
3458 | [('', ''), |
3459 | @@ -426,8 +565,20 @@ |
3460 | ('e/', 'e'), |
3461 | ('a/c', 'a/c'), |
3462 | ]) |
3463 | +======= |
3464 | + self.assertPathRelations( |
3465 | + tree.basis_tree(), tree, |
3466 | + [('', ''), |
3467 | + ('a/', 'a/'), |
3468 | + ('b', 'a/b'), |
3469 | + ('d', 'd'), |
3470 | + ('e/', 'e/'), |
3471 | + ('a/c', 'a/c'), |
3472 | + ]) |
3473 | +>>>>>>> MERGE-SOURCE |
3474 | self.assertEqual([('d', 'a/d')], |
3475 | tree.move(['d'], 'a')) |
3476 | +<<<<<<< TREE |
3477 | self.assertPathRelations( |
3478 | tree.basis_tree(), tree, |
3479 | [('', ''), |
3480 | @@ -437,8 +588,20 @@ |
3481 | ('a/c', 'a/c'), |
3482 | ('a/d', 'd'), |
3483 | ]) |
3484 | +======= |
3485 | + self.assertPathRelations( |
3486 | + tree.basis_tree(), tree, |
3487 | + [('', ''), |
3488 | + ('a/', 'a/'), |
3489 | + ('b', 'a/b'), |
3490 | + ('e/', 'e/'), |
3491 | + ('a/c', 'a/c'), |
3492 | + ('a/d', 'd'), |
3493 | + ]) |
3494 | +>>>>>>> MERGE-SOURCE |
3495 | self.assertEqual([('a', 'e/a')], |
3496 | tree.move(['a'], 'e')) |
3497 | +<<<<<<< TREE |
3498 | self.assertPathRelations( |
3499 | tree.basis_tree(), tree, |
3500 | [('', ''), |
3501 | @@ -448,6 +611,17 @@ |
3502 | ('e/a/c', 'a/c'), |
3503 | ('e/a/d', 'd'), |
3504 | ]) |
3505 | +======= |
3506 | + self.assertPathRelations( |
3507 | + tree.basis_tree(), tree, |
3508 | + [('', ''), |
3509 | + ('b', 'a/b'), |
3510 | + ('e/', 'e/'), |
3511 | + ('e/a/', 'a/'), |
3512 | + ('e/a/c', 'a/c'), |
3513 | + ('e/a/d', 'd'), |
3514 | + ]) |
3515 | +>>>>>>> MERGE-SOURCE |
3516 | tree._validate() |
3517 | |
3518 | def test_move_directory_with_renamed_child(self): |
3519 | @@ -457,6 +631,7 @@ |
3520 | tree.commit('initial') |
3521 | |
3522 | tree.rename_one('a/b', 'a/d') |
3523 | +<<<<<<< TREE |
3524 | self.assertPathRelations( |
3525 | tree.basis_tree(), tree, |
3526 | [('', ''), |
3527 | @@ -465,8 +640,19 @@ |
3528 | ('a/c', 'a/c'), |
3529 | ('a/d', 'a/b')]) |
3530 | |
3531 | +======= |
3532 | + self.assertPathRelations( |
3533 | + tree.basis_tree(), tree, |
3534 | + [('', ''), |
3535 | + ('a/', 'a/'), |
3536 | + ('d/', 'd/'), |
3537 | + ('a/c', 'a/c'), |
3538 | + ('a/d', 'a/b')]) |
3539 | + |
3540 | +>>>>>>> MERGE-SOURCE |
3541 | self.assertEqual([('a', 'd/a')], |
3542 | tree.move(['a'], 'd')) |
3543 | +<<<<<<< TREE |
3544 | self.assertPathRelations( |
3545 | tree.basis_tree(), tree, |
3546 | [('', ''), |
3547 | @@ -474,6 +660,15 @@ |
3548 | ('d/a/', 'a'), |
3549 | ('d/a/c', 'a/c'), |
3550 | ('d/a/d', 'a/b')]) |
3551 | +======= |
3552 | + self.assertPathRelations( |
3553 | + tree.basis_tree(), tree, |
3554 | + [('', ''), |
3555 | + ('d/', 'd/'), |
3556 | + ('d/a/', 'a/'), |
3557 | + ('d/a/c', 'a/c'), |
3558 | + ('d/a/d', 'a/b')]) |
3559 | +>>>>>>> MERGE-SOURCE |
3560 | tree._validate() |
3561 | |
3562 | def test_move_directory_with_swapped_children(self): |
3563 | @@ -485,6 +680,7 @@ |
3564 | tree.rename_one('a/b', 'a/bb') |
3565 | tree.rename_one('a/d', 'a/b') |
3566 | tree.rename_one('a/bb', 'a/d') |
3567 | +<<<<<<< TREE |
3568 | self.assertPathRelations( |
3569 | tree.basis_tree(), tree, |
3570 | [('', ''), |
3571 | @@ -493,8 +689,19 @@ |
3572 | ('a/b', 'a/d'), |
3573 | ('a/c', 'a/c'), |
3574 | ('a/d', 'a/b')]) |
3575 | +======= |
3576 | + self.assertPathRelations( |
3577 | + tree.basis_tree(), tree, |
3578 | + [('', ''), |
3579 | + ('a/', 'a/'), |
3580 | + ('e/', 'e/'), |
3581 | + ('a/b', 'a/d'), |
3582 | + ('a/c', 'a/c'), |
3583 | + ('a/d', 'a/b')]) |
3584 | +>>>>>>> MERGE-SOURCE |
3585 | self.assertEqual([('a', 'e/a')], |
3586 | tree.move(['a'], 'e')) |
3587 | +<<<<<<< TREE |
3588 | self.assertPathRelations( |
3589 | tree.basis_tree(), tree, |
3590 | [('', ''), |
3591 | @@ -503,6 +710,16 @@ |
3592 | ('e/a/b', 'a/d'), |
3593 | ('e/a/c', 'a/c'), |
3594 | ('e/a/d', 'a/b')]) |
3595 | +======= |
3596 | + self.assertPathRelations( |
3597 | + tree.basis_tree(), tree, |
3598 | + [('', ''), |
3599 | + ('e/', 'e/'), |
3600 | + ('e/a/', 'a/'), |
3601 | + ('e/a/b', 'a/d'), |
3602 | + ('e/a/c', 'a/c'), |
3603 | + ('e/a/d', 'a/b')]) |
3604 | +>>>>>>> MERGE-SOURCE |
3605 | tree._validate() |
3606 | |
3607 | def test_move_moved(self): |
3608 | @@ -514,14 +731,27 @@ |
3609 | |
3610 | self.assertEqual([('a/b', 'c/b')], |
3611 | tree.move(['a/b'], 'c')) |
3612 | +<<<<<<< TREE |
3613 | self.assertPathRelations( |
3614 | tree.basis_tree(), tree, |
3615 | [('', ''), ('a/', 'a'), ('c/', 'c'), ('c/b', 'a/b')]) |
3616 | +======= |
3617 | + self.assertPathRelations( |
3618 | + tree.basis_tree(), tree, |
3619 | + [('', ''), ('a/', 'a/'), ('c/', 'c/'), ('c/b', 'a/b')]) |
3620 | +>>>>>>> MERGE-SOURCE |
3621 | |
3622 | +<<<<<<< TREE |
3623 | self.assertEqual([('c/b', 'b')], tree.move(['c/b'], '')) |
3624 | self.assertPathRelations( |
3625 | tree.basis_tree(), tree, |
3626 | [('', ''), ('a/', 'a'), ('b', 'a/b'), ('c/', 'c')]) |
3627 | +======= |
3628 | + self.assertEqual([('c/b', 'b')], tree.move(['c/b'], '')) |
3629 | + self.assertPathRelations( |
3630 | + tree.basis_tree(), tree, |
3631 | + [('', ''), ('a/', 'a/'), ('b', 'a/b'), ('c/', 'c/')]) |
3632 | +>>>>>>> MERGE-SOURCE |
3633 | tree._validate() |
3634 | |
3635 | def test_move_to_unversioned_non_ascii_dir(self): |
3636 | |
3637 | === modified file 'breezy/tests/per_workingtree/test_nested_specifics.py' |
3638 | --- breezy/tests/per_workingtree/test_nested_specifics.py 2018-02-16 19:38:39 +0000 |
3639 | +++ breezy/tests/per_workingtree/test_nested_specifics.py 2018-03-24 17:11:56 +0000 |
3640 | @@ -79,5 +79,5 @@ |
3641 | |
3642 | def test_iter_entries_by_dir_autodetects_subtree(self): |
3643 | tree = self.prepare_with_subtree() |
3644 | - path, ie = next(tree.iter_entries_by_dir(['subtree-id'])) |
3645 | + path, ie = next(tree.iter_entries_by_dir(specific_files=['subtree'])) |
3646 | self.assertEqual('tree-reference', ie.kind) |
3647 | |
3648 | === modified file 'breezy/tests/per_workingtree/test_paths2ids.py' |
3649 | --- breezy/tests/per_workingtree/test_paths2ids.py 2018-02-03 13:39:29 +0000 |
3650 | +++ breezy/tests/per_workingtree/test_paths2ids.py 2018-03-24 17:11:56 +0000 |
3651 | @@ -22,6 +22,7 @@ |
3652 | """ |
3653 | |
3654 | from breezy import errors |
3655 | +from breezy.bzr.inventorytree import InventoryTree |
3656 | from breezy.tests import ( |
3657 | features, |
3658 | TestNotApplicable, |
3659 | @@ -62,16 +63,30 @@ |
3660 | |
3661 | def test_paths_none_result_none(self): |
3662 | tree = self.make_branch_and_tree('tree') |
3663 | + if not isinstance(tree, InventoryTree): |
3664 | + raise TestNotApplicable( |
3665 | + "test not applicable on non-inventory tests") |
3666 | + |
3667 | tree.lock_read() |
3668 | self.assertEqual(None, tree.paths2ids(None)) |
3669 | tree.unlock() |
3670 | |
3671 | def test_find_single_root(self): |
3672 | tree = self.make_branch_and_tree('tree') |
3673 | + if not isinstance(tree, InventoryTree): |
3674 | + raise TestNotApplicable( |
3675 | + "test not applicable on non-inventory tests") |
3676 | + |
3677 | + |
3678 | self.assertExpectedIds([tree.path2id('')], tree, ['']) |
3679 | |
3680 | def test_find_tree_and_clone_roots(self): |
3681 | tree = self.make_branch_and_tree('tree') |
3682 | + if not isinstance(tree, InventoryTree): |
3683 | + raise TestNotApplicable( |
3684 | + "test not applicable on non-inventory tests") |
3685 | + |
3686 | + |
3687 | clone = tree.controldir.clone('clone').open_workingtree() |
3688 | clone.lock_tree_write() |
3689 | clone_root_id = 'new-id' |
3690 | @@ -136,6 +151,11 @@ |
3691 | new-child because its under dir in new. |
3692 | """ |
3693 | tree = self.make_branch_and_tree('tree') |
3694 | + if not isinstance(tree, InventoryTree): |
3695 | + raise TestNotApplicable( |
3696 | + "test not applicable on non-inventory tests") |
3697 | + |
3698 | + |
3699 | self.build_tree( |
3700 | ['tree/dir/', 'tree/dir/child-moves', 'tree/dir/child-stays', |
3701 | 'tree/dir/child-goes']) |
3702 | @@ -161,6 +181,11 @@ |
3703 | |
3704 | def test_unversioned_one_tree(self): |
3705 | tree = self.make_branch_and_tree('tree') |
3706 | + if not isinstance(tree, InventoryTree): |
3707 | + raise TestNotApplicable( |
3708 | + "test not applicable on non-inventory tests") |
3709 | + |
3710 | + |
3711 | self.build_tree(['tree/unversioned']) |
3712 | self.assertExpectedIds([], tree, ['unversioned'], require_versioned=False) |
3713 | tree.lock_read() |
3714 | @@ -172,6 +197,10 @@ |
3715 | # should not raise an error: it must be unversioned in *all* trees to |
3716 | # error. |
3717 | tree = self.make_branch_and_tree('tree') |
3718 | + if not isinstance(tree, InventoryTree): |
3719 | + raise TestNotApplicable( |
3720 | + "test not applicable on non-inventory tests") |
3721 | + |
3722 | if not tree.supports_setting_file_ids(): |
3723 | raise TestNotApplicable('tree does not support setting file ids') |
3724 | tree.commit('make basis') |
3725 | @@ -185,6 +214,10 @@ |
3726 | # should not raise an error: it must be unversioned in *all* trees to |
3727 | # error. |
3728 | tree = self.make_branch_and_tree('tree') |
3729 | + if not isinstance(tree, InventoryTree): |
3730 | + raise TestNotApplicable( |
3731 | + "test not applicable on non-inventory tests") |
3732 | + |
3733 | tree.commit('make basis') |
3734 | basis = tree.basis_tree() |
3735 | self.assertExpectedIds([], tree, ['unversioned'], [basis], |
3736 | @@ -201,6 +234,10 @@ |
3737 | def test_unversioned_non_ascii_one_tree(self): |
3738 | self.requireFeature(features.UnicodeFilenameFeature) |
3739 | tree = self.make_branch_and_tree('.') |
3740 | + if not isinstance(tree, InventoryTree): |
3741 | + raise TestNotApplicable( |
3742 | + "test not applicable on non-inventory tests") |
3743 | + |
3744 | self.build_tree([u"\xa7"]) |
3745 | self.assertExpectedIds([], tree, [u"\xa7"], require_versioned=False) |
3746 | self.addCleanup(tree.lock_read().unlock) |
3747 | |
3748 | === modified file 'breezy/tests/per_workingtree/test_pull.py' |
3749 | --- breezy/tests/per_workingtree/test_pull.py 2018-01-12 08:52:43 +0000 |
3750 | +++ breezy/tests/per_workingtree/test_pull.py 2018-03-24 17:11:56 +0000 |
3751 | @@ -103,7 +103,7 @@ |
3752 | trunk = self.make_branch_deleting_dir('trunk') |
3753 | work = trunk.controldir.sprout('work', revision_id='2').open_workingtree() |
3754 | work.branch.get_config_stack().set( |
3755 | - 'bzr.transform.orphan_policy', 'move') |
3756 | + 'transform.orphan_policy', 'move') |
3757 | # Add some unversioned files in dir |
3758 | self.build_tree(['work/dir/foo', |
3759 | 'work/dir/subdir/', |
3760 | |
3761 | === modified file 'breezy/tests/per_workingtree/test_rename_one.py' |
3762 | --- breezy/tests/per_workingtree/test_rename_one.py 2018-03-12 05:18:13 +0000 |
3763 | +++ breezy/tests/per_workingtree/test_rename_one.py 2018-03-24 17:11:56 +0000 |
3764 | @@ -82,9 +82,15 @@ |
3765 | |
3766 | a_contents = tree.get_file_text('a') |
3767 | tree.rename_one('a', 'foo') |
3768 | +<<<<<<< TREE |
3769 | self.assertPathRelations( |
3770 | tree.basis_tree(), tree, |
3771 | [('', ''), ('b/', 'b'), ('foo', 'a')]) |
3772 | +======= |
3773 | + self.assertPathRelations( |
3774 | + tree.basis_tree(), tree, |
3775 | + [('', ''), ('b/', 'b/'), ('foo', 'a')]) |
3776 | +>>>>>>> MERGE-SOURCE |
3777 | self.assertPathDoesNotExist('a') |
3778 | self.assertFileEqual(a_contents, 'foo') |
3779 | |
3780 | @@ -96,9 +102,15 @@ |
3781 | |
3782 | a_contents = tree.get_file_text('a') |
3783 | tree.rename_one('a', 'b/foo') |
3784 | +<<<<<<< TREE |
3785 | self.assertPathRelations( |
3786 | tree.basis_tree(), tree, |
3787 | [('', ''), ('b/', 'b'), ('b/foo', 'a')]) |
3788 | +======= |
3789 | + self.assertPathRelations( |
3790 | + tree.basis_tree(), tree, |
3791 | + [('', ''), ('b/', 'b/'), ('b/foo', 'a')]) |
3792 | +>>>>>>> MERGE-SOURCE |
3793 | self.assertPathDoesNotExist('tree/a') |
3794 | self.assertFileEqual(a_contents, 'tree/b/foo') |
3795 | |
3796 | @@ -107,14 +119,27 @@ |
3797 | self.build_tree(['a', 'b/', 'b/c']) |
3798 | tree.add(['a', 'b', 'b/c']) |
3799 | tree.commit('initial') |
3800 | +<<<<<<< TREE |
3801 | self.assertPathRelations( |
3802 | tree.basis_tree(), tree, |
3803 | [('', ''), ('a', 'a'), ('b/', 'b'), ('b/c', 'b/c')]) |
3804 | a_contents = tree.get_file_text('a') |
3805 | +======= |
3806 | + self.assertPathRelations( |
3807 | + tree.basis_tree(), tree, |
3808 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('b/c', 'b/c')]) |
3809 | + a_contents = tree.get_file_text('a') |
3810 | +>>>>>>> MERGE-SOURCE |
3811 | tree.rename_one('a', 'b/d') |
3812 | +<<<<<<< TREE |
3813 | self.assertPathRelations( |
3814 | tree.basis_tree(), tree, |
3815 | [('', ''), ('b/', 'b'), ('b/c', 'b/c'), ('b/d', 'a')]) |
3816 | +======= |
3817 | + self.assertPathRelations( |
3818 | + tree.basis_tree(), tree, |
3819 | + [('', ''), ('b/', 'b/'), ('b/c', 'b/c'), ('b/d', 'a')]) |
3820 | +>>>>>>> MERGE-SOURCE |
3821 | self.assertPathDoesNotExist('a') |
3822 | self.assertFileEqual(a_contents, 'b/d') |
3823 | |
3824 | @@ -125,9 +150,15 @@ |
3825 | tree.commit('initial') |
3826 | c_contents = tree.get_file_text('b/c') |
3827 | tree.rename_one('b/c', 'd') |
3828 | +<<<<<<< TREE |
3829 | self.assertPathRelations( |
3830 | tree.basis_tree(), tree, |
3831 | [('', ''), ('a', 'a'), ('b/', 'b'), ('d', 'b/c')]) |
3832 | +======= |
3833 | + self.assertPathRelations( |
3834 | + tree.basis_tree(), tree, |
3835 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('d', 'b/c')]) |
3836 | +>>>>>>> MERGE-SOURCE |
3837 | self.assertPathDoesNotExist('b/c') |
3838 | self.assertFileEqual(c_contents, 'd') |
3839 | |
3840 | @@ -139,9 +170,15 @@ |
3841 | # Target already exists |
3842 | self.assertRaises(errors.RenameFailedFilesExist, |
3843 | tree.rename_one, 'a', 'b/a') |
3844 | +<<<<<<< TREE |
3845 | self.assertPathRelations( |
3846 | tree.basis_tree(), tree, |
3847 | [('', ''), ('a', 'a'), ('b/', 'b'), ('c', 'c')]) |
3848 | +======= |
3849 | + self.assertPathRelations( |
3850 | + tree.basis_tree(), tree, |
3851 | + [('', ''), ('a', 'a'), ('b/', 'b/'), ('c', 'c')]) |
3852 | +>>>>>>> MERGE-SOURCE |
3853 | |
3854 | def test_rename_one_onto_existing(self): |
3855 | tree = self.make_branch_and_tree('.') |
3856 | @@ -177,16 +214,29 @@ |
3857 | tree.commit('initial') |
3858 | os.rename('a', 'b/foo') |
3859 | |
3860 | +<<<<<<< TREE |
3861 | self.assertPathRelations( |
3862 | tree.basis_tree(), tree, |
3863 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3864 | |
3865 | +======= |
3866 | + self.assertPathRelations( |
3867 | + tree.basis_tree(), tree, |
3868 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3869 | + |
3870 | +>>>>>>> MERGE-SOURCE |
3871 | # We don't need after=True as long as source is missing and target |
3872 | # exists. |
3873 | tree.rename_one('a', 'b/foo') |
3874 | +<<<<<<< TREE |
3875 | self.assertPathRelations( |
3876 | tree.basis_tree(), tree, |
3877 | [('', ''), ('b/', 'b'), ('b/foo', 'a')]) |
3878 | +======= |
3879 | + self.assertPathRelations( |
3880 | + tree.basis_tree(), tree, |
3881 | + [('', ''), ('b/', 'b/'), ('b/foo', 'a')]) |
3882 | +>>>>>>> MERGE-SOURCE |
3883 | |
3884 | def test_rename_one_after_with_after(self): |
3885 | tree = self.make_branch_and_tree('.') |
3886 | @@ -196,16 +246,26 @@ |
3887 | os.rename('a', 'b/foo') |
3888 | |
3889 | if tree.has_versioned_directories(): |
3890 | +<<<<<<< TREE |
3891 | self.assertPathRelations(tree.basis_tree(), tree, |
3892 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3893 | +======= |
3894 | + self.assertPathRelations(tree.basis_tree(), tree, |
3895 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3896 | +>>>>>>> MERGE-SOURCE |
3897 | else: |
3898 | self.assertPathRelations(tree.basis_tree(), tree, |
3899 | [('', ''), ('a', 'a')]) |
3900 | |
3901 | # Passing after=True should work as well |
3902 | tree.rename_one('a', 'b/foo', after=True) |
3903 | +<<<<<<< TREE |
3904 | self.assertPathRelations(tree.basis_tree(), tree, |
3905 | [('', ''), ('b/', 'b'), ('b/foo', 'a')]) |
3906 | +======= |
3907 | + self.assertPathRelations(tree.basis_tree(), tree, |
3908 | + [('', ''), ('b/', 'b/'), ('b/foo', 'a')]) |
3909 | +>>>>>>> MERGE-SOURCE |
3910 | |
3911 | def test_rename_one_after_dest_versioned(self): |
3912 | tree = self.make_branch_and_tree('.') |
3913 | @@ -266,16 +326,29 @@ |
3914 | os.rename('a', 'b/foo') |
3915 | tree.remove(['a']) |
3916 | |
3917 | +<<<<<<< TREE |
3918 | self.assertPathRelations( |
3919 | tree.basis_tree(), tree, |
3920 | [('', ''), ('b/', 'b')]) |
3921 | |
3922 | +======= |
3923 | + self.assertPathRelations( |
3924 | + tree.basis_tree(), tree, |
3925 | + [('', ''), ('b/', 'b/')]) |
3926 | + |
3927 | +>>>>>>> MERGE-SOURCE |
3928 | # We don't need after=True as long as source is missing and target |
3929 | # exists. |
3930 | tree.rename_one('a', 'b/foo') |
3931 | +<<<<<<< TREE |
3932 | self.assertPathRelations( |
3933 | tree.basis_tree(), tree, |
3934 | [('', ''), ('b/', 'b'), ('b/foo', 'a')]) |
3935 | +======= |
3936 | + self.assertPathRelations( |
3937 | + tree.basis_tree(), tree, |
3938 | + [('', ''), ('b/', 'b/'), ('b/foo', 'a')]) |
3939 | +>>>>>>> MERGE-SOURCE |
3940 | |
3941 | def test_rename_one_after_no_target(self): |
3942 | tree = self.make_branch_and_tree('.') |
3943 | @@ -287,9 +360,15 @@ |
3944 | # exception |
3945 | self.assertRaises(errors.BzrMoveFailedError, |
3946 | tree.rename_one, 'a', 'b/foo', after=True) |
3947 | +<<<<<<< TREE |
3948 | self.assertPathRelations( |
3949 | tree.basis_tree(), tree, |
3950 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3951 | +======= |
3952 | + self.assertPathRelations( |
3953 | + tree.basis_tree(), tree, |
3954 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3955 | +>>>>>>> MERGE-SOURCE |
3956 | |
3957 | def test_rename_one_after_source_and_dest(self): |
3958 | tree = self.make_branch_and_tree('.') |
3959 | @@ -304,21 +383,39 @@ |
3960 | with open('b/foo', 'r') as foo_file: |
3961 | foo_text = foo_file.read() |
3962 | |
3963 | +<<<<<<< TREE |
3964 | self.assertPathRelations( |
3965 | tree.basis_tree(), tree, |
3966 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3967 | +======= |
3968 | + self.assertPathRelations( |
3969 | + tree.basis_tree(), tree, |
3970 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3971 | +>>>>>>> MERGE-SOURCE |
3972 | self.assertRaises(errors.RenameFailedFilesExist, |
3973 | tree.rename_one, 'a', 'b/foo', after=False) |
3974 | +<<<<<<< TREE |
3975 | self.assertPathRelations( |
3976 | tree.basis_tree(), tree, |
3977 | [('', ''), ('a', 'a'), ('b/', 'b')]) |
3978 | +======= |
3979 | + self.assertPathRelations( |
3980 | + tree.basis_tree(), tree, |
3981 | + [('', ''), ('a', 'a'), ('b/', 'b/')]) |
3982 | +>>>>>>> MERGE-SOURCE |
3983 | self.assertFileEqual(a_text, 'a') |
3984 | self.assertFileEqual(foo_text, 'b/foo') |
3985 | # But you can pass after=True |
3986 | tree.rename_one('a', 'b/foo', after=True) |
3987 | +<<<<<<< TREE |
3988 | self.assertPathRelations( |
3989 | tree.basis_tree(), tree, |
3990 | [('', ''), ('b/', 'b'), ('b/foo', 'a')]) |
3991 | +======= |
3992 | + self.assertPathRelations( |
3993 | + tree.basis_tree(), tree, |
3994 | + [('', ''), ('b/', 'b/'), ('b/foo', 'a')]) |
3995 | +>>>>>>> MERGE-SOURCE |
3996 | # But it shouldn't actually move anything |
3997 | self.assertFileEqual(a_text, 'a') |
3998 | self.assertFileEqual(foo_text, 'b/foo') |
3999 | @@ -330,11 +427,19 @@ |
4000 | tree.commit('initial') |
4001 | |
4002 | tree.rename_one('a', 'e/f') |
4003 | +<<<<<<< TREE |
4004 | self.assertPathRelations( |
4005 | tree.basis_tree(), tree, |
4006 | [('', ''), ('e/', 'e'), ('e/f/', 'a'), |
4007 | ('e/f/b', 'a/b'), ('e/f/c/', 'a/c'), |
4008 | ('e/f/c/d', 'a/c/d')]) |
4009 | +======= |
4010 | + self.assertPathRelations( |
4011 | + tree.basis_tree(), tree, |
4012 | + [('', ''), ('e/', 'e/'), ('e/f/', 'a/'), |
4013 | + ('e/f/b', 'a/b'), ('e/f/c/', 'a/c/'), |
4014 | + ('e/f/c/d', 'a/c/d')]) |
4015 | +>>>>>>> MERGE-SOURCE |
4016 | |
4017 | def test_rename_one_moved(self): |
4018 | """Moving a moved entry works as expected.""" |
4019 | @@ -345,14 +450,26 @@ |
4020 | root_id = tree.get_root_id() |
4021 | |
4022 | tree.rename_one('a/b', 'c/foo') |
4023 | +<<<<<<< TREE |
4024 | self.assertPathRelations( |
4025 | tree.basis_tree(), tree, |
4026 | [('', ''), ('a/', 'a'), ('c/', 'c'), ('c/foo', 'a/b')]) |
4027 | +======= |
4028 | + self.assertPathRelations( |
4029 | + tree.basis_tree(), tree, |
4030 | + [('', ''), ('a/', 'a/'), ('c/', 'c/'), ('c/foo', 'a/b')]) |
4031 | +>>>>>>> MERGE-SOURCE |
4032 | |
4033 | tree.rename_one('c/foo', 'bar') |
4034 | +<<<<<<< TREE |
4035 | self.assertPathRelations( |
4036 | tree.basis_tree(), tree, |
4037 | [('', ''), ('a/', 'a'), ('bar', 'a/b'), ('c/', 'c')]) |
4038 | +======= |
4039 | + self.assertPathRelations( |
4040 | + tree.basis_tree(), tree, |
4041 | + [('', ''), ('a/', 'a/'), ('bar', 'a/b'), ('c/', 'c/')]) |
4042 | +>>>>>>> MERGE-SOURCE |
4043 | |
4044 | def test_rename_to_denormalised_fails(self): |
4045 | if osutils.normalizes_filenames(): |
4046 | |
4047 | === modified file 'breezy/tests/per_workingtree/test_revision_tree.py' |
4048 | --- breezy/tests/per_workingtree/test_revision_tree.py 2018-03-02 16:32:39 +0000 |
4049 | +++ breezy/tests/per_workingtree/test_revision_tree.py 2018-03-24 17:11:56 +0000 |
4050 | @@ -123,7 +123,7 @@ |
4051 | basis = tree.revision_tree(parents[0]) |
4052 | basis.lock_read() |
4053 | self.addCleanup(basis.unlock) |
4054 | - self.assertRaises(errors.NoSuchId, basis.kind, 'a') |
4055 | + self.assertRaises(errors.NoSuchFile, basis.kind, 'a') |
4056 | self.assertEqual(['directory', 'file'], |
4057 | [basis.kind('b'), basis.kind('b/c')]) |
4058 | try: |
4059 | @@ -134,6 +134,6 @@ |
4060 | % type(tree)) |
4061 | other.lock_read() |
4062 | self.addCleanup(other.unlock) |
4063 | - self.assertRaises(errors.NoSuchId, other.kind, 'b') |
4064 | - self.assertRaises(errors.NoSuchId, other.kind, 'c') |
4065 | + self.assertRaises(errors.NoSuchFile, other.kind, 'b') |
4066 | + self.assertRaises(errors.NoSuchFile, other.kind, 'c') |
4067 | self.assertEqual('file', other.kind('a')) |
4068 | |
4069 | === modified file 'breezy/tests/per_workingtree/test_workingtree.py' |
4070 | --- breezy/tests/per_workingtree/test_workingtree.py 2018-03-09 00:05:39 +0000 |
4071 | +++ breezy/tests/per_workingtree/test_workingtree.py 2018-03-24 17:11:56 +0000 |
4072 | @@ -711,17 +711,17 @@ |
4073 | with tree.lock_write(): |
4074 | tree.add(['somefile']) |
4075 | d = {tree.path2id('somefile'): osutils.sha_string('hello')} |
4076 | - try: |
4077 | + if tree.supports_merge_modified(): |
4078 | tree.set_merge_modified(d) |
4079 | - except errors.UnsupportedOperation: |
4080 | + mm = tree.merge_modified() |
4081 | + self.assertEqual(mm, d) |
4082 | + else: |
4083 | + self.assertRaises( |
4084 | + errors.UnsupportedOperation, |
4085 | + tree.set_merge_modified, d) |
4086 | mm = tree.merge_modified() |
4087 | self.assertEqual(mm, {}) |
4088 | - supports_merge_modified = False |
4089 | - else: |
4090 | - mm = tree.merge_modified() |
4091 | - self.assertEqual(mm, d) |
4092 | - supports_merge_modified = True |
4093 | - if supports_merge_modified: |
4094 | + if tree.supports_merge_modified(): |
4095 | mm = tree.merge_modified() |
4096 | self.assertEqual(mm, d) |
4097 | else: |
4098 | |
4099 | === modified file 'breezy/tests/test_bundle.py' |
4100 | --- breezy/tests/test_bundle.py 2018-02-15 19:38:33 +0000 |
4101 | +++ breezy/tests/test_bundle.py 2018-03-24 17:11:56 +0000 |
4102 | @@ -663,7 +663,7 @@ |
4103 | , 'sub/sub' |
4104 | ]) |
4105 | tt = TreeTransform(self.tree1) |
4106 | - trans_id = tt.trans_id_tree_file_id('exe-1') |
4107 | + trans_id = tt.trans_id_tree_path('executable') |
4108 | tt.set_executability(False, trans_id) |
4109 | tt.apply() |
4110 | self.tree1.commit('removed', rev_id='a@cset-0-3') |
4111 | @@ -731,7 +731,7 @@ |
4112 | self.assertEqual(link_target, bund_tree.get_symlink_target(link_name)) |
4113 | |
4114 | tt = TreeTransform(self.tree1) |
4115 | - trans_id = tt.trans_id_tree_file_id(link_id) |
4116 | + trans_id = tt.trans_id_tree_path(link_name) |
4117 | tt.adjust_path('link2', tt.root, trans_id) |
4118 | tt.delete_contents(trans_id) |
4119 | tt.create_symlink(new_link_target, trans_id) |
4120 | @@ -745,7 +745,7 @@ |
4121 | bund_tree.get_symlink_target('link2')) |
4122 | |
4123 | tt = TreeTransform(self.tree1) |
4124 | - trans_id = tt.trans_id_tree_file_id(link_id) |
4125 | + trans_id = tt.trans_id_tree_path('link2') |
4126 | tt.delete_contents(trans_id) |
4127 | tt.create_symlink('jupiter', trans_id) |
4128 | tt.apply() |
4129 | @@ -753,7 +753,7 @@ |
4130 | bundle = self.get_valid_bundle('l@cset-0-2', 'l@cset-0-3') |
4131 | |
4132 | tt = TreeTransform(self.tree1) |
4133 | - trans_id = tt.trans_id_tree_file_id(link_id) |
4134 | + trans_id = tt.trans_id_tree_path('link2') |
4135 | tt.delete_contents(trans_id) |
4136 | tt.apply() |
4137 | self.tree1.commit('Delete symlink', rev_id='l@cset-0-4') |
4138 | @@ -783,7 +783,7 @@ |
4139 | |
4140 | # Delete |
4141 | tt = TreeTransform(self.tree1) |
4142 | - trans_id = tt.trans_id_tree_file_id('binary-1') |
4143 | + trans_id = tt.trans_id_tree_path('file') |
4144 | tt.delete_contents(trans_id) |
4145 | tt.apply() |
4146 | self.tree1.commit('delete binary', rev_id='b@cset-0-2') |
4147 | @@ -791,7 +791,7 @@ |
4148 | |
4149 | # Rename & modify |
4150 | tt = TreeTransform(self.tree1) |
4151 | - trans_id = tt.trans_id_tree_file_id('binary-2') |
4152 | + trans_id = tt.trans_id_tree_path('file2') |
4153 | tt.adjust_path('file3', tt.root, trans_id) |
4154 | tt.delete_contents(trans_id) |
4155 | tt.create_file('file\rcontents\x00\n\x00', trans_id) |
4156 | @@ -801,7 +801,7 @@ |
4157 | |
4158 | # Modify |
4159 | tt = TreeTransform(self.tree1) |
4160 | - trans_id = tt.trans_id_tree_file_id('binary-2') |
4161 | + trans_id = tt.trans_id_tree_path('file3') |
4162 | tt.delete_contents(trans_id) |
4163 | tt.create_file('\x00file\rcontents', trans_id) |
4164 | tt.apply() |
4165 | @@ -820,7 +820,7 @@ |
4166 | self.tree1.commit('create file', rev_id='a@lmod-0-1') |
4167 | |
4168 | tt = TreeTransform(self.tree1) |
4169 | - trans_id = tt.trans_id_tree_file_id('file') |
4170 | + trans_id = tt.trans_id_tree_path('file') |
4171 | tt.delete_contents(trans_id) |
4172 | tt.create_file('file2', trans_id) |
4173 | tt.apply() |
4174 | @@ -828,7 +828,7 @@ |
4175 | |
4176 | other = self.get_checkout('a@lmod-0-1') |
4177 | tt = TreeTransform(other) |
4178 | - trans_id = tt.trans_id_tree_file_id('file') |
4179 | + trans_id = tt.trans_id_tree_path('file2') |
4180 | tt.delete_contents(trans_id) |
4181 | tt.create_file('file2', trans_id) |
4182 | tt.apply() |
4183 | |
4184 | === modified file 'breezy/tests/test_bzrdir.py' |
4185 | --- breezy/tests/test_bzrdir.py 2017-11-12 20:07:32 +0000 |
4186 | +++ breezy/tests/test_bzrdir.py 2018-03-24 17:11:56 +0000 |
4187 | @@ -864,7 +864,7 @@ |
4188 | tree.commit('Initial commit') |
4189 | # The following line force the orhaning to reveal bug #634470 |
4190 | tree.branch.get_config_stack().set( |
4191 | - 'bzr.transform.orphan_policy', 'move') |
4192 | + 'transform.orphan_policy', 'move') |
4193 | tree.controldir.destroy_workingtree() |
4194 | # FIXME: subtree/.bzr is left here which allows the test to pass (or |
4195 | # fail :-( ) -- vila 20100909 |
4196 | |
4197 | === modified file 'breezy/tests/test_matchers.py' |
4198 | --- breezy/tests/test_matchers.py 2018-03-12 02:24:39 +0000 |
4199 | +++ breezy/tests/test_matchers.py 2018-03-24 17:11:56 +0000 |
4200 | @@ -151,6 +151,7 @@ |
4201 | set(mismatch.describe().split(" != "))) |
4202 | |
4203 | |
4204 | +<<<<<<< TREE |
4205 | class TestHasPathRelations(TestCaseWithTransport): |
4206 | |
4207 | def test__str__(self): |
4208 | @@ -176,6 +177,33 @@ |
4209 | self.assertIsNot(None, mismatch) |
4210 | |
4211 | |
4212 | +======= |
4213 | +class TestHasPathRelations(TestCaseWithTransport): |
4214 | + |
4215 | + def test__str__(self): |
4216 | + t = self.make_branch_and_tree('.') |
4217 | + matcher = HasPathRelations(t, [("a", "b")]) |
4218 | + self.assertEqual("HasPathRelations(%r, [('a', 'b')])" % t, str(matcher)) |
4219 | + |
4220 | + def test_match(self): |
4221 | + t = self.make_branch_and_tree('.') |
4222 | + self.build_tree(['a', 'b/', 'b/c']) |
4223 | + t.add(['a', 'b', 'b/c']) |
4224 | + self.assertThat(t, HasPathRelations(t, |
4225 | + [('', ''), |
4226 | + ('a', 'a'), |
4227 | + ('b/', 'b/'), |
4228 | + ('b/c', 'b/c')])) |
4229 | + |
4230 | + def test_mismatch(self): |
4231 | + t = self.make_branch_and_tree('.') |
4232 | + self.build_tree(['a', 'b/', 'b/c']) |
4233 | + t.add(['a', 'b', 'b/c']) |
4234 | + mismatch = HasPathRelations(t, [('a', 'a')]).match(t) |
4235 | + self.assertIsNot(None, mismatch) |
4236 | + |
4237 | + |
4238 | +>>>>>>> MERGE-SOURCE |
4239 | class TestContainsNoVfsCalls(TestCase): |
4240 | |
4241 | def _make_call(self, method, args): |
4242 | |
4243 | === modified file 'breezy/tests/test_merge.py' |
4244 | --- breezy/tests/test_merge.py 2018-02-16 19:38:39 +0000 |
4245 | +++ breezy/tests/test_merge.py 2018-03-24 17:11:56 +0000 |
4246 | @@ -1265,8 +1265,7 @@ |
4247 | builder.build_snapshot(['B-id', 'C-id'], [], revision_id='D-id') |
4248 | return builder |
4249 | |
4250 | - def make_Merger(self, builder, other_revision_id, |
4251 | - interesting_files=None, interesting_ids=None): |
4252 | + def make_Merger(self, builder, other_revision_id, interesting_files=None): |
4253 | """Make a Merger object from a branch builder""" |
4254 | mem_tree = memorytree.MemoryTree.create_on_branch(builder.get_branch()) |
4255 | mem_tree.lock_write() |
4256 | @@ -1274,8 +1273,6 @@ |
4257 | merger = _mod_merge.Merger.from_revision_ids( |
4258 | mem_tree, other_revision_id) |
4259 | merger.set_interesting_files(interesting_files) |
4260 | - # It seems there is no matching function for set_interesting_ids |
4261 | - merger.interesting_ids = interesting_ids |
4262 | merger.merge_type = _mod_merge.Merge3Merger |
4263 | return merger |
4264 | |
4265 | @@ -1400,10 +1397,9 @@ |
4266 | class TestMergerEntriesLCA(TestMergerBase): |
4267 | |
4268 | def make_merge_obj(self, builder, other_revision_id, |
4269 | - interesting_files=None, interesting_ids=None): |
4270 | + interesting_files=None): |
4271 | merger = self.make_Merger(builder, other_revision_id, |
4272 | - interesting_files=interesting_files, |
4273 | - interesting_ids=interesting_ids) |
4274 | + interesting_files=interesting_files) |
4275 | return merger.make_merger() |
4276 | |
4277 | def test_simple(self): |
4278 | @@ -1435,6 +1431,7 @@ |
4279 | # BASE, lca1, lca2, OTHER, THIS |
4280 | root_id = 'a-root-id' |
4281 | self.assertEqual([('a-id', True, |
4282 | + ((u'a', [u'a', u'a']), u'a', u'a'), |
4283 | ((root_id, [root_id, root_id]), root_id, root_id), |
4284 | ((u'a', [u'a', u'a']), u'a', u'a'), |
4285 | ((False, [False, False]), False, False)), |
4286 | @@ -1480,6 +1477,7 @@ |
4287 | entries = list(merge_obj._entries_lca()) |
4288 | root_id = 'a-root-id' |
4289 | self.assertEqual([('bar-id', True, |
4290 | + ((None, [u'bar', u'bar']), u'bar', u'bar'), |
4291 | ((None, [root_id, root_id]), root_id, root_id), |
4292 | ((None, [u'bar', u'bar']), u'bar', u'bar'), |
4293 | ((None, [False, False]), False, False)), |
4294 | @@ -1512,6 +1510,7 @@ |
4295 | entries = list(merge_obj._entries_lca()) |
4296 | root_id = 'a-root-id' |
4297 | self.assertEqual([('a-id', True, |
4298 | + ((u'a', [u'a', u'a']), u'a', None), |
4299 | ((root_id, [root_id, root_id]), root_id, None), |
4300 | ((u'a', [u'a', u'a']), u'a', None), |
4301 | ((False, [False, False]), False, None)), |
4302 | @@ -1562,6 +1561,7 @@ |
4303 | entries = list(merge_obj._entries_lca()) |
4304 | root_id = 'a-root-id' |
4305 | self.assertEqual([('a-id', True, |
4306 | + ((u'a', [u'a', u'a']), None, u'a'), |
4307 | ((root_id, [root_id, root_id]), None, root_id), |
4308 | ((u'a', [u'a', u'a']), None, u'a'), |
4309 | ((False, [False, False]), None, False)), |
4310 | @@ -1627,6 +1627,7 @@ |
4311 | entries = list(merge_obj._entries_lca()) |
4312 | root_id = 'a-root-id' |
4313 | self.assertEqual([('foo-id', True, |
4314 | + ((u'foo', [u'foo', None]), None, u'foo'), |
4315 | ((root_id, [root_id, None]), None, root_id), |
4316 | ((u'foo', [u'foo', None]), None, 'foo'), |
4317 | ((False, [False, None]), None, False)), |
4318 | @@ -1681,6 +1682,7 @@ |
4319 | entries = list(merge_obj._entries_lca()) |
4320 | root_id = 'a-root-id' |
4321 | self.assertEqual([('a-id', True, |
4322 | + ((None, [None, None]), u'a', None), |
4323 | ((None, [None, None]), root_id, None), |
4324 | ((None, [None, None]), u'a', None), |
4325 | ((None, [None, None]), False, None)), |
4326 | @@ -1843,6 +1845,7 @@ |
4327 | entries = list(merge_obj._entries_lca()) |
4328 | root_id = 'a-root-id' |
4329 | self.assertEqual([('foo-id', True, |
4330 | + ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4331 | ((root_id, [root_id, root_id]), root_id, root_id), |
4332 | ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4333 | ((False, [False, False]), False, False)), |
4334 | @@ -1880,6 +1883,7 @@ |
4335 | entries = list(merge_obj._entries_lca()) |
4336 | root_id = 'a-root-id' |
4337 | self.assertEqual([('foo-id', True, |
4338 | + ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4339 | ((root_id, [root_id, root_id]), root_id, root_id), |
4340 | ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4341 | ((False, [False, False]), False, False)), |
4342 | @@ -1941,6 +1945,7 @@ |
4343 | root_id = 'a-root-id' |
4344 | # The content was not changed, only the path |
4345 | self.assertEqual([('a-id', False, |
4346 | + ((u'a', [u'b', u'b']), u'b', u'a'), |
4347 | ((root_id, [root_id, root_id]), root_id, root_id), |
4348 | ((u'a', [u'a', u'a']), u'b', u'a'), |
4349 | ((False, [False, False]), False, False)), |
4350 | @@ -1966,6 +1971,7 @@ |
4351 | root_id = 'a-root-id' |
4352 | # Only the kind was changed (content) |
4353 | self.assertEqual([('a-id', True, |
4354 | + ((u'a', [u'a', u'a']), u'a', u'a'), |
4355 | ((root_id, [root_id, root_id]), root_id, root_id), |
4356 | ((u'a', [u'a', u'a']), u'a', u'a'), |
4357 | ((False, [False, False]), False, False)), |
4358 | @@ -2011,6 +2017,7 @@ |
4359 | entries = list(merge_obj._entries_lca()) |
4360 | root_id = 'a-root-id' |
4361 | self.assertEqual([('b-id', True, |
4362 | + ((u'b', [u'b', u'b']), u'b', u'b'), |
4363 | ((root_id, [root_id, root_id]), root_id, root_id), |
4364 | ((u'b', [u'b', u'b']), u'b', u'b'), |
4365 | ((False, [False, False]), False, False)), |
4366 | @@ -2038,6 +2045,7 @@ |
4367 | entries = list(merge_obj._entries_lca()) |
4368 | root_id = 'a-root-id' |
4369 | self.assertEqual([('b-id', True, |
4370 | + ((u'b', [u'b', u'b']), u'b', u'c'), |
4371 | ((root_id, [root_id, root_id]), root_id, root_id), |
4372 | ((u'b', [u'b', u'b']), u'b', u'c'), |
4373 | ((False, [False, False]), False, False)), |
4374 | @@ -2067,6 +2075,7 @@ |
4375 | entries = list(merge_obj._entries_lca()) |
4376 | root_id = 'a-root-id' |
4377 | self.assertEqual([('c-id', True, |
4378 | + ((u'c', [u'b', u'b']), u'b', u'b'), |
4379 | ((root_id, [root_id, root_id]), root_id, root_id), |
4380 | ((u'c', [u'b', u'b']), u'b', u'b'), |
4381 | ((False, [False, False]), False, False)), |
4382 | @@ -2094,12 +2103,13 @@ |
4383 | entries = list(merge_obj._entries_lca()) |
4384 | root_id = 'a-root-id' |
4385 | self.assertEqual([('b-id', True, |
4386 | + ((u'b', [u'b', u'b']), u'b', u'b'), |
4387 | ((root_id, [root_id, root_id]), root_id, root_id), |
4388 | ((u'b', [u'c', u'b']), u'b', u'b'), |
4389 | ((False, [False, False]), False, False)), |
4390 | ], entries) |
4391 | |
4392 | - def test_interesting_ids(self): |
4393 | + def test_interesting_files(self): |
4394 | # Two files modified, but we should filter one of them |
4395 | builder = self.get_builder() |
4396 | builder.build_snapshot(None, |
4397 | @@ -2114,10 +2124,11 @@ |
4398 | ('modify', ('b-id', 'new-content\n'))], revision_id='E-id') |
4399 | builder.build_snapshot(['B-id', 'C-id'], [], revision_id='D-id') |
4400 | merge_obj = self.make_merge_obj(builder, 'E-id', |
4401 | - interesting_ids=['b-id']) |
4402 | + interesting_files=['b']) |
4403 | entries = list(merge_obj._entries_lca()) |
4404 | root_id = 'a-root-id' |
4405 | self.assertEqual([('b-id', True, |
4406 | + ((u'b', [u'b', u'b']), u'b', u'b'), |
4407 | ((root_id, [root_id, root_id]), root_id, root_id), |
4408 | ((u'b', [u'b', u'b']), u'b', u'b'), |
4409 | ((False, [False, False]), False, False)), |
4410 | @@ -2253,7 +2264,7 @@ |
4411 | wt = self.get_wt_from_builder(builder) |
4412 | tt = transform.TreeTransform(wt) |
4413 | try: |
4414 | - tt.set_executability(True, tt.trans_id_tree_file_id('foo-id')) |
4415 | + tt.set_executability(True, tt.trans_id_tree_path('foo')) |
4416 | tt.apply() |
4417 | except: |
4418 | tt.finalize() |
4419 | @@ -2432,6 +2443,7 @@ |
4420 | entries = list(merge_obj._entries_lca()) |
4421 | # No content change, just a path change |
4422 | self.assertEqual([('foo-id', False, |
4423 | + ((u'foo', [u'blah', u'blah']), u'blah', u'barry'), |
4424 | ((root_id, [root_id, root_id]), root_id, root_id), |
4425 | ((u'foo', [u'barry', u'foo']), u'blah', u'barry'), |
4426 | ((False, [False, False]), False, False)), |
4427 | @@ -2536,6 +2548,7 @@ |
4428 | entries = list(merge_obj._entries_lca()) |
4429 | root_id = wt.path2id('') |
4430 | self.assertEqual([('foo-id', True, |
4431 | + ((None, [u'foo', None]), u'foo', u'foo'), |
4432 | ((None, [root_id, None]), root_id, root_id), |
4433 | ((None, [u'foo', None]), u'foo', u'foo'), |
4434 | ((None, [False, None]), False, False)), |
4435 | @@ -2597,6 +2610,7 @@ |
4436 | entries = list(merge_obj._entries_lca()) |
4437 | root_id = wt.path2id('') |
4438 | self.assertEqual([('foo-id', True, |
4439 | + ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4440 | ((root_id, [root_id, root_id]), root_id, root_id), |
4441 | ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4442 | ((False, [False, False]), False, False)), |
4443 | @@ -2720,10 +2734,12 @@ |
4444 | entries = list(merge_obj._entries_lca()) |
4445 | root_id = 'a-root-id' |
4446 | self.assertEqual([('a-id', False, |
4447 | + ((u'a', [u'c', u'c']), u'c', u'b'), |
4448 | ((root_id, [root_id, root_id]), root_id, root_id), |
4449 | ((u'a', [u'a', u'b']), u'c', u'b'), |
4450 | ((False, [False, False]), False, False)), |
4451 | ('foo-id', True, |
4452 | + ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4453 | ((root_id, [root_id, root_id]), root_id, root_id), |
4454 | ((u'foo', [u'foo', u'foo']), u'foo', u'foo'), |
4455 | ((False, [False, False]), False, False)), |
4456 | @@ -2838,6 +2854,7 @@ |
4457 | entries = list(merge_obj._entries_lca()) |
4458 | root_id = 'a-root-id' |
4459 | self.assertEqual([('sub-tree-root', False, |
4460 | + ((u'sub', [u'alt_sub', u'alt_sub']), u'alt_sub', u'sub'), |
4461 | ((root_id, [root_id, root_id]), root_id, root_id), |
4462 | ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'), |
4463 | ((False, [False, False]), False, False)), |
4464 | @@ -2882,6 +2899,7 @@ |
4465 | entries = list(merge_obj._entries_lca()) |
4466 | root_id = 'a-root-id' |
4467 | self.assertEqual([('sub-tree-root', False, |
4468 | + ((u'sub', [u'alt_sub', u'alt_sub']), u'alt_sub', u'sub'), |
4469 | ((root_id, [root_id, root_id]), root_id, root_id), |
4470 | ((u'sub', [u'sub', u'sub']), u'alt_sub', u'sub'), |
4471 | ((False, [False, False]), False, False)), |
4472 | |
4473 | === modified file 'breezy/tests/test_merge_core.py' |
4474 | --- breezy/tests/test_merge_core.py 2018-03-09 19:52:32 +0000 |
4475 | +++ breezy/tests/test_merge_core.py 2018-03-24 17:11:56 +0000 |
4476 | @@ -77,8 +77,8 @@ |
4477 | if option is True: |
4478 | new_file(tt) |
4479 | |
4480 | - def merge(self, merge_type=Merge3Merger, interesting_ids=None, **kwargs): |
4481 | - merger = self.make_merger(merge_type, interesting_ids, **kwargs) |
4482 | + def merge(self, merge_type=Merge3Merger, interesting_files=None, **kwargs): |
4483 | + merger = self.make_merger(merge_type, interesting_files, **kwargs) |
4484 | merger.do_merge() |
4485 | return merger.cooked_conflicts |
4486 | |
4487 | @@ -86,7 +86,7 @@ |
4488 | merger = self.make_merger(Merge3Merger, None, this_revision_tree=True) |
4489 | return merger.make_preview_transform() |
4490 | |
4491 | - def make_merger(self, merge_type, interesting_ids, |
4492 | + def make_merger(self, merge_type, interesting_files, |
4493 | this_revision_tree=False, **kwargs): |
4494 | self.base_tt.apply() |
4495 | self.base.commit('base commit') |
4496 | @@ -110,7 +110,7 @@ |
4497 | else: |
4498 | this_tree = self.this |
4499 | merger = merge_type(this_tree, self.this, self.base, other_basis, |
4500 | - interesting_ids=interesting_ids, do_merge=False, |
4501 | + interesting_files=interesting_files, do_merge=False, |
4502 | this_branch=self.this.branch, **kwargs) |
4503 | return merger |
4504 | |
4505 | @@ -251,7 +251,7 @@ |
4506 | builder.change_contents("1", other="text4") |
4507 | builder.add_file("2", builder.tree_root, "name2", "hello1", True) |
4508 | builder.change_contents("2", other="text4") |
4509 | - builder.merge(interesting_ids=["1"]) |
4510 | + builder.merge(interesting_files=["name1"]) |
4511 | self.assertEqual(builder.this.get_file("name1").read(), "text4" ) |
4512 | self.assertEqual(builder.this.get_file("name2").read(), "hello1" ) |
4513 | builder.cleanup() |
4514 | |
4515 | === modified file 'breezy/tests/test_revert.py' |
4516 | --- breezy/tests/test_revert.py 2017-11-12 17:53:35 +0000 |
4517 | +++ breezy/tests/test_revert.py 2018-03-24 17:11:56 +0000 |
4518 | @@ -97,7 +97,7 @@ |
4519 | def test_preserve_execute(self): |
4520 | tree = self.tree_with_executable() |
4521 | tt = transform.TreeTransform(tree) |
4522 | - newfile = tt.trans_id_tree_file_id('newfile-id') |
4523 | + newfile = tt.trans_id_tree_path('newfile') |
4524 | tt.delete_contents(newfile) |
4525 | tt.create_file('Woooorld!', newfile) |
4526 | tt.apply() |
4527 | @@ -112,7 +112,7 @@ |
4528 | def test_revert_executable(self): |
4529 | tree = self.tree_with_executable() |
4530 | tt = transform.TreeTransform(tree) |
4531 | - newfile = tt.trans_id_tree_file_id('newfile-id') |
4532 | + newfile = tt.trans_id_tree_path('newfile') |
4533 | tt.set_executability(False, newfile) |
4534 | tt.apply() |
4535 | tree.lock_write() |
4536 | |
4537 | === modified file 'breezy/tests/test_shelf.py' |
4538 | --- breezy/tests/test_shelf.py 2017-12-12 01:19:18 +0000 |
4539 | +++ breezy/tests/test_shelf.py 2018-03-24 17:11:56 +0000 |
4540 | @@ -206,7 +206,7 @@ |
4541 | |
4542 | def check_shelve_creation(self, creator, tree): |
4543 | self.assertRaises(StopIteration, |
4544 | - next, tree.iter_entries_by_dir(['foo-id'])) |
4545 | + next, tree.iter_entries_by_dir(specific_files=['foo'])) |
4546 | s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id') |
4547 | self.assertEqual('foo-id', |
4548 | creator.shelf_transform.final_file_id(s_trans_id)) |
4549 | @@ -349,7 +349,7 @@ |
4550 | creator.shelve_creation('foo-id') |
4551 | creator.transform() |
4552 | self.assertRaises(StopIteration, |
4553 | - next, tree.iter_entries_by_dir(['foo-id'])) |
4554 | + next, tree.iter_entries_by_dir(specific_files=['foo'])) |
4555 | self.assertShelvedFileEqual('', creator, 'foo-id') |
4556 | s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id') |
4557 | self.assertEqual('foo-id', |
4558 | |
4559 | === modified file 'breezy/tests/test_transform.py' |
4560 | --- breezy/tests/test_transform.py 2018-03-09 19:52:32 +0000 |
4561 | +++ breezy/tests/test_transform.py 2018-03-24 17:11:56 +0000 |
4562 | @@ -453,7 +453,7 @@ |
4563 | self.assertEqual(self.wt.path2id('name'), 'my_pretties') |
4564 | self.assertEqual('contents', file(self.wt.abspath('name')).read()) |
4565 | transform2, root = self.get_transform() |
4566 | - oz_id = transform2.trans_id_tree_file_id('oz-id') |
4567 | + oz_id = transform2.trans_id_tree_path('oz') |
4568 | newtip = transform2.new_file('tip', oz_id, 'other', 'tip-id') |
4569 | result = transform2.find_conflicts() |
4570 | fp = FinalPaths(transform2) |
4571 | @@ -467,12 +467,12 @@ |
4572 | transform2.finalize() |
4573 | transform3 = TreeTransform(self.wt) |
4574 | self.addCleanup(transform3.finalize) |
4575 | - oz_id = transform3.trans_id_tree_file_id('oz-id') |
4576 | + oz_id = transform3.trans_id_tree_path('oz') |
4577 | transform3.delete_contents(oz_id) |
4578 | self.assertEqual(transform3.find_conflicts(), |
4579 | [('missing parent', oz_id)]) |
4580 | root_id = transform3.root |
4581 | - tip_id = transform3.trans_id_tree_file_id('tip-id') |
4582 | + tip_id = transform3.trans_id_tree_path('oz/tip') |
4583 | transform3.adjust_path('tip', root_id, tip_id) |
4584 | transform3.apply() |
4585 | |
4586 | @@ -601,7 +601,7 @@ |
4587 | start.new_directory('a', root, 'a') |
4588 | start.apply() |
4589 | transform, root = self.get_transform() |
4590 | - transform.delete_versioned(transform.trans_id_tree_file_id('a')) |
4591 | + transform.delete_versioned(transform.trans_id_tree_path('a')) |
4592 | transform.new_directory('a', root, 'a') |
4593 | transform.apply() |
4594 | |
4595 | @@ -616,7 +616,7 @@ |
4596 | unversion.unversion_file(parent) |
4597 | self.assertEqual(unversion.find_conflicts(), |
4598 | [('unversioned parent', parent_id)]) |
4599 | - file_id = unversion.trans_id_tree_file_id('child-id') |
4600 | + file_id = unversion.trans_id_tree_path('parent/child') |
4601 | unversion.unversion_file(file_id) |
4602 | unversion.apply() |
4603 | |
4604 | @@ -635,23 +635,23 @@ |
4605 | mangle_tree, root = self.get_transform() |
4606 | root = mangle_tree.root |
4607 | #swap names |
4608 | - name1 = mangle_tree.trans_id_tree_file_id('name1') |
4609 | - name2 = mangle_tree.trans_id_tree_file_id('name2') |
4610 | + name1 = mangle_tree.trans_id_tree_path('name1') |
4611 | + name2 = mangle_tree.trans_id_tree_path('name2') |
4612 | mangle_tree.adjust_path('name2', root, name1) |
4613 | mangle_tree.adjust_path('name1', root, name2) |
4614 | |
4615 | #tests for deleting parent directories |
4616 | - ddir = mangle_tree.trans_id_tree_file_id('ddir') |
4617 | + ddir = mangle_tree.trans_id_tree_path('dying_directory') |
4618 | mangle_tree.delete_contents(ddir) |
4619 | - dfile = mangle_tree.trans_id_tree_file_id('dfile') |
4620 | + dfile = mangle_tree.trans_id_tree_path('dying_directory/dying_file') |
4621 | mangle_tree.delete_versioned(dfile) |
4622 | mangle_tree.unversion_file(dfile) |
4623 | - mfile = mangle_tree.trans_id_tree_file_id('mfile') |
4624 | + mfile = mangle_tree.trans_id_tree_path('dying_directory/moving_file') |
4625 | mangle_tree.adjust_path('mfile', root, mfile) |
4626 | |
4627 | #tests for adding parent directories |
4628 | newdir = mangle_tree.new_directory('new_directory', root, 'newdir') |
4629 | - mfile2 = mangle_tree.trans_id_tree_file_id('mfile2') |
4630 | + mfile2 = mangle_tree.trans_id_tree_path('moving_file2') |
4631 | mangle_tree.adjust_path('mfile2', newdir, mfile2) |
4632 | mangle_tree.new_file('newfile', newdir, 'hello3', 'dfile') |
4633 | self.assertEqual(mangle_tree.final_file_id(mfile2), 'mfile2') |
4634 | @@ -677,8 +677,8 @@ |
4635 | create_tree.new_file('blackbox.py', newdir, 'hello1', 'blackbox-id') |
4636 | create_tree.apply() |
4637 | mangle_tree, root = self.get_transform() |
4638 | - selftest = mangle_tree.trans_id_tree_file_id('selftest-id') |
4639 | - blackbox = mangle_tree.trans_id_tree_file_id('blackbox-id') |
4640 | + selftest = mangle_tree.trans_id_tree_path('selftest') |
4641 | + blackbox = mangle_tree.trans_id_tree_path('selftest/blackbox.py') |
4642 | mangle_tree.adjust_path('test', root, selftest) |
4643 | mangle_tree.adjust_path('test_too_much', root, selftest) |
4644 | mangle_tree.set_executability(True, blackbox) |
4645 | @@ -693,9 +693,9 @@ |
4646 | 'test_too_much-id') |
4647 | create_tree.apply() |
4648 | mangle_tree, root = self.get_transform() |
4649 | - breezy = mangle_tree.trans_id_tree_file_id('breezy-id') |
4650 | - tests = mangle_tree.trans_id_tree_file_id('tests-id') |
4651 | - test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id') |
4652 | + breezy = mangle_tree.trans_id_tree_path('breezy') |
4653 | + tests = mangle_tree.trans_id_tree_path('breezy/tests') |
4654 | + test_too_much = mangle_tree.trans_id_tree_path('breezy/tests/blackbox/test_too_much.py') |
4655 | mangle_tree.adjust_path('selftest', breezy, tests) |
4656 | mangle_tree.adjust_path('blackbox.py', tests, test_too_much) |
4657 | mangle_tree.set_executability(True, test_too_much) |
4658 | @@ -708,8 +708,8 @@ |
4659 | 'test_too_much-id') |
4660 | create_tree.apply() |
4661 | mangle_tree, root = self.get_transform() |
4662 | - tests = mangle_tree.trans_id_tree_file_id('tests-id') |
4663 | - test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id') |
4664 | + tests = mangle_tree.trans_id_tree_path('tests') |
4665 | + test_too_much = mangle_tree.trans_id_tree_path('tests/test_too_much.py') |
4666 | mangle_tree.adjust_path('selftest', root, tests) |
4667 | mangle_tree.adjust_path('blackbox.py', tests, test_too_much) |
4668 | mangle_tree.set_executability(True, test_too_much) |
4669 | @@ -722,11 +722,11 @@ |
4670 | create_tree.new_file('name1', root, 'hello1', 'name1') |
4671 | create_tree.apply() |
4672 | delete_contents, root = self.get_transform() |
4673 | - file = delete_contents.trans_id_tree_file_id('name1') |
4674 | + file = delete_contents.trans_id_tree_path('name1') |
4675 | delete_contents.delete_contents(file) |
4676 | delete_contents.apply() |
4677 | move_id, root = self.get_transform() |
4678 | - name1 = move_id.trans_id_tree_file_id('name1') |
4679 | + name1 = move_id.trans_id_tree_path('name1') |
4680 | newdir = move_id.new_directory('dir', root, 'newdir') |
4681 | move_id.adjust_path('name2', newdir, name1) |
4682 | move_id.apply() |
4683 | @@ -739,7 +739,7 @@ |
4684 | create_tree.apply() |
4685 | delete_contents = TreeTransform(self.wt) |
4686 | self.addCleanup(delete_contents.finalize) |
4687 | - file = delete_contents.trans_id_tree_file_id('name1') |
4688 | + file = delete_contents.trans_id_tree_path('name1') |
4689 | delete_contents.delete_contents(file) |
4690 | delete_contents.apply() |
4691 | delete_contents.finalize() |
4692 | @@ -747,7 +747,7 @@ |
4693 | self.addCleanup(replace.finalize) |
4694 | name2 = replace.new_file('name2', root, 'hello2', 'name1') |
4695 | conflicts = replace.find_conflicts() |
4696 | - name1 = replace.trans_id_tree_file_id('name1') |
4697 | + name1 = replace.trans_id_tree_path('name1') |
4698 | self.assertEqual(conflicts, [('duplicate id', name1, name2)]) |
4699 | resolve_conflicts(replace) |
4700 | replace.apply() |
4701 | @@ -819,11 +819,11 @@ |
4702 | # set up duplicate entry, duplicate id |
4703 | new_dorothy = conflicts.new_file('dorothy', root, 'dorothy', |
4704 | 'dorothy-id') |
4705 | - old_dorothy = conflicts.trans_id_tree_file_id('dorothy-id') |
4706 | - oz = conflicts.trans_id_tree_file_id('oz-id') |
4707 | + old_dorothy = conflicts.trans_id_tree_path('dorothy') |
4708 | + oz = conflicts.trans_id_tree_path('oz') |
4709 | # set up DeletedParent parent conflict |
4710 | conflicts.delete_versioned(oz) |
4711 | - emerald = conflicts.trans_id_tree_file_id('emerald-id') |
4712 | + emerald = conflicts.trans_id_tree_path('oz/emeraldcity') |
4713 | # set up MissingParent conflict |
4714 | munchkincity = conflicts.trans_id_file_id('munchkincity-id') |
4715 | conflicts.adjust_path('munchkincity', root, munchkincity) |
4716 | @@ -975,8 +975,8 @@ |
4717 | create.new_directory('oz', root, 'oz-id') |
4718 | create.apply() |
4719 | cyclone, root = self.get_transform() |
4720 | - oz = cyclone.trans_id_tree_file_id('oz-id') |
4721 | - house = cyclone.trans_id_tree_file_id('house-id') |
4722 | + oz = cyclone.trans_id_tree_path('oz') |
4723 | + house = cyclone.trans_id_tree_path('house') |
4724 | cyclone.adjust_path('house', oz, house) |
4725 | cyclone.apply() |
4726 | |
4727 | @@ -1080,7 +1080,7 @@ |
4728 | self.addCleanup(self.wt.unlock) |
4729 | self.assertTrue(self.wt.is_executable('file1')) |
4730 | transform, root = self.get_transform() |
4731 | - file1_id = transform.trans_id_tree_file_id('file1-id') |
4732 | + file1_id = transform.trans_id_tree_path('file1') |
4733 | transform.delete_contents(file1_id) |
4734 | transform.create_file('contents2', file1_id) |
4735 | transform.apply() |
4736 | @@ -1124,7 +1124,7 @@ |
4737 | transform, root = self.get_transform() |
4738 | try: |
4739 | self.assertEqual([], list(transform.iter_changes())) |
4740 | - old = transform.trans_id_tree_file_id('id-1') |
4741 | + old = transform.trans_id_tree_path('old') |
4742 | transform.unversion_file(old) |
4743 | self.assertEqual([('id-1', ('old', None), False, (True, False), |
4744 | ('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'), |
4745 | @@ -1162,7 +1162,7 @@ |
4746 | transform, root = self.get_transform() |
4747 | try: |
4748 | old = transform.trans_id_tree_path('old') |
4749 | - subdir = transform.trans_id_tree_file_id('subdir-id') |
4750 | + subdir = transform.trans_id_tree_path('subdir') |
4751 | new = transform.trans_id_tree_path('new') |
4752 | self.assertEqual([], list(transform.iter_changes())) |
4753 | |
4754 | @@ -1280,7 +1280,7 @@ |
4755 | transform, root = self.get_transform() |
4756 | try: |
4757 | old = transform.trans_id_tree_path('old') |
4758 | - subdir = transform.trans_id_tree_file_id('subdir-id') |
4759 | + subdir = transform.trans_id_tree_path('subdir') |
4760 | self.assertEqual([], list(transform.iter_changes())) |
4761 | transform.delete_contents(subdir) |
4762 | transform.create_directory(subdir) |
4763 | @@ -1651,7 +1651,7 @@ |
4764 | self.wt.set_root_id(root_id) |
4765 | self.b = self.wt.branch |
4766 | self.tt = TreeTransform(self.wt) |
4767 | - self.root = self.tt.trans_id_tree_file_id(self.wt.get_root_id()) |
4768 | + self.root = self.tt.trans_id_tree_path('') |
4769 | |
4770 | |
4771 | def conflict_text(tree, merge): |
4772 | @@ -1675,7 +1675,7 @@ |
4773 | with TransformPreview(tree) as tt: |
4774 | tt.unversion_file(tt.root) |
4775 | tt.version_file('new-id', tt.root) |
4776 | - foo_trans_id = tt.trans_id_tree_file_id('foo-id') |
4777 | + foo_trans_id = tt.trans_id_tree_path('foo') |
4778 | foo_tuple = ('foo', foo_trans_id) |
4779 | root_tuple = ('', tt.root) |
4780 | self.assertEqual([root_tuple, foo_tuple], tt._inventory_altered()) |
4781 | @@ -1687,7 +1687,7 @@ |
4782 | with TransformPreview(tree) as tt: |
4783 | tt.unversion_file(tt.root) |
4784 | tt.version_file(tree.get_root_id(), tt.root) |
4785 | - foo_trans_id = tt.trans_id_tree_file_id('foo-id') |
4786 | + foo_trans_id = tt.trans_id_tree_path('foo') |
4787 | self.assertEqual([], tt._inventory_altered()) |
4788 | |
4789 | |
4790 | @@ -2160,7 +2160,7 @@ |
4791 | self.requireFeature(HardlinkFeature) |
4792 | source = self.create_ab_tree() |
4793 | tt = TreeTransform(source) |
4794 | - trans_id = tt.trans_id_tree_file_id('file1-id') |
4795 | + trans_id = tt.trans_id_tree_path('file1') |
4796 | tt.set_executability(True, trans_id) |
4797 | tt.apply() |
4798 | self.assertTrue(source.is_executable('file1')) |
4799 | @@ -2669,7 +2669,7 @@ |
4800 | |
4801 | def test_resolve_create_parent_for_versioned_file(self): |
4802 | wt, tt = self.make_tt_with_versioned_dir() |
4803 | - dir_tid = tt.trans_id_tree_file_id('dir-id') |
4804 | + dir_tid = tt.trans_id_tree_path('dir') |
4805 | file_tid = tt.new_file('file', dir_tid, 'Contents', file_id='file-id') |
4806 | tt.delete_contents(dir_tid) |
4807 | tt.unversion_file(dir_tid) |
4808 | @@ -2680,7 +2680,7 @@ |
4809 | |
4810 | def test_non_versioned_file_create_conflict(self): |
4811 | wt, tt = self.make_tt_with_versioned_dir() |
4812 | - dir_tid = tt.trans_id_tree_file_id('dir-id') |
4813 | + dir_tid = tt.trans_id_tree_path('dir') |
4814 | tt.new_file('file', dir_tid, 'Contents') |
4815 | tt.delete_contents(dir_tid) |
4816 | tt.unversion_file(dir_tid) |
4817 | @@ -2837,7 +2837,7 @@ |
4818 | work_tree.add('file', 'file-id') |
4819 | preview = TransformPreview(work_tree) |
4820 | self.addCleanup(preview.finalize) |
4821 | - file_trans_id = preview.trans_id_tree_file_id('file-id') |
4822 | + file_trans_id = preview.trans_id_tree_path('file') |
4823 | preview.adjust_path('renamed', preview.root, file_trans_id) |
4824 | preview_tree = preview.get_preview_tree() |
4825 | preview_mtime = preview_tree.get_file_mtime('renamed', 'file-id') |
4826 | @@ -2937,13 +2937,14 @@ |
4827 | self.assertFalse(preview_tree.is_versioned('old_name/child')) |
4828 | self.assertEqual('child-id', preview_tree.path2id('new_name/child')) |
4829 | |
4830 | - def assertMatchingIterEntries(self, tt, specific_file_ids=None): |
4831 | + def assertMatchingIterEntries(self, tt, specific_files=None): |
4832 | preview_tree = tt.get_preview_tree() |
4833 | preview_result = list(preview_tree.iter_entries_by_dir( |
4834 | - specific_file_ids)) |
4835 | + specific_files=specific_files)) |
4836 | tree = tt._tree |
4837 | tt.apply() |
4838 | - actual_result = list(tree.iter_entries_by_dir(specific_file_ids)) |
4839 | + actual_result = list(tree.iter_entries_by_dir( |
4840 | + specific_files=specific_files)) |
4841 | self.assertEqual(actual_result, preview_result) |
4842 | |
4843 | def test_iter_entries_by_dir_new(self): |
4844 | @@ -2977,13 +2978,13 @@ |
4845 | tt.trans_id_file_id('moved-id')) |
4846 | self.assertMatchingIterEntries(tt) |
4847 | |
4848 | - def test_iter_entries_by_dir_specific_file_ids(self): |
4849 | + def test_iter_entries_by_dir_specific_files(self): |
4850 | tree = self.make_branch_and_tree('tree') |
4851 | tree.set_root_id('tree-root-id') |
4852 | self.build_tree(['tree/parent/', 'tree/parent/child']) |
4853 | tree.add(['parent', 'parent/child'], ['parent-id', 'child-id']) |
4854 | tt = TreeTransform(tree) |
4855 | - self.assertMatchingIterEntries(tt, ['tree-root-id', 'child-id']) |
4856 | + self.assertMatchingIterEntries(tt, ['', 'parent/child']) |
4857 | |
4858 | def test_symlink_content_summary(self): |
4859 | self.requireFeature(SymlinkFeature) |
4860 | @@ -3455,9 +3456,9 @@ |
4861 | |
4862 | def test_serialize_destruction(self): |
4863 | tt = self.make_destruction_preview() |
4864 | - foo_trans_id = tt.trans_id_tree_file_id('foo-id') |
4865 | + foo_trans_id = tt.trans_id_tree_path(u'foo\u1234') |
4866 | tt.unversion_file(foo_trans_id) |
4867 | - bar_trans_id = tt.trans_id_tree_file_id('bar-id') |
4868 | + bar_trans_id = tt.trans_id_tree_path('bar') |
4869 | tt.delete_contents(bar_trans_id) |
4870 | self.assertSerializesTo(self.destruction_records(), tt) |
4871 | |
4872 | @@ -3612,7 +3613,7 @@ |
4873 | self.assertRaises(NotImplementedError, tt.new_orphan, 'foo', 'bar') |
4874 | |
4875 | def _set_orphan_policy(self, wt, policy): |
4876 | - wt.branch.get_config_stack().set('bzr.transform.orphan_policy', |
4877 | + wt.branch.get_config_stack().set('transform.orphan_policy', |
4878 | policy) |
4879 | |
4880 | def _prepare_orphan(self, wt): |
4881 | @@ -3741,7 +3742,7 @@ |
4882 | self.parent_tree.lock_write() |
4883 | self.addCleanup(self.parent_tree.unlock) |
4884 | self.build_tree_contents([('parent/foo', 'bar')]) |
4885 | - self.parent_tree.add('foo', 'foo-id') |
4886 | + self.parent_tree.add('foo') |
4887 | self.parent_tree.commit('added foo') |
4888 | child_controldir = self.parent_tree.controldir.sprout('child') |
4889 | self.child_tree = child_controldir.open_workingtree() |
4890 | @@ -3761,7 +3762,7 @@ |
4891 | """If the file to be linked has modified execute bit, don't link.""" |
4892 | tt = TreeTransform(self.child_tree) |
4893 | try: |
4894 | - trans_id = tt.trans_id_tree_file_id('foo-id') |
4895 | + trans_id = tt.trans_id_tree_path('foo') |
4896 | tt.set_executability(True, trans_id) |
4897 | tt.apply() |
4898 | finally: |
4899 | |
4900 | === modified file 'breezy/tests/test_workingtree.py' |
4901 | --- breezy/tests/test_workingtree.py 2018-02-11 17:07:38 +0000 |
4902 | +++ breezy/tests/test_workingtree.py 2018-03-24 17:11:56 +0000 |
4903 | @@ -257,7 +257,8 @@ |
4904 | subtree = self.make_branch_and_tree('tree/a/b') |
4905 | self.assertEqual([('tree-reference', 'b-id')], |
4906 | [(ie.kind, ie.file_id) |
4907 | - for path, ie in tree.iter_entries_by_dir(['b-id'])]) |
4908 | + for path, ie in tree.iter_entries_by_dir( |
4909 | + specific_files=['a/b'])]) |
4910 | |
4911 | def test_direct_subtree(self): |
4912 | tree = self.make_simple_tree() |
4913 | |
4914 | === modified file 'breezy/transform.py' |
4915 | --- breezy/transform.py 2018-03-12 05:18:13 +0000 |
4916 | +++ breezy/transform.py 2018-03-24 17:11:56 +0000 |
4917 | @@ -93,8 +93,7 @@ |
4918 | class TreeTransformBase(object): |
4919 | """The base class for TreeTransform and its kin.""" |
4920 | |
4921 | - def __init__(self, tree, pb=None, |
4922 | - case_sensitive=True): |
4923 | + def __init__(self, tree, pb=None, case_sensitive=True): |
4924 | """Constructor. |
4925 | |
4926 | :param tree: The tree that will be transformed, but not necessarily |
4927 | @@ -135,7 +134,7 @@ |
4928 | # The trans_id that will be used as the tree root |
4929 | root_id = tree.get_root_id() |
4930 | if root_id is not None: |
4931 | - self._new_root = self.trans_id_tree_file_id(root_id) |
4932 | + self._new_root = self.trans_id_tree_path('') |
4933 | else: |
4934 | self._new_root = None |
4935 | # Indicator of whether the transform has been applied |
4936 | @@ -219,7 +218,7 @@ |
4937 | # the physical root needs a new transaction id |
4938 | self._tree_path_ids.pop("") |
4939 | self._tree_id_paths.pop(old_root) |
4940 | - self._new_root = self.trans_id_tree_file_id(self._tree.get_root_id()) |
4941 | + self._new_root = self.trans_id_tree_path('') |
4942 | if parent == old_root: |
4943 | parent = self._new_root |
4944 | self.adjust_path(name, parent, old_root) |
4945 | @@ -288,17 +287,6 @@ |
4946 | del self._new_parent[old_new_root] |
4947 | del self._new_name[old_new_root] |
4948 | |
4949 | - def trans_id_tree_file_id(self, inventory_id): |
4950 | - """Determine the transaction id of a working tree file. |
4951 | - |
4952 | - This reflects only files that already exist, not ones that will be |
4953 | - added by transactions. |
4954 | - """ |
4955 | - if inventory_id is None: |
4956 | - raise ValueError('None is not a valid file id') |
4957 | - path = self._tree.id2path(inventory_id) |
4958 | - return self.trans_id_tree_path(path) |
4959 | - |
4960 | def trans_id_file_id(self, file_id): |
4961 | """Determine or set the transaction id associated with a file ID. |
4962 | A new id is only created for file_ids that were never present. If |
4963 | @@ -311,8 +299,8 @@ |
4964 | return self._r_new_id[file_id] |
4965 | else: |
4966 | try: |
4967 | - next(self._tree.iter_entries_by_dir([file_id])) |
4968 | - except StopIteration: |
4969 | + path = self._tree.id2path(file_id) |
4970 | + except errors.NoSuchId: |
4971 | if file_id in self._non_present_ids: |
4972 | return self._non_present_ids[file_id] |
4973 | else: |
4974 | @@ -320,7 +308,7 @@ |
4975 | self._non_present_ids[file_id] = trans_id |
4976 | return trans_id |
4977 | else: |
4978 | - return self.trans_id_tree_file_id(file_id) |
4979 | + return self.trans_id_tree_path(path) |
4980 | |
4981 | def trans_id_tree_path(self, path): |
4982 | """Determine (and maybe set) the transaction ID for a tree path.""" |
4983 | @@ -457,12 +445,14 @@ |
4984 | else: |
4985 | return self.tree_kind(trans_id) |
4986 | |
4987 | + def tree_path(self, trans_id): |
4988 | + """Determine the tree path associated with the trans_id.""" |
4989 | + return self._tree_id_paths.get(trans_id) |
4990 | + |
4991 | def tree_file_id(self, trans_id): |
4992 | """Determine the file id associated with the trans_id in the tree""" |
4993 | - try: |
4994 | - path = self._tree_id_paths[trans_id] |
4995 | - except KeyError: |
4996 | - # the file is a new, unversioned file, or invalid trans_id |
4997 | + path = self.tree_path(trans_id) |
4998 | + if path is None: |
4999 | return None |
5000 | # the file is old; the old id is still valid |
The diff has been truncated for viewing.