Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/objects-2c |
Merge into: | lp:brz |
Diff against target: |
500 lines (+62/-73) 8 files modified
breezy/bzr/inventorytree.py (+7/-6) breezy/merge.py (+31/-41) breezy/plugins/changelog_merge/tests/test_changelog_merge.py (+3/-4) breezy/tests/per_merger.py (+15/-14) breezy/tests/per_tree/test_tree.py (+1/-2) breezy/tests/per_workingtree/test_merge_from_branch.py (+1/-1) breezy/tests/test_transform.py (+2/-2) breezy/transform.py (+2/-3) |
To merge this branch: | bzr merge lp:~jelmer/brz/objects-2c |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Packman | Approve | ||
Review via email: mp+368932@code.launchpad.net |
Commit message
Drop file_id attribute from MergeHookParams and Tree.plan_
Description of the change
Drop file_id attribute from MergeHookParams and Tree.plan_
(This depends on objects-2a and objects-2b, but I can't set two prerequisite branches)
To post a comment you must log in.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Merging failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/bzr/inventorytree.py' | |||
2 | --- breezy/bzr/inventorytree.py 2019-06-21 16:18:13 +0000 | |||
3 | +++ breezy/bzr/inventorytree.py 2019-06-22 13:51:41 +0000 | |||
4 | @@ -215,11 +215,12 @@ | |||
5 | 215 | raise errors.NotADirectory(path) | 215 | raise errors.NotADirectory(path) |
6 | 216 | return iter(viewvalues(ie.children)) | 216 | return iter(viewvalues(ie.children)) |
7 | 217 | 217 | ||
9 | 218 | def _get_plan_merge_data(self, file_id, other, base): | 218 | def _get_plan_merge_data(self, path, other, base): |
10 | 219 | from . import versionedfile | 219 | from . import versionedfile |
11 | 220 | file_id = self.path2id(path) | ||
12 | 220 | vf = versionedfile._PlanMergeVersionedFile(file_id) | 221 | vf = versionedfile._PlanMergeVersionedFile(file_id) |
13 | 221 | last_revision_a = self._get_file_revision( | 222 | last_revision_a = self._get_file_revision( |
15 | 222 | self.id2path(file_id), file_id, vf, b'this:') | 223 | path, file_id, vf, b'this:') |
16 | 223 | last_revision_b = other._get_file_revision( | 224 | last_revision_b = other._get_file_revision( |
17 | 224 | other.id2path(file_id), file_id, vf, b'other:') | 225 | other.id2path(file_id), file_id, vf, b'other:') |
18 | 225 | if base is None: | 226 | if base is None: |
19 | @@ -229,7 +230,7 @@ | |||
20 | 229 | base.id2path(file_id), file_id, vf, b'base:') | 230 | base.id2path(file_id), file_id, vf, b'base:') |
21 | 230 | return vf, last_revision_a, last_revision_b, last_revision_base | 231 | return vf, last_revision_a, last_revision_b, last_revision_base |
22 | 231 | 232 | ||
24 | 232 | def plan_file_merge(self, file_id, other, base=None): | 233 | def plan_file_merge(self, path, other, base=None): |
25 | 233 | """Generate a merge plan based on annotations. | 234 | """Generate a merge plan based on annotations. |
26 | 234 | 235 | ||
27 | 235 | If the file contains uncommitted changes in this tree, they will be | 236 | If the file contains uncommitted changes in this tree, they will be |
28 | @@ -237,12 +238,12 @@ | |||
29 | 237 | uncommitted changes in the other tree, they will be assigned to the | 238 | uncommitted changes in the other tree, they will be assigned to the |
30 | 238 | 'other:' pseudo-revision. | 239 | 'other:' pseudo-revision. |
31 | 239 | """ | 240 | """ |
33 | 240 | data = self._get_plan_merge_data(file_id, other, base) | 241 | data = self._get_plan_merge_data(path, other, base) |
34 | 241 | vf, last_revision_a, last_revision_b, last_revision_base = data | 242 | vf, last_revision_a, last_revision_b, last_revision_base = data |
35 | 242 | return vf.plan_merge(last_revision_a, last_revision_b, | 243 | return vf.plan_merge(last_revision_a, last_revision_b, |
36 | 243 | last_revision_base) | 244 | last_revision_base) |
37 | 244 | 245 | ||
39 | 245 | def plan_file_lca_merge(self, file_id, other, base=None): | 246 | def plan_file_lca_merge(self, path, other, base=None): |
40 | 246 | """Generate a merge plan based lca-newness. | 247 | """Generate a merge plan based lca-newness. |
41 | 247 | 248 | ||
42 | 248 | If the file contains uncommitted changes in this tree, they will be | 249 | If the file contains uncommitted changes in this tree, they will be |
43 | @@ -250,7 +251,7 @@ | |||
44 | 250 | uncommitted changes in the other tree, they will be assigned to the | 251 | uncommitted changes in the other tree, they will be assigned to the |
45 | 251 | 'other:' pseudo-revision. | 252 | 'other:' pseudo-revision. |
46 | 252 | """ | 253 | """ |
48 | 253 | data = self._get_plan_merge_data(file_id, other, base) | 254 | data = self._get_plan_merge_data(path, other, base) |
49 | 254 | vf, last_revision_a, last_revision_b, last_revision_base = data | 255 | vf, last_revision_a, last_revision_b, last_revision_base = data |
50 | 255 | return vf.plan_lca_merge(last_revision_a, last_revision_b, | 256 | return vf.plan_lca_merge(last_revision_a, last_revision_b, |
51 | 256 | last_revision_base) | 257 | last_revision_base) |
52 | 257 | 258 | ||
53 | === modified file 'breezy/merge.py' | |||
54 | --- breezy/merge.py 2019-06-22 11:16:17 +0000 | |||
55 | +++ breezy/merge.py 2019-06-22 13:51:41 +0000 | |||
56 | @@ -223,20 +223,18 @@ | |||
57 | 223 | 223 | ||
58 | 224 | There are some fields hooks can access: | 224 | There are some fields hooks can access: |
59 | 225 | 225 | ||
60 | 226 | :ivar file_id: the file ID of the file being merged | ||
61 | 227 | :ivar base_path: Path in base tree | 226 | :ivar base_path: Path in base tree |
62 | 228 | :ivar other_path: Path in other tree | 227 | :ivar other_path: Path in other tree |
63 | 229 | :ivar this_path: Path in this tree | 228 | :ivar this_path: Path in this tree |
64 | 230 | :ivar trans_id: the transform ID for the merge of this file | 229 | :ivar trans_id: the transform ID for the merge of this file |
67 | 231 | :ivar this_kind: kind of file_id in 'this' tree | 230 | :ivar this_kind: kind of file in 'this' tree |
68 | 232 | :ivar other_kind: kind of file_id in 'other' tree | 231 | :ivar other_kind: kind of file in 'other' tree |
69 | 233 | :ivar winner: one of 'this', 'other', 'conflict' | 232 | :ivar winner: one of 'this', 'other', 'conflict' |
70 | 234 | """ | 233 | """ |
71 | 235 | 234 | ||
73 | 236 | def __init__(self, merger, file_id, paths, trans_id, this_kind, other_kind, | 235 | def __init__(self, merger, paths, trans_id, this_kind, other_kind, |
74 | 237 | winner): | 236 | winner): |
75 | 238 | self._merger = merger | 237 | self._merger = merger |
76 | 239 | self.file_id = file_id | ||
77 | 240 | self.paths = paths | 238 | self.paths = paths |
78 | 241 | self.base_path, self.other_path, self.this_path = paths | 239 | self.base_path, self.other_path, self.this_path = paths |
79 | 242 | self.trans_id = trans_id | 240 | self.trans_id = trans_id |
80 | @@ -804,16 +802,18 @@ | |||
81 | 804 | with ui.ui_factory.nested_progress_bar() as child_pb: | 802 | with ui.ui_factory.nested_progress_bar() as child_pb: |
82 | 805 | for num, (file_id, changed, paths3, parents3, names3, | 803 | for num, (file_id, changed, paths3, parents3, names3, |
83 | 806 | executable3) in enumerate(entries): | 804 | executable3) in enumerate(entries): |
84 | 805 | trans_id = self.tt.trans_id_file_id(file_id) | ||
85 | 806 | |||
86 | 807 | # Try merging each entry | 807 | # Try merging each entry |
87 | 808 | child_pb.update(gettext('Preparing file merge'), | 808 | child_pb.update(gettext('Preparing file merge'), |
88 | 809 | num, len(entries)) | 809 | num, len(entries)) |
90 | 810 | self._merge_names(file_id, paths3, parents3, | 810 | self._merge_names(trans_id, file_id, paths3, parents3, |
91 | 811 | names3, resolver=resolver) | 811 | names3, resolver=resolver) |
92 | 812 | if changed: | 812 | if changed: |
94 | 813 | file_status = self._do_merge_contents(paths3, file_id) | 813 | file_status = self._do_merge_contents(paths3, trans_id, file_id) |
95 | 814 | else: | 814 | else: |
96 | 815 | file_status = 'unmodified' | 815 | file_status = 'unmodified' |
98 | 816 | self._merge_executable(paths3, file_id, executable3, | 816 | self._merge_executable(paths3, trans_id, executable3, |
99 | 817 | file_status, resolver=resolver) | 817 | file_status, resolver=resolver) |
100 | 818 | self.tt.fixup_new_roots() | 818 | self.tt.fixup_new_roots() |
101 | 819 | self._finish_computing_transform() | 819 | self._finish_computing_transform() |
102 | @@ -1182,8 +1182,8 @@ | |||
103 | 1182 | # At this point, the lcas disagree, and the tip disagree | 1182 | # At this point, the lcas disagree, and the tip disagree |
104 | 1183 | return 'conflict' | 1183 | return 'conflict' |
105 | 1184 | 1184 | ||
108 | 1185 | def _merge_names(self, file_id, paths, parents, names, resolver): | 1185 | def _merge_names(self, trans_id, file_id, paths, parents, names, resolver): |
109 | 1186 | """Perform a merge on file_id names and parents""" | 1186 | """Perform a merge on file names and parents""" |
110 | 1187 | base_name, other_name, this_name = names | 1187 | base_name, other_name, this_name = names |
111 | 1188 | base_parent, other_parent, this_parent = parents | 1188 | base_parent, other_parent, this_parent = parents |
112 | 1189 | unused_base_path, other_path, this_path = paths | 1189 | unused_base_path, other_path, this_path = paths |
113 | @@ -1202,7 +1202,6 @@ | |||
114 | 1202 | # Creating helpers (.OTHER or .THIS) here cause problems down the | 1202 | # Creating helpers (.OTHER or .THIS) here cause problems down the |
115 | 1203 | # road if a ContentConflict needs to be created so we should not do | 1203 | # road if a ContentConflict needs to be created so we should not do |
116 | 1204 | # that | 1204 | # that |
117 | 1205 | trans_id = self.tt.trans_id_file_id(file_id) | ||
118 | 1206 | self._raw_conflicts.append(('path conflict', trans_id, file_id, | 1205 | self._raw_conflicts.append(('path conflict', trans_id, file_id, |
119 | 1207 | this_parent, this_name, | 1206 | this_parent, this_name, |
120 | 1208 | other_parent, other_name)) | 1207 | other_parent, other_name)) |
121 | @@ -1225,10 +1224,9 @@ | |||
122 | 1225 | parent_trans_id = transform.ROOT_PARENT | 1224 | parent_trans_id = transform.ROOT_PARENT |
123 | 1226 | else: | 1225 | else: |
124 | 1227 | parent_trans_id = self.tt.trans_id_file_id(parent_id) | 1226 | parent_trans_id = self.tt.trans_id_file_id(parent_id) |
127 | 1228 | self.tt.adjust_path(name, parent_trans_id, | 1227 | self.tt.adjust_path(name, parent_trans_id, trans_id) |
126 | 1229 | self.tt.trans_id_file_id(file_id)) | ||
128 | 1230 | 1228 | ||
130 | 1231 | def _do_merge_contents(self, paths, file_id): | 1229 | def _do_merge_contents(self, paths, trans_id, file_id): |
131 | 1232 | """Performs a merge on file_id contents.""" | 1230 | """Performs a merge on file_id contents.""" |
132 | 1233 | def contents_pair(tree, path): | 1231 | def contents_pair(tree, path): |
133 | 1234 | if path is None: | 1232 | if path is None: |
134 | @@ -1272,10 +1270,8 @@ | |||
135 | 1272 | return "unmodified" | 1270 | return "unmodified" |
136 | 1273 | # We have a hypothetical conflict, but if we have files, then we | 1271 | # We have a hypothetical conflict, but if we have files, then we |
137 | 1274 | # can try to merge the content | 1272 | # can try to merge the content |
138 | 1275 | trans_id = self.tt.trans_id_file_id(file_id) | ||
139 | 1276 | params = MergeFileHookParams( | 1273 | params = MergeFileHookParams( |
142 | 1277 | self, file_id, (base_path, other_path, | 1274 | self, (base_path, other_path, this_path), trans_id, this_pair[0], |
141 | 1278 | this_path), trans_id, this_pair[0], | ||
143 | 1279 | other_pair[0], winner) | 1275 | other_pair[0], winner) |
144 | 1280 | hooks = self.active_hooks | 1276 | hooks = self.active_hooks |
145 | 1281 | hook_status = 'not_applicable' | 1277 | hook_status = 'not_applicable' |
146 | @@ -1372,8 +1368,8 @@ | |||
147 | 1372 | return 'delete', None | 1368 | return 'delete', None |
148 | 1373 | else: | 1369 | else: |
149 | 1374 | raise AssertionError( | 1370 | raise AssertionError( |
152 | 1375 | 'winner is OTHER, but file_id %r not in THIS or OTHER tree' | 1371 | 'winner is OTHER, but file %r not in THIS or OTHER tree' |
153 | 1376 | % (file_id,)) | 1372 | % (merge_hook_params.base_path,)) |
154 | 1377 | 1373 | ||
155 | 1378 | def merge_contents(self, merge_hook_params): | 1374 | def merge_contents(self, merge_hook_params): |
156 | 1379 | """Fallback merge logic after user installed hooks.""" | 1375 | """Fallback merge logic after user installed hooks.""" |
157 | @@ -1389,7 +1385,7 @@ | |||
158 | 1389 | # have agreement that output should be a file. | 1385 | # have agreement that output should be a file. |
159 | 1390 | try: | 1386 | try: |
160 | 1391 | self.text_merge(merge_hook_params.trans_id, | 1387 | self.text_merge(merge_hook_params.trans_id, |
162 | 1392 | merge_hook_params.paths, merge_hook_params.file_id) | 1388 | merge_hook_params.paths) |
163 | 1393 | except errors.BinaryFile: | 1389 | except errors.BinaryFile: |
164 | 1394 | return 'not_applicable', None | 1390 | return 'not_applicable', None |
165 | 1395 | return 'done', None | 1391 | return 'done', None |
166 | @@ -1409,8 +1405,8 @@ | |||
167 | 1409 | return [] | 1405 | return [] |
168 | 1410 | return tree.get_file_lines(path) | 1406 | return tree.get_file_lines(path) |
169 | 1411 | 1407 | ||
172 | 1412 | def text_merge(self, trans_id, paths, file_id): | 1408 | def text_merge(self, trans_id, paths): |
173 | 1413 | """Perform a three-way text merge on a file_id""" | 1409 | """Perform a three-way text merge on a file""" |
174 | 1414 | # it's possible that we got here with base as a different type. | 1410 | # it's possible that we got here with base as a different type. |
175 | 1415 | # if so, we just want two-way text conflicts. | 1411 | # if so, we just want two-way text conflicts. |
176 | 1416 | base_path, other_path, this_path = paths | 1412 | base_path, other_path, this_path = paths |
177 | @@ -1445,6 +1441,7 @@ | |||
178 | 1445 | self._raw_conflicts.append(('text conflict', trans_id)) | 1441 | self._raw_conflicts.append(('text conflict', trans_id)) |
179 | 1446 | name = self.tt.final_name(trans_id) | 1442 | name = self.tt.final_name(trans_id) |
180 | 1447 | parent_id = self.tt.final_parent(trans_id) | 1443 | parent_id = self.tt.final_parent(trans_id) |
181 | 1444 | file_id = self.tt.final_file_id(trans_id) | ||
182 | 1448 | file_group = self._dump_conflicts(name, paths, parent_id, file_id, | 1445 | file_group = self._dump_conflicts(name, paths, parent_id, file_id, |
183 | 1449 | this_lines, base_lines, | 1446 | this_lines, base_lines, |
184 | 1450 | other_lines) | 1447 | other_lines) |
185 | @@ -1515,14 +1512,7 @@ | |||
186 | 1515 | filter_tree_path=filter_tree_path) | 1512 | filter_tree_path=filter_tree_path) |
187 | 1516 | return trans_id | 1513 | return trans_id |
188 | 1517 | 1514 | ||
197 | 1518 | def merge_executable(self, paths, file_id, file_status): | 1515 | def _merge_executable(self, paths, trans_id, executable, file_status, |
190 | 1519 | """Perform a merge on the execute bit.""" | ||
191 | 1520 | executable = [self.executable(t, p, file_id) | ||
192 | 1521 | for t, p in zip([self.base_tree, self.other_tree, self.this_tree], paths)] | ||
193 | 1522 | self._merge_executable(paths, file_id, executable, file_status, | ||
194 | 1523 | resolver=self._three_way) | ||
195 | 1524 | |||
196 | 1525 | def _merge_executable(self, paths, file_id, executable, file_status, | ||
198 | 1526 | resolver): | 1516 | resolver): |
199 | 1527 | """Perform a merge on the execute bit.""" | 1517 | """Perform a merge on the execute bit.""" |
200 | 1528 | base_executable, other_executable, this_executable = executable | 1518 | base_executable, other_executable, this_executable = executable |
201 | @@ -1539,7 +1529,6 @@ | |||
202 | 1539 | winner = "other" | 1529 | winner = "other" |
203 | 1540 | if winner == 'this' and file_status != "modified": | 1530 | if winner == 'this' and file_status != "modified": |
204 | 1541 | return | 1531 | return |
205 | 1542 | trans_id = self.tt.trans_id_file_id(file_id) | ||
206 | 1543 | if self.tt.final_kind(trans_id) != "file": | 1532 | if self.tt.final_kind(trans_id) != "file": |
207 | 1544 | return | 1533 | return |
208 | 1545 | if winner == "this": | 1534 | if winner == "this": |
209 | @@ -1552,7 +1541,6 @@ | |||
210 | 1552 | elif base_path is not None: | 1541 | elif base_path is not None: |
211 | 1553 | executability = base_executable | 1542 | executability = base_executable |
212 | 1554 | if executability is not None: | 1543 | if executability is not None: |
213 | 1555 | trans_id = self.tt.trans_id_file_id(file_id) | ||
214 | 1556 | self.tt.set_executability(executability, trans_id) | 1544 | self.tt.set_executability(executability, trans_id) |
215 | 1557 | 1545 | ||
216 | 1558 | def cook_conflicts(self, fs_conflicts): | 1546 | def cook_conflicts(self, fs_conflicts): |
217 | @@ -1634,11 +1622,11 @@ | |||
218 | 1634 | history_based = True | 1622 | history_based = True |
219 | 1635 | requires_file_merge_plan = True | 1623 | requires_file_merge_plan = True |
220 | 1636 | 1624 | ||
223 | 1637 | def _generate_merge_plan(self, file_id, base): | 1625 | def _generate_merge_plan(self, this_path, base): |
224 | 1638 | return self.this_tree.plan_file_merge(file_id, self.other_tree, | 1626 | return self.this_tree.plan_file_merge(this_path, self.other_tree, |
225 | 1639 | base=base) | 1627 | base=base) |
226 | 1640 | 1628 | ||
228 | 1641 | def _merged_lines(self, file_id): | 1629 | def _merged_lines(self, this_path): |
229 | 1642 | """Generate the merged lines. | 1630 | """Generate the merged lines. |
230 | 1643 | There is no distinction between lines that are meant to contain <<<<<<< | 1631 | There is no distinction between lines that are meant to contain <<<<<<< |
231 | 1644 | and conflicts. | 1632 | and conflicts. |
232 | @@ -1647,7 +1635,7 @@ | |||
233 | 1647 | base = self.base_tree | 1635 | base = self.base_tree |
234 | 1648 | else: | 1636 | else: |
235 | 1649 | base = None | 1637 | base = None |
237 | 1650 | plan = self._generate_merge_plan(file_id, base) | 1638 | plan = self._generate_merge_plan(this_path, base) |
238 | 1651 | if 'merge' in debug.debug_flags: | 1639 | if 'merge' in debug.debug_flags: |
239 | 1652 | plan = list(plan) | 1640 | plan = list(plan) |
240 | 1653 | trans_id = self.tt.trans_id_file_id(file_id) | 1641 | trans_id = self.tt.trans_id_file_id(file_id) |
241 | @@ -1663,13 +1651,13 @@ | |||
242 | 1663 | base_lines = None | 1651 | base_lines = None |
243 | 1664 | return lines, base_lines | 1652 | return lines, base_lines |
244 | 1665 | 1653 | ||
246 | 1666 | def text_merge(self, trans_id, paths, file_id): | 1654 | def text_merge(self, trans_id, paths): |
247 | 1667 | """Perform a (weave) text merge for a given file and file-id. | 1655 | """Perform a (weave) text merge for a given file and file-id. |
248 | 1668 | If conflicts are encountered, .THIS and .OTHER files will be emitted, | 1656 | If conflicts are encountered, .THIS and .OTHER files will be emitted, |
249 | 1669 | and a conflict will be noted. | 1657 | and a conflict will be noted. |
250 | 1670 | """ | 1658 | """ |
251 | 1671 | base_path, other_path, this_path = paths | 1659 | base_path, other_path, this_path = paths |
253 | 1672 | lines, base_lines = self._merged_lines(file_id) | 1660 | lines, base_lines = self._merged_lines(this_path) |
254 | 1673 | lines = list(lines) | 1661 | lines = list(lines) |
255 | 1674 | # Note we're checking whether the OUTPUT is binary in this case, | 1662 | # Note we're checking whether the OUTPUT is binary in this case, |
256 | 1675 | # because we don't want to get into weave merge guts. | 1663 | # because we don't want to get into weave merge guts. |
257 | @@ -1680,6 +1668,7 @@ | |||
258 | 1680 | self._raw_conflicts.append(('text conflict', trans_id)) | 1668 | self._raw_conflicts.append(('text conflict', trans_id)) |
259 | 1681 | name = self.tt.final_name(trans_id) | 1669 | name = self.tt.final_name(trans_id) |
260 | 1682 | parent_id = self.tt.final_parent(trans_id) | 1670 | parent_id = self.tt.final_parent(trans_id) |
261 | 1671 | file_id = self.tt.final_file_id(trans_id) | ||
262 | 1683 | file_group = self._dump_conflicts(name, paths, parent_id, file_id, | 1672 | file_group = self._dump_conflicts(name, paths, parent_id, file_id, |
263 | 1684 | no_base=False, | 1673 | no_base=False, |
264 | 1685 | base_lines=base_lines) | 1674 | base_lines=base_lines) |
265 | @@ -1690,8 +1679,8 @@ | |||
266 | 1690 | 1679 | ||
267 | 1691 | requires_file_merge_plan = True | 1680 | requires_file_merge_plan = True |
268 | 1692 | 1681 | ||
271 | 1693 | def _generate_merge_plan(self, file_id, base): | 1682 | def _generate_merge_plan(self, this_path, base): |
272 | 1694 | return self.this_tree.plan_file_lca_merge(file_id, self.other_tree, | 1683 | return self.this_tree.plan_file_lca_merge(this_path, self.other_tree, |
273 | 1695 | base=base) | 1684 | base=base) |
274 | 1696 | 1685 | ||
275 | 1697 | 1686 | ||
276 | @@ -1708,7 +1697,7 @@ | |||
277 | 1708 | out_file.write(line) | 1697 | out_file.write(line) |
278 | 1709 | return out_path | 1698 | return out_path |
279 | 1710 | 1699 | ||
281 | 1711 | def text_merge(self, trans_id, paths, file_id): | 1700 | def text_merge(self, trans_id, paths): |
282 | 1712 | """Perform a diff3 merge using a specified file-id and trans-id. | 1701 | """Perform a diff3 merge using a specified file-id and trans-id. |
283 | 1713 | If conflicts are encountered, .BASE, .THIS. and .OTHER conflict files | 1702 | If conflicts are encountered, .BASE, .THIS. and .OTHER conflict files |
284 | 1714 | will be dumped, and a will be conflict noted. | 1703 | will be dumped, and a will be conflict noted. |
285 | @@ -1732,6 +1721,7 @@ | |||
286 | 1732 | if status == 1: | 1721 | if status == 1: |
287 | 1733 | name = self.tt.final_name(trans_id) | 1722 | name = self.tt.final_name(trans_id) |
288 | 1734 | parent_id = self.tt.final_parent(trans_id) | 1723 | parent_id = self.tt.final_parent(trans_id) |
289 | 1724 | file_id = self.tt.final_file_id(trans_id) | ||
290 | 1735 | self._dump_conflicts(name, paths, parent_id, file_id) | 1725 | self._dump_conflicts(name, paths, parent_id, file_id) |
291 | 1736 | self._raw_conflicts.append(('text conflict', trans_id)) | 1726 | self._raw_conflicts.append(('text conflict', trans_id)) |
292 | 1737 | finally: | 1727 | finally: |
293 | 1738 | 1728 | ||
294 | === modified file 'breezy/plugins/changelog_merge/tests/test_changelog_merge.py' | |||
295 | --- breezy/plugins/changelog_merge/tests/test_changelog_merge.py 2018-11-11 04:08:32 +0000 | |||
296 | +++ breezy/plugins/changelog_merge/tests/test_changelog_merge.py 2019-06-22 13:51:41 +0000 | |||
297 | @@ -193,10 +193,9 @@ | |||
298 | 193 | # won't write the new value to disk where get_user_option can get it). | 193 | # won't write the new value to disk where get_user_option can get it). |
299 | 194 | merger.this_branch.get_config().set_user_option( | 194 | merger.this_branch.get_config().set_user_option( |
300 | 195 | 'changelog_merge_files', 'ChangeLog') | 195 | 'changelog_merge_files', 'ChangeLog') |
305 | 196 | merge_hook_params = merge.MergeFileHookParams(merger, b'clog-id', | 196 | merge_hook_params = merge.MergeFileHookParams( |
306 | 197 | ['ChangeLog', 'ChangeLog', | 197 | merger, ['ChangeLog', 'ChangeLog', 'ChangeLog'], None, |
307 | 198 | 'ChangeLog'], None, | 198 | 'file', 'file', 'conflict') |
304 | 199 | 'file', 'file', 'conflict') | ||
308 | 200 | changelog_merger = changelog_merge.ChangeLogMerger(merger) | 199 | changelog_merger = changelog_merge.ChangeLogMerger(merger) |
309 | 201 | return changelog_merger, merge_hook_params | 200 | return changelog_merger, merge_hook_params |
310 | 202 | 201 | ||
311 | 203 | 202 | ||
312 | === modified file 'breezy/tests/per_merger.py' | |||
313 | --- breezy/tests/per_merger.py 2019-06-17 23:01:58 +0000 | |||
314 | +++ breezy/tests/per_merger.py 2019-06-22 13:51:41 +0000 | |||
315 | @@ -242,7 +242,7 @@ | |||
316 | 242 | class HookSuccess(_mod_merge.AbstractPerFileMerger): | 242 | class HookSuccess(_mod_merge.AbstractPerFileMerger): |
317 | 243 | def merge_contents(self, merge_params): | 243 | def merge_contents(self, merge_params): |
318 | 244 | test.hook_log.append(('success',)) | 244 | test.hook_log.append(('success',)) |
320 | 245 | if merge_params.file_id == b'1': | 245 | if merge_params.this_path == 'name1': |
321 | 246 | return 'success', [b'text-merged-by-hook'] | 246 | return 'success', [b'text-merged-by-hook'] |
322 | 247 | return 'not_applicable', None | 247 | return 'not_applicable', None |
323 | 248 | 248 | ||
324 | @@ -257,7 +257,7 @@ | |||
325 | 257 | class HookConflict(_mod_merge.AbstractPerFileMerger): | 257 | class HookConflict(_mod_merge.AbstractPerFileMerger): |
326 | 258 | def merge_contents(self, merge_params): | 258 | def merge_contents(self, merge_params): |
327 | 259 | test.hook_log.append(('conflict',)) | 259 | test.hook_log.append(('conflict',)) |
329 | 260 | if merge_params.file_id == b'1': | 260 | if merge_params.this_path == 'name1': |
330 | 261 | return ('conflicted', | 261 | return ('conflicted', |
331 | 262 | [b'text-with-conflict-markers-from-hook']) | 262 | [b'text-with-conflict-markers-from-hook']) |
332 | 263 | return 'not_applicable', None | 263 | return 'not_applicable', None |
333 | @@ -273,7 +273,7 @@ | |||
334 | 273 | class HookDelete(_mod_merge.AbstractPerFileMerger): | 273 | class HookDelete(_mod_merge.AbstractPerFileMerger): |
335 | 274 | def merge_contents(self, merge_params): | 274 | def merge_contents(self, merge_params): |
336 | 275 | test.hook_log.append(('delete',)) | 275 | test.hook_log.append(('delete',)) |
338 | 276 | if merge_params.file_id == b'1': | 276 | if merge_params.this_path == 'name1': |
339 | 277 | return 'delete', None | 277 | return 'delete', None |
340 | 278 | return 'not_applicable', None | 278 | return 'not_applicable', None |
341 | 279 | 279 | ||
342 | @@ -309,8 +309,9 @@ | |||
343 | 309 | self.addCleanup(builder.cleanup) | 309 | self.addCleanup(builder.cleanup) |
344 | 310 | return builder | 310 | return builder |
345 | 311 | 311 | ||
348 | 312 | def create_file_needing_contents_merge(self, builder, file_id): | 312 | def create_file_needing_contents_merge(self, builder, name): |
349 | 313 | builder.add_file(file_id, builder.tree_root, "name1", b"text1", True) | 313 | file_id = name.encode('ascii') + b'-id' |
350 | 314 | builder.add_file(file_id, builder.tree_root, name, b"text1", True) | ||
351 | 314 | builder.change_contents(file_id, other=b"text4", this=b"text3") | 315 | builder.change_contents(file_id, other=b"text4", this=b"text3") |
352 | 315 | 316 | ||
353 | 316 | def test_change_vs_change(self): | 317 | def test_change_vs_change(self): |
354 | @@ -340,19 +341,19 @@ | |||
355 | 340 | """A hook's result can be the deletion of a file.""" | 341 | """A hook's result can be the deletion of a file.""" |
356 | 341 | self.install_hook_delete() | 342 | self.install_hook_delete() |
357 | 342 | builder = self.make_merge_builder() | 343 | builder = self.make_merge_builder() |
359 | 343 | self.create_file_needing_contents_merge(builder, b"1") | 344 | self.create_file_needing_contents_merge(builder, "name1") |
360 | 344 | conflicts = builder.merge(self.merge_type) | 345 | conflicts = builder.merge(self.merge_type) |
361 | 345 | self.assertEqual(conflicts, []) | 346 | self.assertEqual(conflicts, []) |
363 | 346 | self.assertRaises(errors.NoSuchId, builder.this.id2path, b'1') | 347 | self.assertFalse(builder.this.is_versioned('name1')) |
364 | 347 | self.assertEqual([], list(builder.this.list_files())) | 348 | self.assertEqual([], list(builder.this.list_files())) |
365 | 348 | 349 | ||
366 | 349 | def test_result_can_be_conflict(self): | 350 | def test_result_can_be_conflict(self): |
367 | 350 | """A hook's result can be a conflict.""" | 351 | """A hook's result can be a conflict.""" |
368 | 351 | self.install_hook_conflict() | 352 | self.install_hook_conflict() |
369 | 352 | builder = self.make_merge_builder() | 353 | builder = self.make_merge_builder() |
371 | 353 | self.create_file_needing_contents_merge(builder, b"1") | 354 | self.create_file_needing_contents_merge(builder, "name1") |
372 | 354 | conflicts = builder.merge(self.merge_type) | 355 | conflicts = builder.merge(self.merge_type) |
374 | 355 | self.assertEqual(conflicts, [TextConflict('name1', file_id=b'1')]) | 356 | self.assertEqual(conflicts, [TextConflict('name1', file_id=b'name1-id')]) |
375 | 356 | # The hook still gets to set the file contents in this case, so that it | 357 | # The hook still gets to set the file contents in this case, so that it |
376 | 357 | # can insert custom conflict markers. | 358 | # can insert custom conflict markers. |
377 | 358 | with builder.this.get_file('name1') as f: | 359 | with builder.this.get_file('name1') as f: |
378 | @@ -375,7 +376,7 @@ | |||
379 | 375 | self.install_hook_inactive() | 376 | self.install_hook_inactive() |
380 | 376 | self.install_hook_success() | 377 | self.install_hook_success() |
381 | 377 | builder = self.make_merge_builder() | 378 | builder = self.make_merge_builder() |
383 | 378 | self.create_file_needing_contents_merge(builder, b"1") | 379 | self.create_file_needing_contents_merge(builder, "name1") |
384 | 379 | conflicts = builder.merge(self.merge_type) | 380 | conflicts = builder.merge(self.merge_type) |
385 | 380 | self.assertEqual(conflicts, []) | 381 | self.assertEqual(conflicts, []) |
386 | 381 | with builder.this.get_file('name1') as f: | 382 | with builder.this.get_file('name1') as f: |
387 | @@ -389,7 +390,7 @@ | |||
388 | 389 | self.install_hook_noop() | 390 | self.install_hook_noop() |
389 | 390 | self.install_hook_success() | 391 | self.install_hook_success() |
390 | 391 | builder = self.make_merge_builder() | 392 | builder = self.make_merge_builder() |
392 | 392 | self.create_file_needing_contents_merge(builder, b"1") | 393 | self.create_file_needing_contents_merge(builder, "name1") |
393 | 393 | conflicts = builder.merge(self.merge_type) | 394 | conflicts = builder.merge(self.merge_type) |
394 | 394 | self.assertEqual(conflicts, []) | 395 | self.assertEqual(conflicts, []) |
395 | 395 | with builder.this.get_file('name1') as f: | 396 | with builder.this.get_file('name1') as f: |
396 | @@ -402,7 +403,7 @@ | |||
397 | 402 | self.install_hook_success() | 403 | self.install_hook_success() |
398 | 403 | self.install_hook_noop() | 404 | self.install_hook_noop() |
399 | 404 | builder = self.make_merge_builder() | 405 | builder = self.make_merge_builder() |
401 | 405 | self.create_file_needing_contents_merge(builder, b"1") | 406 | self.create_file_needing_contents_merge(builder, "name1") |
402 | 406 | conflicts = builder.merge(self.merge_type) | 407 | conflicts = builder.merge(self.merge_type) |
403 | 407 | self.assertEqual([('success',)], self.hook_log) | 408 | self.assertEqual([('success',)], self.hook_log) |
404 | 408 | 409 | ||
405 | @@ -412,7 +413,7 @@ | |||
406 | 412 | self.install_hook_conflict() | 413 | self.install_hook_conflict() |
407 | 413 | self.install_hook_noop() | 414 | self.install_hook_noop() |
408 | 414 | builder = self.make_merge_builder() | 415 | builder = self.make_merge_builder() |
410 | 415 | self.create_file_needing_contents_merge(builder, b"1") | 416 | self.create_file_needing_contents_merge(builder, "name1") |
411 | 416 | conflicts = builder.merge(self.merge_type) | 417 | conflicts = builder.merge(self.merge_type) |
412 | 417 | self.assertEqual([('conflict',)], self.hook_log) | 418 | self.assertEqual([('conflict',)], self.hook_log) |
413 | 418 | 419 | ||
414 | @@ -422,6 +423,6 @@ | |||
415 | 422 | self.install_hook_delete() | 423 | self.install_hook_delete() |
416 | 423 | self.install_hook_noop() | 424 | self.install_hook_noop() |
417 | 424 | builder = self.make_merge_builder() | 425 | builder = self.make_merge_builder() |
419 | 425 | self.create_file_needing_contents_merge(builder, b"1") | 426 | self.create_file_needing_contents_merge(builder, "name1") |
420 | 426 | conflicts = builder.merge(self.merge_type) | 427 | conflicts = builder.merge(self.merge_type) |
421 | 427 | self.assertEqual([('delete',)], self.hook_log) | 428 | self.assertEqual([('delete',)], self.hook_log) |
422 | 428 | 429 | ||
423 | === modified file 'breezy/tests/per_tree/test_tree.py' | |||
424 | --- breezy/tests/per_tree/test_tree.py 2019-06-18 13:48:45 +0000 | |||
425 | +++ breezy/tests/per_tree/test_tree.py 2019-06-22 13:51:41 +0000 | |||
426 | @@ -51,7 +51,6 @@ | |||
427 | 51 | work_a = self.make_branch_and_tree('wta') | 51 | work_a = self.make_branch_and_tree('wta') |
428 | 52 | self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')]) | 52 | self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')]) |
429 | 53 | work_a.add('file') | 53 | work_a.add('file') |
430 | 54 | file_id = work_a.path2id('file') | ||
431 | 55 | work_a.commit('base version') | 54 | work_a.commit('base version') |
432 | 56 | work_b = work_a.controldir.sprout('wtb').open_workingtree() | 55 | work_b = work_a.controldir.sprout('wtb').open_workingtree() |
433 | 57 | self.build_tree_contents([('wta/file', b'b\nc\nd\ne\n')]) | 56 | self.build_tree_contents([('wta/file', b'b\nc\nd\ne\n')]) |
434 | @@ -72,7 +71,7 @@ | |||
435 | 72 | ('unchanged', b'd\n'), | 71 | ('unchanged', b'd\n'), |
436 | 73 | ('new-a', b'e\n'), | 72 | ('new-a', b'e\n'), |
437 | 74 | ('new-b', b'f\n'), | 73 | ('new-b', b'f\n'), |
439 | 75 | ], list(tree_a.plan_file_merge(file_id, tree_b))) | 74 | ], list(tree_a.plan_file_merge('file', tree_b))) |
440 | 76 | 75 | ||
441 | 77 | 76 | ||
442 | 78 | class TestReference(TestCaseWithTree): | 77 | class TestReference(TestCaseWithTree): |
443 | 79 | 78 | ||
444 | === modified file 'breezy/tests/per_workingtree/test_merge_from_branch.py' | |||
445 | --- breezy/tests/per_workingtree/test_merge_from_branch.py 2018-11-11 04:08:32 +0000 | |||
446 | +++ breezy/tests/per_workingtree/test_merge_from_branch.py 2019-06-22 13:51:41 +0000 | |||
447 | @@ -115,7 +115,7 @@ | |||
448 | 115 | this.commit('content -> baz') | 115 | this.commit('content -> baz') |
449 | 116 | 116 | ||
450 | 117 | class QuxMerge(merge.Merge3Merger): | 117 | class QuxMerge(merge.Merge3Merger): |
452 | 118 | def text_merge(self, trans_id, paths, file_id): | 118 | def text_merge(self, trans_id, paths): |
453 | 119 | self.tt.create_file([b'qux'], trans_id) | 119 | self.tt.create_file([b'qux'], trans_id) |
454 | 120 | this.merge_from_branch(other.branch, merge_type=QuxMerge) | 120 | this.merge_from_branch(other.branch, merge_type=QuxMerge) |
455 | 121 | self.assertEqual(b'qux', this.get_file_text('foo')) | 121 | self.assertEqual(b'qux', this.get_file_text('foo')) |
456 | 122 | 122 | ||
457 | === modified file 'breezy/tests/test_transform.py' | |||
458 | --- breezy/tests/test_transform.py 2019-06-22 11:16:17 +0000 | |||
459 | +++ breezy/tests/test_transform.py 2019-06-22 13:51:41 +0000 | |||
460 | @@ -3264,7 +3264,7 @@ | |||
461 | 3264 | ('unchanged', b'd\n'), | 3264 | ('unchanged', b'd\n'), |
462 | 3265 | ('new-a', b'e\n'), | 3265 | ('new-a', b'e\n'), |
463 | 3266 | ('new-b', b'f\n'), | 3266 | ('new-b', b'f\n'), |
465 | 3267 | ], list(tree_a.plan_file_merge(b'file-id', tree_b))) | 3267 | ], list(tree_a.plan_file_merge('file', tree_b))) |
466 | 3268 | 3268 | ||
467 | 3269 | def test_plan_file_merge_revision_tree(self): | 3269 | def test_plan_file_merge_revision_tree(self): |
468 | 3270 | work_a = self.make_branch_and_tree('wta') | 3270 | work_a = self.make_branch_and_tree('wta') |
469 | @@ -3287,7 +3287,7 @@ | |||
470 | 3287 | ('unchanged', b'd\n'), | 3287 | ('unchanged', b'd\n'), |
471 | 3288 | ('new-a', b'e\n'), | 3288 | ('new-a', b'e\n'), |
472 | 3289 | ('new-b', b'f\n'), | 3289 | ('new-b', b'f\n'), |
474 | 3290 | ], list(tree_a.plan_file_merge(b'file-id', tree_b))) | 3290 | ], list(tree_a.plan_file_merge('file', tree_b))) |
475 | 3291 | 3291 | ||
476 | 3292 | def test_walkdirs(self): | 3292 | def test_walkdirs(self): |
477 | 3293 | preview = self.get_empty_preview() | 3293 | preview = self.get_empty_preview() |
478 | 3294 | 3294 | ||
479 | === modified file 'breezy/transform.py' | |||
480 | --- breezy/transform.py 2019-06-22 11:16:17 +0000 | |||
481 | +++ breezy/transform.py 2019-06-22 13:51:41 +0000 | |||
482 | @@ -2675,8 +2675,7 @@ | |||
483 | 2675 | divert.add(file_id) | 2675 | divert.add(file_id) |
484 | 2676 | if (file_id not in divert | 2676 | if (file_id not in divert |
485 | 2677 | and _content_match( | 2677 | and _content_match( |
488 | 2678 | tree, entry, tree_path, file_id, kind, | 2678 | tree, entry, tree_path, kind, target_path)): |
487 | 2679 | target_path)): | ||
489 | 2680 | tt.delete_contents(tt.trans_id_tree_path(tree_path)) | 2679 | tt.delete_contents(tt.trans_id_tree_path(tree_path)) |
490 | 2681 | if kind == 'directory': | 2680 | if kind == 'directory': |
491 | 2682 | reparent = True | 2681 | reparent = True |
492 | @@ -2785,7 +2784,7 @@ | |||
493 | 2785 | return by_parent[old_parent] | 2784 | return by_parent[old_parent] |
494 | 2786 | 2785 | ||
495 | 2787 | 2786 | ||
497 | 2788 | def _content_match(tree, entry, tree_path, file_id, kind, target_path): | 2787 | def _content_match(tree, entry, tree_path, kind, target_path): |
498 | 2789 | if entry.kind != kind: | 2788 | if entry.kind != kind: |
499 | 2790 | return False | 2789 | return False |
500 | 2791 | if entry.kind == "directory": | 2790 | if entry.kind == "directory": |
New changes here all seem fine. Some interface changes, which may be worth calling out in NEWS?