Merge lp:~jelmer/bzr/result-mentions-tags into lp:bzr
- result-mentions-tags
- Merge into bzr.dev
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merged at revision: | 6125 |
Proposed branch: | lp:~jelmer/bzr/result-mentions-tags |
Merge into: | lp:bzr |
Diff against target: |
447 lines (+102/-45) 12 files modified
bzrlib/branch.py (+32/-12) bzrlib/commit.py (+2/-1) bzrlib/tag.py (+21/-14) bzrlib/tests/blackbox/test_non_ascii.py (+1/-1) bzrlib/tests/blackbox/test_pull.py (+11/-1) bzrlib/tests/blackbox/test_push.py (+3/-1) bzrlib/tests/per_branch/test_pull.py (+1/-1) bzrlib/tests/per_branch/test_tags.py (+19/-10) bzrlib/tests/per_interbranch/test_pull.py (+1/-1) bzrlib/tests/test_branch.py (+1/-1) bzrlib/tests/test_tag.py (+4/-2) doc/en/release-notes/bzr-2.5.txt (+6/-0) |
To merge this branch: | bzr merge lp:~jelmer/bzr/result-mentions-tags |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vincent Ladeuil | Needs Fixing | ||
Review via email: mp+73564@code.launchpad.net |
Commit message
Mention the number of tags that was pushed/pull, if any.
Description of the change
Mention the number of tags that was pushed/pull, if any.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
I've filed a bug about the output inconsistency between "bzr pull" / "bzr push" and added a note in the code. r=vila on IRC.
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
sent to pqm by email
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
sent to pqm by email
Revision history for this message
Jelmer Vernooij (jelmer) wrote : | # |
sent to pqm by email
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bzrlib/branch.py' | |||
2 | --- bzrlib/branch.py 2011-08-27 16:59:43 +0000 | |||
3 | +++ bzrlib/branch.py 2011-09-02 00:55:08 +0000 | |||
4 | @@ -3044,6 +3044,7 @@ | |||
5 | 3044 | :ivar local_branch: target branch if there is a Master, else None | 3044 | :ivar local_branch: target branch if there is a Master, else None |
6 | 3045 | :ivar target_branch: Target/destination branch object. (write locked) | 3045 | :ivar target_branch: Target/destination branch object. (write locked) |
7 | 3046 | :ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to | 3046 | :ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to |
8 | 3047 | :ivar tag_updates: A dict with new tags, see BasicTags.merge_to | ||
9 | 3047 | """ | 3048 | """ |
10 | 3048 | 3049 | ||
11 | 3049 | @deprecated_method(deprecated_in((2, 3, 0))) | 3050 | @deprecated_method(deprecated_in((2, 3, 0))) |
12 | @@ -3055,11 +3056,18 @@ | |||
13 | 3055 | return self.new_revno - self.old_revno | 3056 | return self.new_revno - self.old_revno |
14 | 3056 | 3057 | ||
15 | 3057 | def report(self, to_file): | 3058 | def report(self, to_file): |
16 | 3059 | tag_conflicts = getattr(self, "tag_conflicts", None) | ||
17 | 3060 | tag_updates = getattr(self, "tag_updates", None) | ||
18 | 3058 | if not is_quiet(): | 3061 | if not is_quiet(): |
22 | 3059 | if self.old_revid == self.new_revid: | 3062 | if self.old_revid != self.new_revid: |
20 | 3060 | to_file.write('No revisions to pull.\n') | ||
21 | 3061 | else: | ||
23 | 3062 | to_file.write('Now on revision %d.\n' % self.new_revno) | 3063 | to_file.write('Now on revision %d.\n' % self.new_revno) |
24 | 3064 | if tag_updates: | ||
25 | 3065 | to_file.write('%d tag(s) updated.\n' % len(tag_updates)) | ||
26 | 3066 | if self.old_revid == self.new_revid and not tag_updates: | ||
27 | 3067 | if not tag_conflicts: | ||
28 | 3068 | to_file.write('No revisions or tags to pull.\n') | ||
29 | 3069 | else: | ||
30 | 3070 | to_file.write('No revisions to pull.\n') | ||
31 | 3063 | self._show_tag_conficts(to_file) | 3071 | self._show_tag_conficts(to_file) |
32 | 3064 | 3072 | ||
33 | 3065 | 3073 | ||
34 | @@ -3091,11 +3099,22 @@ | |||
35 | 3091 | return self.new_revno - self.old_revno | 3099 | return self.new_revno - self.old_revno |
36 | 3092 | 3100 | ||
37 | 3093 | def report(self, to_file): | 3101 | def report(self, to_file): |
43 | 3094 | """Write a human-readable description of the result.""" | 3102 | # TODO: This function gets passed a to_file, but then |
44 | 3095 | if self.old_revid == self.new_revid: | 3103 | # ignores it and calls note() instead. This is also |
45 | 3096 | note('No new revisions to push.') | 3104 | # inconsistent with PullResult(), which writes to stdout. |
46 | 3097 | else: | 3105 | # -- JRV20110901, bug #838853 |
47 | 3098 | note('Pushed up to revision %d.' % self.new_revno) | 3106 | tag_conflicts = getattr(self, "tag_conflicts", None) |
48 | 3107 | tag_updates = getattr(self, "tag_updates", None) | ||
49 | 3108 | if not is_quiet(): | ||
50 | 3109 | if self.old_revid != self.new_revid: | ||
51 | 3110 | note('Pushed up to revision %d.' % self.new_revno) | ||
52 | 3111 | if tag_updates: | ||
53 | 3112 | note('%d tag(s) updated.' % len(tag_updates)) | ||
54 | 3113 | if self.old_revid == self.new_revid and not tag_updates: | ||
55 | 3114 | if not tag_conflicts: | ||
56 | 3115 | note('No new revisions or tags to push.') | ||
57 | 3116 | else: | ||
58 | 3117 | note('No new revisions to push.') | ||
59 | 3099 | self._show_tag_conficts(to_file) | 3118 | self._show_tag_conficts(to_file) |
60 | 3100 | 3119 | ||
61 | 3101 | 3120 | ||
62 | @@ -3409,8 +3428,8 @@ | |||
63 | 3409 | self._update_revisions(stop_revision, overwrite=overwrite, | 3428 | self._update_revisions(stop_revision, overwrite=overwrite, |
64 | 3410 | graph=graph) | 3429 | graph=graph) |
65 | 3411 | if self.source._push_should_merge_tags(): | 3430 | if self.source._push_should_merge_tags(): |
68 | 3412 | result.tag_conflicts = self.source.tags.merge_to(self.target.tags, | 3431 | result.tag_updates, result.tag_conflicts = ( |
69 | 3413 | overwrite) | 3432 | self.source.tags.merge_to(self.target.tags, overwrite)) |
70 | 3414 | result.new_revno, result.new_revid = self.target.last_revision_info() | 3433 | result.new_revno, result.new_revid = self.target.last_revision_info() |
71 | 3415 | return result | 3434 | return result |
72 | 3416 | 3435 | ||
73 | @@ -3499,8 +3518,9 @@ | |||
74 | 3499 | # TODO: The old revid should be specified when merging tags, | 3518 | # TODO: The old revid should be specified when merging tags, |
75 | 3500 | # so a tags implementation that versions tags can only | 3519 | # so a tags implementation that versions tags can only |
76 | 3501 | # pull in the most recent changes. -- JRV20090506 | 3520 | # pull in the most recent changes. -- JRV20090506 |
79 | 3502 | result.tag_conflicts = self.source.tags.merge_to(self.target.tags, | 3521 | result.tag_updates, result.tag_conflicts = ( |
80 | 3503 | overwrite, ignore_master=not merge_tags_to_master) | 3522 | self.source.tags.merge_to(self.target.tags, overwrite, |
81 | 3523 | ignore_master=not merge_tags_to_master)) | ||
82 | 3504 | result.new_revno, result.new_revid = self.target.last_revision_info() | 3524 | result.new_revno, result.new_revid = self.target.last_revision_info() |
83 | 3505 | if _hook_master: | 3525 | if _hook_master: |
84 | 3506 | result.master_branch = _hook_master | 3526 | result.master_branch = _hook_master |
85 | 3507 | 3527 | ||
86 | === modified file 'bzrlib/commit.py' | |||
87 | --- bzrlib/commit.py 2011-06-28 17:25:26 +0000 | |||
88 | +++ bzrlib/commit.py 2011-09-02 00:55:08 +0000 | |||
89 | @@ -464,7 +464,8 @@ | |||
90 | 464 | # Merge local tags to remote | 464 | # Merge local tags to remote |
91 | 465 | if self.bound_branch: | 465 | if self.bound_branch: |
92 | 466 | self._set_progress_stage("Merging tags to master branch") | 466 | self._set_progress_stage("Merging tags to master branch") |
94 | 467 | tag_conflicts = self.branch.tags.merge_to(self.master_branch.tags) | 467 | tag_updates, tag_conflicts = self.branch.tags.merge_to( |
95 | 468 | self.master_branch.tags) | ||
96 | 468 | if tag_conflicts: | 469 | if tag_conflicts: |
97 | 469 | warning_lines = [' ' + name for name, _, _ in tag_conflicts] | 470 | warning_lines = [' ' + name for name, _, _ in tag_conflicts] |
98 | 470 | note("Conflicting tags in bound branch:\n" + | 471 | note("Conflicting tags in bound branch:\n" + |
99 | 471 | 472 | ||
100 | === modified file 'bzrlib/tag.py' | |||
101 | --- bzrlib/tag.py 2011-05-18 16:42:48 +0000 | |||
102 | +++ bzrlib/tag.py 2011-09-02 00:55:08 +0000 | |||
103 | @@ -68,7 +68,7 @@ | |||
104 | 68 | 68 | ||
105 | 69 | def merge_to(self, to_tags, overwrite=False, ignore_master=False): | 69 | def merge_to(self, to_tags, overwrite=False, ignore_master=False): |
106 | 70 | # we never have anything to copy | 70 | # we never have anything to copy |
108 | 71 | pass | 71 | return {}, [] |
109 | 72 | 72 | ||
110 | 73 | def rename_revisions(self, rename_map): | 73 | def rename_revisions(self, rename_map): |
111 | 74 | # No tags, so nothing to rename | 74 | # No tags, so nothing to rename |
112 | @@ -201,7 +201,10 @@ | |||
113 | 201 | branch (if any). Default is false (so the master will be updated). | 201 | branch (if any). Default is false (so the master will be updated). |
114 | 202 | New in bzr 2.3. | 202 | New in bzr 2.3. |
115 | 203 | 203 | ||
117 | 204 | :returns: A set of tags that conflicted, each of which is | 204 | :returns: Tuple with tag_updates and tag_conflicts. |
118 | 205 | tag_updates is a dictionary with new tags, None is used for | ||
119 | 206 | removed tags | ||
120 | 207 | tag_conflicts is a set of tags that conflicted, each of which is | ||
121 | 205 | (tagname, source_target, dest_target), or None if no copying was | 208 | (tagname, source_target, dest_target), or None if no copying was |
122 | 206 | done. | 209 | done. |
123 | 207 | """ | 210 | """ |
124 | @@ -211,15 +214,15 @@ | |||
125 | 211 | def _merge_to_operation(self, operation, to_tags, overwrite, ignore_master): | 214 | def _merge_to_operation(self, operation, to_tags, overwrite, ignore_master): |
126 | 212 | add_cleanup = operation.add_cleanup | 215 | add_cleanup = operation.add_cleanup |
127 | 213 | if self.branch == to_tags.branch: | 216 | if self.branch == to_tags.branch: |
129 | 214 | return | 217 | return {}, [] |
130 | 215 | if not self.branch.supports_tags(): | 218 | if not self.branch.supports_tags(): |
131 | 216 | # obviously nothing to copy | 219 | # obviously nothing to copy |
133 | 217 | return | 220 | return {}, [] |
134 | 218 | source_dict = self.get_tag_dict() | 221 | source_dict = self.get_tag_dict() |
135 | 219 | if not source_dict: | 222 | if not source_dict: |
136 | 220 | # no tags in the source, and we don't want to clobber anything | 223 | # no tags in the source, and we don't want to clobber anything |
137 | 221 | # that's in the destination | 224 | # that's in the destination |
139 | 222 | return | 225 | return {}, [] |
140 | 223 | # We merge_to both master and child individually. | 226 | # We merge_to both master and child individually. |
141 | 224 | # | 227 | # |
142 | 225 | # It's possible for master and child to have differing sets of | 228 | # It's possible for master and child to have differing sets of |
143 | @@ -239,21 +242,23 @@ | |||
144 | 239 | master = to_tags.branch.get_master_branch() | 242 | master = to_tags.branch.get_master_branch() |
145 | 240 | if master is not None: | 243 | if master is not None: |
146 | 241 | add_cleanup(master.lock_write().unlock) | 244 | add_cleanup(master.lock_write().unlock) |
148 | 242 | conflicts = self._merge_to(to_tags, source_dict, overwrite) | 245 | updates, conflicts = self._merge_to(to_tags, source_dict, overwrite) |
149 | 243 | if master is not None: | 246 | if master is not None: |
152 | 244 | conflicts += self._merge_to(master.tags, source_dict, | 247 | extra_updates, extra_conflicts = self._merge_to(master.tags, |
153 | 245 | overwrite) | 248 | source_dict, overwrite) |
154 | 249 | updates.update(extra_updates) | ||
155 | 250 | conflicts += extra_conflicts | ||
156 | 246 | # We use set() to remove any duplicate conflicts from the master | 251 | # We use set() to remove any duplicate conflicts from the master |
157 | 247 | # branch. | 252 | # branch. |
159 | 248 | return set(conflicts) | 253 | return updates, set(conflicts) |
160 | 249 | 254 | ||
161 | 250 | def _merge_to(self, to_tags, source_dict, overwrite): | 255 | def _merge_to(self, to_tags, source_dict, overwrite): |
162 | 251 | dest_dict = to_tags.get_tag_dict() | 256 | dest_dict = to_tags.get_tag_dict() |
165 | 252 | result, conflicts = self._reconcile_tags(source_dict, dest_dict, | 257 | result, updates, conflicts = self._reconcile_tags(source_dict, |
166 | 253 | overwrite) | 258 | dest_dict, overwrite) |
167 | 254 | if result != dest_dict: | 259 | if result != dest_dict: |
168 | 255 | to_tags._set_tag_dict(result) | 260 | to_tags._set_tag_dict(result) |
170 | 256 | return conflicts | 261 | return updates, conflicts |
171 | 257 | 262 | ||
172 | 258 | def rename_revisions(self, rename_map): | 263 | def rename_revisions(self, rename_map): |
173 | 259 | """Rename revisions in this tags dictionary. | 264 | """Rename revisions in this tags dictionary. |
174 | @@ -275,19 +280,21 @@ | |||
175 | 275 | * different definitions => if overwrite is False, keep destination | 280 | * different definitions => if overwrite is False, keep destination |
176 | 276 | value and give a warning, otherwise use the source value | 281 | value and give a warning, otherwise use the source value |
177 | 277 | 282 | ||
179 | 278 | :returns: (result_dict, | 283 | :returns: (result_dict, updates, |
180 | 279 | [(conflicting_tag, source_target, dest_target)]) | 284 | [(conflicting_tag, source_target, dest_target)]) |
181 | 280 | """ | 285 | """ |
182 | 281 | conflicts = [] | 286 | conflicts = [] |
183 | 287 | updates = {} | ||
184 | 282 | result = dict(dest_dict) # copy | 288 | result = dict(dest_dict) # copy |
185 | 283 | for name, target in source_dict.items(): | 289 | for name, target in source_dict.items(): |
186 | 284 | if name not in result or overwrite: | 290 | if name not in result or overwrite: |
187 | 285 | result[name] = target | 291 | result[name] = target |
188 | 292 | updates[name] = target | ||
189 | 286 | elif result[name] == target: | 293 | elif result[name] == target: |
190 | 287 | pass | 294 | pass |
191 | 288 | else: | 295 | else: |
192 | 289 | conflicts.append((name, target, result[name])) | 296 | conflicts.append((name, target, result[name])) |
194 | 290 | return result, conflicts | 297 | return result, updates, conflicts |
195 | 291 | 298 | ||
196 | 292 | 299 | ||
197 | 293 | def _merge_tags_if_possible(from_branch, to_branch, ignore_master=False): | 300 | def _merge_tags_if_possible(from_branch, to_branch, ignore_master=False): |
198 | 294 | 301 | ||
199 | === modified file 'bzrlib/tests/blackbox/test_non_ascii.py' | |||
200 | --- bzrlib/tests/blackbox/test_non_ascii.py 2011-08-04 00:17:53 +0000 | |||
201 | +++ bzrlib/tests/blackbox/test_non_ascii.py 2011-09-02 00:55:08 +0000 | |||
202 | @@ -267,7 +267,7 @@ | |||
203 | 267 | 267 | ||
204 | 268 | expected = osutils.pathjoin(osutils.getcwd(), dirname1) | 268 | expected = osutils.pathjoin(osutils.getcwd(), dirname1) |
205 | 269 | self.assertEqual(u'Using saved parent location: %s/\n' | 269 | self.assertEqual(u'Using saved parent location: %s/\n' |
207 | 270 | 'No revisions to pull.\n' % (expected,), txt) | 270 | 'No revisions or tags to pull.\n' % (expected,), txt) |
208 | 271 | 271 | ||
209 | 272 | self.build_tree_contents( | 272 | self.build_tree_contents( |
210 | 273 | [(osutils.pathjoin(dirname1, 'a'), 'and yet more\n')]) | 273 | [(osutils.pathjoin(dirname1, 'a'), 'and yet more\n')]) |
211 | 274 | 274 | ||
212 | === modified file 'bzrlib/tests/blackbox/test_pull.py' | |||
213 | --- bzrlib/tests/blackbox/test_pull.py 2011-08-30 08:46:10 +0000 | |||
214 | +++ bzrlib/tests/blackbox/test_pull.py 2011-09-02 00:55:08 +0000 | |||
215 | @@ -318,7 +318,7 @@ | |||
216 | 318 | # it is legal to attempt to pull an already-merged bundle | 318 | # it is legal to attempt to pull an already-merged bundle |
217 | 319 | out, err = self.run_bzr('pull ../bundle') | 319 | out, err = self.run_bzr('pull ../bundle') |
218 | 320 | self.assertEqual(err, '') | 320 | self.assertEqual(err, '') |
220 | 321 | self.assertEqual(out, 'No revisions to pull.\n') | 321 | self.assertEqual(out, 'No revisions or tags to pull.\n') |
221 | 322 | 322 | ||
222 | 323 | def test_pull_verbose_no_files(self): | 323 | def test_pull_verbose_no_files(self): |
223 | 324 | """Pull --verbose should not list modified files""" | 324 | """Pull --verbose should not list modified files""" |
224 | @@ -533,3 +533,13 @@ | |||
225 | 533 | out = self.run_bzr(['pull','-d','to','from'],retcode=1) | 533 | out = self.run_bzr(['pull','-d','to','from'],retcode=1) |
226 | 534 | self.assertEqual(out, | 534 | self.assertEqual(out, |
227 | 535 | ('No revisions to pull.\nConflicting tags:\n mytag\n', '')) | 535 | ('No revisions to pull.\nConflicting tags:\n mytag\n', '')) |
228 | 536 | |||
229 | 537 | def test_pull_tag_notification(self): | ||
230 | 538 | """pulling tags with conflicts will change the exit code""" | ||
231 | 539 | # create a branch, see that --show-base fails | ||
232 | 540 | from_tree = self.make_branch_and_tree('from') | ||
233 | 541 | from_tree.branch.tags.set_tag("mytag", "somerevid") | ||
234 | 542 | to_tree = self.make_branch_and_tree('to') | ||
235 | 543 | out = self.run_bzr(['pull', '-d', 'to', 'from']) | ||
236 | 544 | self.assertEqual(out, | ||
237 | 545 | ('1 tag(s) updated.\n', '')) | ||
238 | 536 | 546 | ||
239 | === modified file 'bzrlib/tests/blackbox/test_push.py' | |||
240 | --- bzrlib/tests/blackbox/test_push.py 2011-08-16 15:03:03 +0000 | |||
241 | +++ bzrlib/tests/blackbox/test_push.py 2011-09-02 00:55:08 +0000 | |||
242 | @@ -157,7 +157,9 @@ | |||
243 | 157 | self.run_bzr('push -d tree pushed-to') | 157 | self.run_bzr('push -d tree pushed-to') |
244 | 158 | path = t.branch.get_push_location() | 158 | path = t.branch.get_push_location() |
245 | 159 | out, err = self.run_bzr('push', working_dir="tree") | 159 | out, err = self.run_bzr('push', working_dir="tree") |
247 | 160 | self.assertEqual('Using saved push location: %s\nNo new revisions to push.\n' % urlutils.local_path_from_url(path), err) | 160 | self.assertEqual('Using saved push location: %s\n' |
248 | 161 | 'No new revisions or tags to push.\n' % | ||
249 | 162 | urlutils.local_path_from_url(path), err) | ||
250 | 161 | out, err = self.run_bzr('push -q', working_dir="tree") | 163 | out, err = self.run_bzr('push -q', working_dir="tree") |
251 | 162 | self.assertEqual('', out) | 164 | self.assertEqual('', out) |
252 | 163 | self.assertEqual('', err) | 165 | self.assertEqual('', err) |
253 | 164 | 166 | ||
254 | === modified file 'bzrlib/tests/per_branch/test_pull.py' | |||
255 | --- bzrlib/tests/per_branch/test_pull.py 2011-08-09 14:18:05 +0000 | |||
256 | +++ bzrlib/tests/per_branch/test_pull.py 2011-09-02 00:55:08 +0000 | |||
257 | @@ -117,7 +117,7 @@ | |||
258 | 117 | self.assertEqual('P1', result.old_revid) | 117 | self.assertEqual('P1', result.old_revid) |
259 | 118 | self.assertEqual(2, result.new_revno) | 118 | self.assertEqual(2, result.new_revno) |
260 | 119 | self.assertEqual('M1', result.new_revid) | 119 | self.assertEqual('M1', result.new_revid) |
262 | 120 | self.assertEqual(None, result.tag_conflicts) | 120 | self.assertEqual([], result.tag_conflicts) |
263 | 121 | 121 | ||
264 | 122 | def test_pull_overwrite(self): | 122 | def test_pull_overwrite(self): |
265 | 123 | tree_a = self.make_branch_and_tree('tree_a') | 123 | tree_a = self.make_branch_and_tree('tree_a') |
266 | 124 | 124 | ||
267 | === modified file 'bzrlib/tests/per_branch/test_tags.py' | |||
268 | --- bzrlib/tests/per_branch/test_tags.py 2011-08-26 23:59:59 +0000 | |||
269 | +++ bzrlib/tests/per_branch/test_tags.py 2011-09-02 00:55:08 +0000 | |||
270 | @@ -93,17 +93,19 @@ | |||
271 | 93 | # if a tag is in the destination and not in the source, it is not | 93 | # if a tag is in the destination and not in the source, it is not |
272 | 94 | # removed when we merge them | 94 | # removed when we merge them |
273 | 95 | b2.tags.set_tag('in-destination', 'revid') | 95 | b2.tags.set_tag('in-destination', 'revid') |
276 | 96 | result = b1.tags.merge_to(b2.tags) | 96 | updates, conflicts = b1.tags.merge_to(b2.tags) |
277 | 97 | self.assertEquals(list(result), []) | 97 | self.assertEquals(list(conflicts), []) |
278 | 98 | self.assertEquals(updates, {}) | ||
279 | 98 | self.assertEquals(b2.tags.lookup_tag('in-destination'), 'revid') | 99 | self.assertEquals(b2.tags.lookup_tag('in-destination'), 'revid') |
280 | 99 | # if there's a conflicting tag, it's reported -- the command line | 100 | # if there's a conflicting tag, it's reported -- the command line |
281 | 100 | # interface will say "these tags couldn't be copied" | 101 | # interface will say "these tags couldn't be copied" |
282 | 101 | b1.tags.set_tag('conflicts', 'revid-1') | 102 | b1.tags.set_tag('conflicts', 'revid-1') |
283 | 102 | b2.tags.set_tag('conflicts', 'revid-2') | 103 | b2.tags.set_tag('conflicts', 'revid-2') |
286 | 103 | result = b1.tags.merge_to(b2.tags) | 104 | updates, conflicts = b1.tags.merge_to(b2.tags) |
287 | 104 | self.assertEquals(list(result), | 105 | self.assertEquals(list(conflicts), |
288 | 105 | [('conflicts', 'revid-1', 'revid-2')]) | 106 | [('conflicts', 'revid-1', 'revid-2')]) |
289 | 106 | # and it keeps the same value | 107 | # and it keeps the same value |
290 | 108 | self.assertEquals(updates, {}) | ||
291 | 107 | self.assertEquals(b2.tags.lookup_tag('conflicts'), 'revid-2') | 109 | self.assertEquals(b2.tags.lookup_tag('conflicts'), 'revid-2') |
292 | 108 | 110 | ||
293 | 109 | def test_unicode_tag(self): | 111 | def test_unicode_tag(self): |
294 | @@ -292,9 +294,10 @@ | |||
295 | 292 | child.bind(master) | 294 | child.bind(master) |
296 | 293 | child.update() | 295 | child.update() |
297 | 294 | master.tags.set_tag('foo', 'rev-2') | 296 | master.tags.set_tag('foo', 'rev-2') |
299 | 295 | tag_conflicts = other.tags.merge_to(child.tags, overwrite=True) | 297 | tag_updates, tag_conflicts = other.tags.merge_to(child.tags, overwrite=True) |
300 | 296 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) | 298 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) |
301 | 297 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) | 299 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) |
302 | 300 | self.assertEquals({"foo": "rev-1"}, tag_updates) | ||
303 | 298 | self.assertLength(0, tag_conflicts) | 301 | self.assertLength(0, tag_conflicts) |
304 | 299 | 302 | ||
305 | 300 | def test_merge_to_overwrite_conflict_in_child_and_master(self): | 303 | def test_merge_to_overwrite_conflict_in_child_and_master(self): |
306 | @@ -308,9 +311,11 @@ | |||
307 | 308 | child = self.make_branch('child') | 311 | child = self.make_branch('child') |
308 | 309 | child.bind(master) | 312 | child.bind(master) |
309 | 310 | child.update() | 313 | child.update() |
311 | 311 | tag_conflicts = other.tags.merge_to(child.tags, overwrite=True) | 314 | tag_updates, tag_conflicts = other.tags.merge_to( |
312 | 315 | child.tags, overwrite=True) | ||
313 | 312 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) | 316 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) |
314 | 313 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) | 317 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) |
315 | 318 | self.assertEquals({u'foo': 'rev-1'}, tag_updates) | ||
316 | 314 | self.assertLength(0, tag_conflicts) | 319 | self.assertLength(0, tag_conflicts) |
317 | 315 | 320 | ||
318 | 316 | def test_merge_to_conflict_in_child_only(self): | 321 | def test_merge_to_conflict_in_child_only(self): |
319 | @@ -325,13 +330,14 @@ | |||
320 | 325 | child.bind(master) | 330 | child.bind(master) |
321 | 326 | child.update() | 331 | child.update() |
322 | 327 | master.tags.delete_tag('foo') | 332 | master.tags.delete_tag('foo') |
324 | 328 | tag_conflicts = other.tags.merge_to(child.tags) | 333 | tag_updates, tag_conflicts = other.tags.merge_to(child.tags) |
325 | 329 | # Conflict in child, so it is unchanged. | 334 | # Conflict in child, so it is unchanged. |
326 | 330 | self.assertEquals('rev-2', child.tags.lookup_tag('foo')) | 335 | self.assertEquals('rev-2', child.tags.lookup_tag('foo')) |
327 | 331 | # No conflict in the master, so the 'foo' tag equals other's value here. | 336 | # No conflict in the master, so the 'foo' tag equals other's value here. |
328 | 332 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) | 337 | self.assertEquals('rev-1', master.tags.lookup_tag('foo')) |
329 | 333 | # The conflict is reported. | 338 | # The conflict is reported. |
330 | 334 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) | 339 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) |
331 | 340 | self.assertEquals({u'foo': 'rev-1'}, tag_updates) | ||
332 | 335 | 341 | ||
333 | 336 | def test_merge_to_conflict_in_master_only(self): | 342 | def test_merge_to_conflict_in_master_only(self): |
334 | 337 | """When new_tags.merge_to(child.tags) conflicts with the master but not | 343 | """When new_tags.merge_to(child.tags) conflicts with the master but not |
335 | @@ -344,12 +350,13 @@ | |||
336 | 344 | child.bind(master) | 350 | child.bind(master) |
337 | 345 | child.update() | 351 | child.update() |
338 | 346 | master.tags.set_tag('foo', 'rev-2') | 352 | master.tags.set_tag('foo', 'rev-2') |
340 | 347 | tag_conflicts = other.tags.merge_to(child.tags) | 353 | tag_updates, tag_conflicts = other.tags.merge_to(child.tags) |
341 | 348 | # No conflict in the child, so the 'foo' tag equals other's value here. | 354 | # No conflict in the child, so the 'foo' tag equals other's value here. |
342 | 349 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) | 355 | self.assertEquals('rev-1', child.tags.lookup_tag('foo')) |
343 | 350 | # Conflict in master, so it is unchanged. | 356 | # Conflict in master, so it is unchanged. |
344 | 351 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) | 357 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) |
345 | 352 | # The conflict is reported. | 358 | # The conflict is reported. |
346 | 359 | self.assertEquals({u'foo': 'rev-1'}, tag_updates) | ||
347 | 353 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) | 360 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) |
348 | 354 | 361 | ||
349 | 355 | def test_merge_to_same_conflict_in_master_and_child(self): | 362 | def test_merge_to_same_conflict_in_master_and_child(self): |
350 | @@ -363,12 +370,13 @@ | |||
351 | 363 | child = self.make_branch('child') | 370 | child = self.make_branch('child') |
352 | 364 | child.bind(master) | 371 | child.bind(master) |
353 | 365 | child.update() | 372 | child.update() |
355 | 366 | tag_conflicts = other.tags.merge_to(child.tags) | 373 | tag_updates, tag_conflicts = other.tags.merge_to(child.tags) |
356 | 367 | # Both master and child conflict, so both stay as rev-2 | 374 | # Both master and child conflict, so both stay as rev-2 |
357 | 368 | self.assertEquals('rev-2', child.tags.lookup_tag('foo')) | 375 | self.assertEquals('rev-2', child.tags.lookup_tag('foo')) |
358 | 369 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) | 376 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) |
359 | 370 | # The conflict is reported exactly once, even though it occurs in both | 377 | # The conflict is reported exactly once, even though it occurs in both |
360 | 371 | # master and child. | 378 | # master and child. |
361 | 379 | self.assertEquals({}, tag_updates) | ||
362 | 372 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) | 380 | self.assertEquals([(u'foo', 'rev-1', 'rev-2')], list(tag_conflicts)) |
363 | 373 | 381 | ||
364 | 374 | def test_merge_to_different_conflict_in_master_and_child(self): | 382 | def test_merge_to_different_conflict_in_master_and_child(self): |
365 | @@ -385,11 +393,12 @@ | |||
366 | 385 | # We use the private method _set_tag_dict because normally bzr tries to | 393 | # We use the private method _set_tag_dict because normally bzr tries to |
367 | 386 | # avoid this scenario. | 394 | # avoid this scenario. |
368 | 387 | child.tags._set_tag_dict({'foo': 'rev-3'}) | 395 | child.tags._set_tag_dict({'foo': 'rev-3'}) |
370 | 388 | tag_conflicts = other.tags.merge_to(child.tags) | 396 | tag_updates, tag_conflicts = other.tags.merge_to(child.tags) |
371 | 389 | # Both master and child conflict, so both stay as they were. | 397 | # Both master and child conflict, so both stay as they were. |
372 | 390 | self.assertEquals('rev-3', child.tags.lookup_tag('foo')) | 398 | self.assertEquals('rev-3', child.tags.lookup_tag('foo')) |
373 | 391 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) | 399 | self.assertEquals('rev-2', master.tags.lookup_tag('foo')) |
374 | 392 | # Both conflicts are reported. | 400 | # Both conflicts are reported. |
375 | 401 | self.assertEquals({}, tag_updates) | ||
376 | 393 | self.assertEquals( | 402 | self.assertEquals( |
377 | 394 | [(u'foo', 'rev-1', 'rev-2'), (u'foo', 'rev-1', 'rev-3')], | 403 | [(u'foo', 'rev-1', 'rev-2'), (u'foo', 'rev-1', 'rev-3')], |
378 | 395 | sorted(tag_conflicts)) | 404 | sorted(tag_conflicts)) |
379 | 396 | 405 | ||
380 | === modified file 'bzrlib/tests/per_interbranch/test_pull.py' | |||
381 | --- bzrlib/tests/per_interbranch/test_pull.py 2010-06-17 09:23:19 +0000 | |||
382 | +++ bzrlib/tests/per_interbranch/test_pull.py 2011-09-02 00:55:08 +0000 | |||
383 | @@ -99,7 +99,7 @@ | |||
384 | 99 | self.assertEqual('P1', result.old_revid) | 99 | self.assertEqual('P1', result.old_revid) |
385 | 100 | self.assertEqual(2, result.new_revno) | 100 | self.assertEqual(2, result.new_revno) |
386 | 101 | self.assertEqual('M1', result.new_revid) | 101 | self.assertEqual('M1', result.new_revid) |
388 | 102 | self.assertEqual(None, result.tag_conflicts) | 102 | self.assertEqual([], result.tag_conflicts) |
389 | 103 | 103 | ||
390 | 104 | def test_pull_overwrite(self): | 104 | def test_pull_overwrite(self): |
391 | 105 | tree_a = self.make_from_branch_and_tree('tree_a') | 105 | tree_a = self.make_from_branch_and_tree('tree_a') |
392 | 106 | 106 | ||
393 | === modified file 'bzrlib/tests/test_branch.py' | |||
394 | --- bzrlib/tests/test_branch.py 2011-05-26 08:04:46 +0000 | |||
395 | +++ bzrlib/tests/test_branch.py 2011-09-02 00:55:08 +0000 | |||
396 | @@ -709,5 +709,5 @@ | |||
397 | 709 | r.new_revid = "same-revid" | 709 | r.new_revid = "same-revid" |
398 | 710 | f = StringIO() | 710 | f = StringIO() |
399 | 711 | r.report(f) | 711 | r.report(f) |
401 | 712 | self.assertEqual("No revisions to pull.\n", f.getvalue()) | 712 | self.assertEqual("No revisions or tags to pull.\n", f.getvalue()) |
402 | 713 | 713 | ||
403 | 714 | 714 | ||
404 | === modified file 'bzrlib/tests/test_tag.py' | |||
405 | --- bzrlib/tests/test_tag.py 2011-08-06 07:32:51 +0000 | |||
406 | +++ bzrlib/tests/test_tag.py 2011-09-02 00:55:08 +0000 | |||
407 | @@ -109,12 +109,14 @@ | |||
408 | 109 | self.assertRaises(errors.NoSuchTag, a.tags.lookup_tag, 'tag-2') | 109 | self.assertRaises(errors.NoSuchTag, a.tags.lookup_tag, 'tag-2') |
409 | 110 | # conflicting merge | 110 | # conflicting merge |
410 | 111 | a.tags.set_tag('tag-2', 'z') | 111 | a.tags.set_tag('tag-2', 'z') |
412 | 112 | conflicts = a.tags.merge_to(b.tags) | 112 | updates, conflicts = a.tags.merge_to(b.tags) |
413 | 113 | self.assertEqual({}, updates) | ||
414 | 113 | self.assertEqual(list(conflicts), [('tag-2', 'z', 'y')]) | 114 | self.assertEqual(list(conflicts), [('tag-2', 'z', 'y')]) |
415 | 114 | self.assertEqual('y', b.tags.lookup_tag('tag-2')) | 115 | self.assertEqual('y', b.tags.lookup_tag('tag-2')) |
416 | 115 | # overwrite conflicts | 116 | # overwrite conflicts |
418 | 116 | conflicts = a.tags.merge_to(b.tags, overwrite=True) | 117 | updates, conflicts = a.tags.merge_to(b.tags, overwrite=True) |
419 | 117 | self.assertEqual(list(conflicts), []) | 118 | self.assertEqual(list(conflicts), []) |
420 | 119 | self.assertEqual({u'tag-1': 'x', u'tag-2': 'z'}, updates) | ||
421 | 118 | self.assertEqual('z', b.tags.lookup_tag('tag-2')) | 120 | self.assertEqual('z', b.tags.lookup_tag('tag-2')) |
422 | 119 | 121 | ||
423 | 120 | 122 | ||
424 | 121 | 123 | ||
425 | === modified file 'doc/en/release-notes/bzr-2.5.txt' | |||
426 | --- doc/en/release-notes/bzr-2.5.txt 2011-09-01 18:11:38 +0000 | |||
427 | +++ doc/en/release-notes/bzr-2.5.txt 2011-09-02 00:55:08 +0000 | |||
428 | @@ -102,6 +102,9 @@ | |||
429 | 102 | Entering an empty commit message in the message editor still triggers | 102 | Entering an empty commit message in the message editor still triggers |
430 | 103 | an error. (Jelmer Vernooij) | 103 | an error. (Jelmer Vernooij) |
431 | 104 | 104 | ||
432 | 105 | * ``bzr pull`` will now mention how many tags it has updated. | ||
433 | 106 | (Jelmer Vernooij, #164450) | ||
434 | 107 | |||
435 | 105 | * ``bzr tag`` no longer errors if a tag already exists but refers to the | 108 | * ``bzr tag`` no longer errors if a tag already exists but refers to the |
436 | 106 | same revision. (Jelmer Vernooij) | 109 | same revision. (Jelmer Vernooij) |
437 | 107 | 110 | ||
438 | @@ -214,6 +217,9 @@ | |||
439 | 214 | value in SI format (i.e. "20MB", "1GB") into its integer equivalent. | 217 | value in SI format (i.e. "20MB", "1GB") into its integer equivalent. |
440 | 215 | (Shannon Weyrick) | 218 | (Shannon Weyrick) |
441 | 216 | 219 | ||
442 | 220 | * ``Tags.merge_to`` now returns a dictionary with the updated tags | ||
443 | 221 | and a set of conflicts, rather than just conflicts. (Jelmer Vernooij) | ||
444 | 222 | |||
445 | 217 | * ``Transport`` now has a ``_parsed_url`` attribute instead of | 223 | * ``Transport`` now has a ``_parsed_url`` attribute instead of |
446 | 218 | separate ``_user``, ``_password``, ``_port``, ``_scheme``, ``_host`` | 224 | separate ``_user``, ``_password``, ``_port``, ``_scheme``, ``_host`` |
447 | 219 | and ``_path`` attributes. Proxies are provided for the moment but | 225 | and ``_path`` attributes. Proxies are provided for the moment but |
[needsinfo] It seems merge_to changes caused problems in the past tags._merge_ tags_if_ possible) , what's your feeling on
(see bzrlib.
changing the signature again and the possible fallouts ? (loom ?)
Or did I misread the diff and merge_to didn't return anything
before ? Or does it matter nevertheless ?
[needsfixing] There is a lot of duplication between t.report( )
PullResult.report() and BranchPushResul
But one is using to_file_ write.write( ) and the other
trace.note(). This doesn't feel right, shouldn't they both
provide the same feedback to the user ?
[PEP8 nit] tag_conflicts = self.source. tags.merge_ to( to_master)
75 + result.tag_updates, result.
76 + self.target.tags, overwrite, ignore_master=not merge_tags_
lines too long.
[2.4-worthy] Shouldn't that be backported for the benefit of the
package importer ?