Merge lp:~jelmer/brz/tag-selector into lp:brz/3.1
- tag-selector
- Merge into 3.1
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/tag-selector |
Merge into: | lp:brz/3.1 |
Diff against target: |
1290 lines (+266/-129) 23 files modified
breezy/branch.py (+42/-26) breezy/bzr/branch.py (+1/-1) breezy/bzr/bzrdir.py (+4/-2) breezy/bzr/remote.py (+2/-2) breezy/controldir.py (+15/-8) breezy/git/branch.py (+55/-33) breezy/git/dir.py (+5/-4) breezy/git/interrepo.py (+12/-6) breezy/git/workingtree.py (+2/-2) breezy/plugins/propose/github.py (+4/-3) breezy/plugins/propose/gitlabs.py (+3/-3) breezy/plugins/propose/launchpad.py (+15/-11) breezy/plugins/weave_fmt/bzrdir.py (+2/-2) breezy/propose.py (+1/-1) breezy/tag.py (+21/-20) breezy/tests/per_branch/test_pull.py (+1/-1) breezy/tests/per_branch/test_tags.py (+15/-0) breezy/tests/per_controldir/test_push.py (+11/-0) breezy/tests/per_interbranch/test_pull.py (+21/-1) breezy/tests/per_interbranch/test_push.py (+20/-0) breezy/tests/test_foreign.py (+1/-1) breezy/tests/test_tag.py (+11/-0) breezy/workingtree.py (+2/-2) |
To merge this branch: | bzr merge lp:~jelmer/brz/tag-selector |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+379435@code.launchpad.net |
Commit message
Add a tag_selector argument to push/pull/sprout functions.
Description of the change
Add a tag_selector argument to push/pull/sprout functions.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests 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/branch.py' |
2 | --- breezy/branch.py 2020-01-20 00:03:54 +0000 |
3 | +++ breezy/branch.py 2020-02-19 23:22:37 +0000 |
4 | @@ -1194,7 +1194,8 @@ |
5 | if revno < 1 or revno > self.revno(): |
6 | raise errors.InvalidRevisionNumber(revno) |
7 | |
8 | - def clone(self, to_controldir, revision_id=None, repository_policy=None): |
9 | + def clone(self, to_controldir, revision_id=None, repository_policy=None, |
10 | + tag_selector=None): |
11 | """Clone this branch into to_controldir preserving all semantic values. |
12 | |
13 | Most API users will want 'create_clone_on_transport', which creates a |
14 | @@ -1207,11 +1208,12 @@ |
15 | with self.lock_read(), result.lock_write(): |
16 | if repository_policy is not None: |
17 | repository_policy.configure_branch(result) |
18 | - self.copy_content_into(result, revision_id=revision_id) |
19 | + self.copy_content_into( |
20 | + result, revision_id=revision_id, tag_selector=tag_selector) |
21 | return result |
22 | |
23 | def sprout(self, to_controldir, revision_id=None, repository_policy=None, |
24 | - repository=None, lossy=False): |
25 | + repository=None, lossy=False, tag_selector=None): |
26 | """Create a new line of development from the branch, into to_controldir. |
27 | |
28 | to_controldir controls the branch format. |
29 | @@ -1228,7 +1230,8 @@ |
30 | with self.lock_read(), result.lock_write(): |
31 | if repository_policy is not None: |
32 | repository_policy.configure_branch(result) |
33 | - self.copy_content_into(result, revision_id=revision_id) |
34 | + self.copy_content_into( |
35 | + result, revision_id=revision_id, tag_selector=tag_selector) |
36 | master_url = self.get_bound_location() |
37 | if master_url is None: |
38 | result.set_parent(self.user_url) |
39 | @@ -1261,14 +1264,16 @@ |
40 | revno = 1 |
41 | destination.set_last_revision_info(revno, revision_id) |
42 | |
43 | - def copy_content_into(self, destination, revision_id=None): |
44 | + def copy_content_into(self, destination, revision_id=None, tag_selector=None): |
45 | """Copy the content of self into destination. |
46 | |
47 | revision_id: if not None, the revision history in the new branch will |
48 | be truncated to end with revision_id. |
49 | + tag_selector: Optional callback that receives a tag name |
50 | + and should return a boolean to indicate whether a tag should be copied |
51 | """ |
52 | return InterBranch.get(self, destination).copy_content_into( |
53 | - revision_id=revision_id) |
54 | + revision_id=revision_id, tag_selector=tag_selector) |
55 | |
56 | def update_references(self, target): |
57 | if not self._format.supports_reference_locations: |
58 | @@ -1313,7 +1318,8 @@ |
59 | |
60 | def create_clone_on_transport(self, to_transport, revision_id=None, |
61 | stacked_on=None, create_prefix=False, |
62 | - use_existing_dir=False, no_tree=None): |
63 | + use_existing_dir=False, no_tree=None, |
64 | + tag_selector=None): |
65 | """Create a clone of this branch and its bzrdir. |
66 | |
67 | :param to_transport: The transport to clone onto. |
68 | @@ -1333,7 +1339,7 @@ |
69 | dir_to = self.controldir.clone_on_transport( |
70 | to_transport, revision_id=revision_id, stacked_on=stacked_on, |
71 | create_prefix=create_prefix, use_existing_dir=use_existing_dir, |
72 | - no_tree=no_tree) |
73 | + no_tree=no_tree, tag_selector=tag_selector) |
74 | return dir_to.open_branch() |
75 | |
76 | def create_checkout(self, to_location, revision_id=None, |
77 | @@ -2060,7 +2066,7 @@ |
78 | raise NotImplementedError(klass._get_branch_formats_to_test) |
79 | |
80 | def pull(self, overwrite=False, stop_revision=None, |
81 | - possible_transports=None, local=False): |
82 | + possible_transports=None, local=False, tag_selector=None): |
83 | """Mirror source into target branch. |
84 | |
85 | The target branch is considered to be 'local', having low latency. |
86 | @@ -2070,18 +2076,21 @@ |
87 | raise NotImplementedError(self.pull) |
88 | |
89 | def push(self, overwrite=False, stop_revision=None, lossy=False, |
90 | - _override_hook_source_branch=None): |
91 | + _override_hook_source_branch=None, tag_selector=None): |
92 | """Mirror the source branch into the target branch. |
93 | |
94 | The source branch is considered to be 'local', having low latency. |
95 | """ |
96 | raise NotImplementedError(self.push) |
97 | |
98 | - def copy_content_into(self, revision_id=None): |
99 | + def copy_content_into(self, revision_id=None, tag_selector=None): |
100 | """Copy the content of source into target |
101 | |
102 | - revision_id: if not None, the revision history in the new branch will |
103 | - be truncated to end with revision_id. |
104 | + :param revision_id: |
105 | + if not None, the revision history in the new branch will |
106 | + be truncated to end with revision_id. |
107 | + :param tag_selector: Optional callback that can decide |
108 | + to copy or not copy tags. |
109 | """ |
110 | raise NotImplementedError(self.copy_content_into) |
111 | |
112 | @@ -2128,7 +2137,7 @@ |
113 | return format._custom_format |
114 | return format |
115 | |
116 | - def copy_content_into(self, revision_id=None): |
117 | + def copy_content_into(self, revision_id=None, tag_selector=None): |
118 | """Copy the content of source into target |
119 | |
120 | revision_id: if not None, the revision history in the new branch will |
121 | @@ -2145,7 +2154,7 @@ |
122 | if parent: |
123 | self.target.set_parent(parent) |
124 | if self.source._push_should_merge_tags(): |
125 | - self.source.tags.merge_to(self.target.tags) |
126 | + self.source.tags.merge_to(self.target.tags, selector=tag_selector) |
127 | |
128 | def fetch(self, stop_revision=None, limit=None, lossy=False): |
129 | if self.target.base == self.source.base: |
130 | @@ -2206,7 +2215,8 @@ |
131 | |
132 | def pull(self, overwrite=False, stop_revision=None, |
133 | possible_transports=None, run_hooks=True, |
134 | - _override_hook_target=None, local=False): |
135 | + _override_hook_target=None, local=False, |
136 | + tag_selector=None): |
137 | """Pull from source into self, updating my master if any. |
138 | |
139 | :param run_hooks: Private parameter - if false, this branch |
140 | @@ -2237,15 +2247,17 @@ |
141 | if master_branch: |
142 | # pull from source into master. |
143 | master_branch.pull( |
144 | - self.source, overwrite, stop_revision, run_hooks=False) |
145 | + self.source, overwrite, stop_revision, run_hooks=False, |
146 | + tag_selector=tag_selector) |
147 | return self._pull( |
148 | overwrite, stop_revision, _hook_master=master_branch, |
149 | run_hooks=run_hooks, |
150 | _override_hook_target=_override_hook_target, |
151 | - merge_tags_to_master=not source_is_master) |
152 | + merge_tags_to_master=not source_is_master, |
153 | + tag_selector=tag_selector) |
154 | |
155 | def push(self, overwrite=False, stop_revision=None, lossy=False, |
156 | - _override_hook_source_branch=None): |
157 | + _override_hook_source_branch=None, tag_selector=None): |
158 | """See InterBranch.push. |
159 | |
160 | This is the basic concrete implementation of push() |
161 | @@ -2277,18 +2289,21 @@ |
162 | with master_branch.lock_write(): |
163 | # push into the master from the source branch. |
164 | master_inter = InterBranch.get(self.source, master_branch) |
165 | - master_inter._basic_push(overwrite, stop_revision) |
166 | + master_inter._basic_push( |
167 | + overwrite, stop_revision, tag_selector=tag_selector) |
168 | # and push into the target branch from the source. Note |
169 | # that we push from the source branch again, because it's |
170 | # considered the highest bandwidth repository. |
171 | - result = self._basic_push(overwrite, stop_revision) |
172 | + result = self._basic_push( |
173 | + overwrite, stop_revision, tag_selector=tag_selector) |
174 | result.master_branch = master_branch |
175 | result.local_branch = self.target |
176 | _run_hooks() |
177 | else: |
178 | master_branch = None |
179 | # no master branch |
180 | - result = self._basic_push(overwrite, stop_revision) |
181 | + result = self._basic_push( |
182 | + overwrite, stop_revision, tag_selector=tag_selector) |
183 | # TODO: Why set master_branch and local_branch if there's no |
184 | # binding? Maybe cleaner to just leave them unset? -- mbp |
185 | # 20070504 |
186 | @@ -2297,7 +2312,7 @@ |
187 | _run_hooks() |
188 | return result |
189 | |
190 | - def _basic_push(self, overwrite, stop_revision): |
191 | + def _basic_push(self, overwrite, stop_revision, tag_selector=None): |
192 | """Basic implementation of push without bound branches or hooks. |
193 | |
194 | Must be called with source read locked and target write locked. |
195 | @@ -2316,7 +2331,7 @@ |
196 | if self.source._push_should_merge_tags(): |
197 | result.tag_updates, result.tag_conflicts = ( |
198 | self.source.tags.merge_to( |
199 | - self.target.tags, "tags" in overwrite)) |
200 | + self.target.tags, "tags" in overwrite, selector=tag_selector)) |
201 | self.update_references() |
202 | result.new_revno, result.new_revid = self.target.last_revision_info() |
203 | return result |
204 | @@ -2324,7 +2339,7 @@ |
205 | def _pull(self, overwrite=False, stop_revision=None, |
206 | possible_transports=None, _hook_master=None, run_hooks=True, |
207 | _override_hook_target=None, local=False, |
208 | - merge_tags_to_master=True): |
209 | + merge_tags_to_master=True, tag_selector=None): |
210 | """See Branch.pull. |
211 | |
212 | This function is the core worker, used by GenericInterBranch.pull to |
213 | @@ -2368,7 +2383,8 @@ |
214 | result.tag_updates, result.tag_conflicts = ( |
215 | self.source.tags.merge_to( |
216 | self.target.tags, "tags" in overwrite, |
217 | - ignore_master=not merge_tags_to_master)) |
218 | + ignore_master=not merge_tags_to_master, |
219 | + selector=tag_selector)) |
220 | self.update_references() |
221 | result.new_revno, result.new_revid = ( |
222 | self.target.last_revision_info()) |
223 | |
224 | === modified file 'breezy/bzr/branch.py' |
225 | --- breezy/bzr/branch.py 2020-02-18 01:32:25 +0000 |
226 | +++ breezy/bzr/branch.py 2020-02-19 23:22:37 +0000 |
227 | @@ -1033,7 +1033,7 @@ |
228 | def _make_reference_clone_function(format, a_branch): |
229 | """Create a clone() routine for a branch dynamically.""" |
230 | def clone(to_bzrdir, revision_id=None, |
231 | - repository_policy=None): |
232 | + repository_policy=None, tag_selector=None): |
233 | """See Branch.clone().""" |
234 | return format.initialize(to_bzrdir, target_branch=a_branch) |
235 | # cannot obey revision_id limits when cloning a reference ... |
236 | |
237 | === modified file 'breezy/bzr/bzrdir.py' |
238 | --- breezy/bzr/bzrdir.py 2020-01-19 01:29:22 +0000 |
239 | +++ breezy/bzr/bzrdir.py 2020-02-19 23:22:37 +0000 |
240 | @@ -143,7 +143,8 @@ |
241 | |
242 | def clone_on_transport(self, transport, revision_id=None, |
243 | force_new_repo=False, preserve_stacking=False, stacked_on=None, |
244 | - create_prefix=False, use_existing_dir=True, no_tree=False): |
245 | + create_prefix=False, use_existing_dir=True, no_tree=False, |
246 | + tag_selector=None): |
247 | """Clone this bzrdir and its contents to transport verbatim. |
248 | |
249 | :param transport: The transport for the location to produce the clone |
250 | @@ -235,7 +236,8 @@ |
251 | if local_branch is not None: |
252 | local_branch.clone( |
253 | result, revision_id=revision_id, |
254 | - repository_policy=repository_policy) |
255 | + repository_policy=repository_policy, |
256 | + tag_selector=tag_selector) |
257 | try: |
258 | # Cheaper to check if the target is not local, than to try making |
259 | # the tree and fail. |
260 | |
261 | === modified file 'breezy/bzr/remote.py' |
262 | --- breezy/bzr/remote.py 2020-02-09 01:16:06 +0000 |
263 | +++ breezy/bzr/remote.py 2020-02-19 23:22:37 +0000 |
264 | @@ -4033,12 +4033,12 @@ |
265 | source, overwrite=overwrite, stop_revision=stop_revision, |
266 | _override_hook_target=self, **kwargs) |
267 | |
268 | - def push(self, target, overwrite=False, stop_revision=None, lossy=False): |
269 | + def push(self, target, overwrite=False, stop_revision=None, lossy=False, tag_selector=None): |
270 | with self.lock_read(): |
271 | self._ensure_real() |
272 | return self._real_branch.push( |
273 | target, overwrite=overwrite, stop_revision=stop_revision, lossy=lossy, |
274 | - _override_hook_source_branch=self) |
275 | + _override_hook_source_branch=self, tag_selector=tag_selector) |
276 | |
277 | def peek_lock_mode(self): |
278 | return self._lock_mode |
279 | |
280 | === modified file 'breezy/controldir.py' |
281 | --- breezy/controldir.py 2019-11-06 01:31:41 +0000 |
282 | +++ breezy/controldir.py 2020-02-19 23:22:37 +0000 |
283 | @@ -400,7 +400,8 @@ |
284 | raise NotImplementedError(self.sprout) |
285 | |
286 | def push_branch(self, source, revision_id=None, overwrite=False, |
287 | - remember=False, create_prefix=False, lossy=False): |
288 | + remember=False, create_prefix=False, lossy=False, |
289 | + tag_selector=None): |
290 | """Push the source branch into this ControlDir.""" |
291 | br_to = None |
292 | # If we can open a branch, use its direct repository, otherwise see |
293 | @@ -424,7 +425,9 @@ |
294 | # revision |
295 | revision_id = source.last_revision() |
296 | repository_to.fetch(source.repository, revision_id=revision_id) |
297 | - br_to = source.sprout(self, revision_id=revision_id, lossy=lossy) |
298 | + br_to = source.sprout( |
299 | + self, revision_id=revision_id, lossy=lossy, |
300 | + tag_selector=tag_selector) |
301 | if source.get_push_location() is None or remember: |
302 | # FIXME: Should be done only if we succeed ? -- vila 2012-01-18 |
303 | source.set_push_location(br_to.base) |
304 | @@ -444,17 +447,19 @@ |
305 | tree_to = self.open_workingtree() |
306 | except errors.NotLocalUrl: |
307 | push_result.branch_push_result = source.push( |
308 | - br_to, overwrite, stop_revision=revision_id, lossy=lossy) |
309 | + br_to, overwrite, stop_revision=revision_id, lossy=lossy, |
310 | + tag_selector=tag_selector) |
311 | push_result.workingtree_updated = False |
312 | except errors.NoWorkingTree: |
313 | push_result.branch_push_result = source.push( |
314 | - br_to, overwrite, stop_revision=revision_id, lossy=lossy) |
315 | + br_to, overwrite, stop_revision=revision_id, lossy=lossy, |
316 | + tag_selector=tag_selector) |
317 | push_result.workingtree_updated = None # Not applicable |
318 | else: |
319 | with tree_to.lock_write(): |
320 | push_result.branch_push_result = source.push( |
321 | tree_to.branch, overwrite, stop_revision=revision_id, |
322 | - lossy=lossy) |
323 | + lossy=lossy, tag_selector=tag_selector) |
324 | tree_to.update() |
325 | push_result.workingtree_updated = True |
326 | push_result.old_revno = push_result.branch_push_result.old_revno |
327 | @@ -493,7 +498,7 @@ |
328 | raise NotImplementedError(self.check_conversion_target) |
329 | |
330 | def clone(self, url, revision_id=None, force_new_repo=False, |
331 | - preserve_stacking=False): |
332 | + preserve_stacking=False, tag_selector=None): |
333 | """Clone this controldir and its contents to url verbatim. |
334 | |
335 | :param url: The url create the clone at. If url's last component does |
336 | @@ -509,11 +514,13 @@ |
337 | return self.clone_on_transport(_mod_transport.get_transport(url), |
338 | revision_id=revision_id, |
339 | force_new_repo=force_new_repo, |
340 | - preserve_stacking=preserve_stacking) |
341 | + preserve_stacking=preserve_stacking, |
342 | + tag_selector=tag_selector) |
343 | |
344 | def clone_on_transport(self, transport, revision_id=None, |
345 | force_new_repo=False, preserve_stacking=False, stacked_on=None, |
346 | - create_prefix=False, use_existing_dir=True, no_tree=False): |
347 | + create_prefix=False, use_existing_dir=True, no_tree=False, |
348 | + tag_selector=None): |
349 | """Clone this controldir and its contents to transport verbatim. |
350 | |
351 | :param transport: The transport for the location to produce the clone |
352 | |
353 | === modified file 'breezy/git/branch.py' |
354 | --- breezy/git/branch.py 2020-02-18 01:27:12 +0000 |
355 | +++ breezy/git/branch.py 2020-02-19 23:22:37 +0000 |
356 | @@ -131,7 +131,7 @@ |
357 | return False |
358 | return True |
359 | |
360 | - def merge(self, overwrite=False, ignore_master=False): |
361 | + def merge(self, overwrite=False, ignore_master=False, selector=None): |
362 | if self.source.branch.repository.has_same_location(self.target.branch.repository): |
363 | return {}, [] |
364 | updates = {} |
365 | @@ -142,6 +142,8 @@ |
366 | ret = dict(old_refs) |
367 | for ref_name, tag_name, peeled, unpeeled in ( |
368 | source_tag_refs.iteritems()): |
369 | + if selector and not selector(tag_name): |
370 | + continue |
371 | if old_refs.get(ref_name) == unpeeled: |
372 | pass |
373 | elif overwrite or ref_name not in old_refs: |
374 | @@ -158,7 +160,7 @@ |
375 | return ret |
376 | self.target.branch.repository.controldir.send_pack( |
377 | get_changed_refs, lambda have, want: []) |
378 | - return updates, conflicts |
379 | + return updates, set(conflicts) |
380 | |
381 | |
382 | class InterTagsFromGitToLocalGit(InterTags): |
383 | @@ -173,7 +175,7 @@ |
384 | return False |
385 | return True |
386 | |
387 | - def merge(self, overwrite=False, ignore_master=False): |
388 | + def merge(self, overwrite=False, ignore_master=False, selector=None): |
389 | if self.source.branch.repository.has_same_location(self.target.branch.repository): |
390 | return {}, [] |
391 | |
392 | @@ -184,6 +186,8 @@ |
393 | target_repo = self.target.branch.repository |
394 | |
395 | for ref_name, tag_name, peeled, unpeeled in source_tag_refs: |
396 | + if selector and not selector(tag_name): |
397 | + continue |
398 | if target_repo._git.refs.get(ref_name) == unpeeled: |
399 | pass |
400 | elif overwrite or ref_name not in target_repo._git.refs: |
401 | @@ -215,7 +219,7 @@ |
402 | tag_name) |
403 | continue |
404 | conflicts.append((tag_name, source_revid, target_revid)) |
405 | - return updates, conflicts |
406 | + return updates, set(conflicts) |
407 | |
408 | |
409 | class InterTagsFromGitToNonGit(InterTags): |
410 | @@ -228,7 +232,7 @@ |
411 | return False |
412 | return True |
413 | |
414 | - def merge(self, overwrite=False, ignore_master=False): |
415 | + def merge(self, overwrite=False, ignore_master=False, selector=None): |
416 | """See Tags.merge_to.""" |
417 | source_tag_refs = self.source.branch.get_tag_refs() |
418 | if ignore_master: |
419 | @@ -239,22 +243,26 @@ |
420 | if master is not None: |
421 | es.enter_context(master.lock_write()) |
422 | updates, conflicts = self._merge_to( |
423 | - self.target, source_tag_refs, overwrite=overwrite) |
424 | + self.target, source_tag_refs, overwrite=overwrite, |
425 | + selector=selector) |
426 | if master is not None: |
427 | extra_updates, extra_conflicts = self._merge_to( |
428 | master.tags, overwrite=overwrite, |
429 | source_tag_refs=source_tag_refs, |
430 | - ignore_master=ignore_master) |
431 | + ignore_master=ignore_master, selector=selector) |
432 | updates.update(extra_updates) |
433 | - conflicts += extra_conflicts |
434 | + conflicts.update(extra_conflicts) |
435 | return updates, conflicts |
436 | |
437 | - def _merge_to(self, to_tags, source_tag_refs, overwrite=False): |
438 | + def _merge_to(self, to_tags, source_tag_refs, overwrite=False, |
439 | + selector=None): |
440 | unpeeled_map = defaultdict(set) |
441 | conflicts = [] |
442 | updates = {} |
443 | result = dict(to_tags.get_tag_dict()) |
444 | for ref_name, tag_name, peeled, unpeeled in source_tag_refs: |
445 | + if selector and not selector(tag_name): |
446 | + continue |
447 | if unpeeled is not None: |
448 | unpeeled_map[peeled].add(unpeeled) |
449 | try: |
450 | @@ -273,7 +281,7 @@ |
451 | map_file = UnpeelMap.from_repository(to_tags.branch.repository) |
452 | map_file.update(unpeeled_map) |
453 | map_file.save_in_repository(to_tags.branch.repository) |
454 | - return updates, conflicts |
455 | + return updates, set(conflicts) |
456 | |
457 | |
458 | InterTags.register_optimiser(InterTagsFromGitToRemoteGit) |
459 | @@ -659,9 +667,10 @@ |
460 | return revision.NULL_REVISION |
461 | return self.lookup_foreign_revision_id(self.head) |
462 | |
463 | - def _basic_push(self, target, overwrite=False, stop_revision=None): |
464 | + def _basic_push(self, target, overwrite=False, stop_revision=None, |
465 | + tag_selector=None): |
466 | return branch.InterBranch.get(self, target)._basic_push( |
467 | - overwrite, stop_revision) |
468 | + overwrite, stop_revision, tag_selector=tag_selector) |
469 | |
470 | def lookup_foreign_revision_id(self, foreign_revid): |
471 | try: |
472 | @@ -981,7 +990,7 @@ |
473 | stop_revision, fetch_tags=fetch_tags, limit=limit, lossy=lossy) |
474 | return _mod_repository.FetchResult() |
475 | |
476 | - def fetch_objects(self, stop_revision, fetch_tags, limit=None, lossy=False): |
477 | + def fetch_objects(self, stop_revision, fetch_tags, limit=None, lossy=False, tag_selector=None): |
478 | interrepo = self._get_interrepo(self.source, self.target) |
479 | if fetch_tags is None: |
480 | c = self.source.get_config_stack() |
481 | @@ -999,7 +1008,7 @@ |
482 | else: |
483 | self._last_revid = stop_revision |
484 | real = interrepo.get_determine_wants_revids( |
485 | - [self._last_revid], include_tags=fetch_tags) |
486 | + [self._last_revid], include_tags=fetch_tags, tag_selector=tag_selector) |
487 | return real(heads) |
488 | pack_hint, head, refs = interrepo.fetch_objects( |
489 | determine_wants, self.source.mapping, limit=limit, |
490 | @@ -1009,8 +1018,8 @@ |
491 | self.target.repository.pack(hint=pack_hint) |
492 | return head, refs |
493 | |
494 | - def _update_revisions(self, stop_revision=None, overwrite=False): |
495 | - head, refs = self.fetch_objects(stop_revision, fetch_tags=None) |
496 | + def _update_revisions(self, stop_revision=None, overwrite=False, tag_selector=None): |
497 | + head, refs = self.fetch_objects(stop_revision, fetch_tags=None, tag_selector=tag_selector) |
498 | if overwrite: |
499 | prev_last_revid = None |
500 | else: |
501 | @@ -1035,7 +1044,7 @@ |
502 | pass |
503 | |
504 | def _basic_pull(self, stop_revision, overwrite, run_hooks, |
505 | - _override_hook_target, _hook_master): |
506 | + _override_hook_target, _hook_master, tag_selector=None): |
507 | if overwrite is True: |
508 | overwrite = set(["history", "tags"]) |
509 | elif not overwrite: |
510 | @@ -1052,7 +1061,8 @@ |
511 | (result.old_revno, result.old_revid) = \ |
512 | self.target.last_revision_info() |
513 | result.new_git_head, remote_refs = self._update_revisions( |
514 | - stop_revision, overwrite=("history" in overwrite)) |
515 | + stop_revision, overwrite=("history" in overwrite), |
516 | + tag_selector=tag_selector) |
517 | tags_ret = self.source.tags.merge_to( |
518 | self.target.tags, ("tags" in overwrite), ignore_master=True) |
519 | if isinstance(tags_ret, tuple): |
520 | @@ -1075,7 +1085,7 @@ |
521 | |
522 | def pull(self, overwrite=False, stop_revision=None, |
523 | possible_transports=None, _hook_master=None, run_hooks=True, |
524 | - _override_hook_target=None, local=False): |
525 | + _override_hook_target=None, local=False, tag_selector=None): |
526 | """See Branch.pull. |
527 | |
528 | :param _hook_master: Private parameter - set the branch to |
529 | @@ -1113,9 +1123,10 @@ |
530 | master_branch = None |
531 | return self._basic_pull(stop_revision, overwrite, run_hooks, |
532 | _override_hook_target, |
533 | - _hook_master=master_branch) |
534 | + _hook_master=master_branch, |
535 | + tag_selector=tag_selector) |
536 | |
537 | - def _basic_push(self, overwrite, stop_revision): |
538 | + def _basic_push(self, overwrite, stop_revision, tag_selector=None): |
539 | if overwrite is True: |
540 | overwrite = set(["history", "tags"]) |
541 | elif not overwrite: |
542 | @@ -1125,9 +1136,11 @@ |
543 | result.target_branch = self.target |
544 | result.old_revno, result.old_revid = self.target.last_revision_info() |
545 | result.new_git_head, remote_refs = self._update_revisions( |
546 | - stop_revision, overwrite=("history" in overwrite)) |
547 | + stop_revision, overwrite=("history" in overwrite), |
548 | + tag_selector=tag_selector) |
549 | tags_ret = self.source.tags.merge_to( |
550 | - self.target.tags, "tags" in overwrite, ignore_master=True) |
551 | + self.target.tags, "tags" in overwrite, ignore_master=True, |
552 | + selector=tag_selector) |
553 | (result.tag_updates, result.tag_conflicts) = tags_ret |
554 | result.new_revno, result.new_revid = self.target.last_revision_info() |
555 | self.update_references(revid=result.new_revid) |
556 | @@ -1156,7 +1169,7 @@ |
557 | return (isinstance(source, LocalGitBranch) and |
558 | isinstance(target, RemoteGitBranch)) |
559 | |
560 | - def _basic_push(self, overwrite, stop_revision): |
561 | + def _basic_push(self, overwrite, stop_revision, tag_selector=None): |
562 | result = GitBranchPushResult() |
563 | result.source_branch = self.source |
564 | result.target_branch = self.target |
565 | @@ -1181,6 +1194,8 @@ |
566 | result.new_revid = stop_revision |
567 | for name, sha in viewitems( |
568 | self.source.repository._git.refs.as_dict(b"refs/tags")): |
569 | + if tag_selector and not tag_selector(name): |
570 | + continue |
571 | if sha not in self.source.repository._git: |
572 | trace.mutter('Ignoring missing SHA: %s', sha) |
573 | continue |
574 | @@ -1220,7 +1235,7 @@ |
575 | interrepo.fetch_objects(determine_wants, limit=limit, lossy=lossy) |
576 | return _mod_repository.FetchResult() |
577 | |
578 | - def _basic_push(self, overwrite=False, stop_revision=None): |
579 | + def _basic_push(self, overwrite=False, stop_revision=None, tag_selector=None): |
580 | if overwrite is True: |
581 | overwrite = set(["history", "tags"]) |
582 | elif not overwrite: |
583 | @@ -1236,7 +1251,8 @@ |
584 | other_branch=self.source) |
585 | tags_ret = self.source.tags.merge_to( |
586 | self.target.tags, |
587 | - overwrite=("tags" in overwrite)) |
588 | + overwrite=("tags" in overwrite), |
589 | + selector=tag_selector) |
590 | if isinstance(tags_ret, tuple): |
591 | (result.tag_updates, result.tag_conflicts) = tags_ret |
592 | else: |
593 | @@ -1264,7 +1280,8 @@ |
594 | return result.refs, stop_revision |
595 | |
596 | def pull(self, stop_revision=None, overwrite=False, |
597 | - possible_transports=None, run_hooks=True, local=False): |
598 | + possible_transports=None, run_hooks=True, local=False, |
599 | + tag_selector=None): |
600 | # This type of branch can't be bound. |
601 | if local: |
602 | raise errors.LocalRequiresBoundBranch() |
603 | @@ -1284,7 +1301,8 @@ |
604 | (result.old_revid if ("history" not in overwrite) else None), |
605 | other_branch=self.source) |
606 | tags_ret = self.source.tags.merge_to( |
607 | - self.target.tags, overwrite=("tags" in overwrite)) |
608 | + self.target.tags, overwrite=("tags" in overwrite), |
609 | + selector=tag_selector) |
610 | if isinstance(tags_ret, tuple): |
611 | (result.tag_updates, result.tag_conflicts) = tags_ret |
612 | else: |
613 | @@ -1352,7 +1370,7 @@ |
614 | refs[ref] = (None, revid) |
615 | return refs, main_ref, (stop_revno, stop_revision) |
616 | |
617 | - def _update_refs(self, result, old_refs, new_refs, overwrite): |
618 | + def _update_refs(self, result, old_refs, new_refs, overwrite, tag_selector): |
619 | mutter("updating refs. old refs: %r, new refs: %r", |
620 | old_refs, new_refs) |
621 | result.tag_updates = {} |
622 | @@ -1391,6 +1409,8 @@ |
623 | except ValueError: |
624 | pass |
625 | else: |
626 | + if tag_selector and not tag_selector(tag_name): |
627 | + continue |
628 | result.tag_updates[tag_name] = revid |
629 | ret[ref] = (git_sha, revid) |
630 | else: |
631 | @@ -1426,7 +1446,8 @@ |
632 | for (old_revid, (new_sha, new_revid)) in revidmap.items()}) |
633 | |
634 | def pull(self, overwrite=False, stop_revision=None, local=False, |
635 | - possible_transports=None, run_hooks=True, _stop_revno=None): |
636 | + possible_transports=None, run_hooks=True, _stop_revno=None, |
637 | + tag_selector=None): |
638 | result = GitBranchPullResult() |
639 | result.source_branch = self.source |
640 | result.target_branch = self.target |
641 | @@ -1435,7 +1456,7 @@ |
642 | stop_revision, stop_revno=_stop_revno) |
643 | |
644 | def update_refs(old_refs): |
645 | - return self._update_refs(result, old_refs, new_refs, overwrite) |
646 | + return self._update_refs(result, old_refs, new_refs, overwrite, tag_selector) |
647 | try: |
648 | result.revidmap, old_refs, new_refs = ( |
649 | self.interrepo.fetch_refs(update_refs, lossy=False)) |
650 | @@ -1455,7 +1476,8 @@ |
651 | return result |
652 | |
653 | def push(self, overwrite=False, stop_revision=None, lossy=False, |
654 | - _override_hook_source_branch=None, _stop_revno=None): |
655 | + _override_hook_source_branch=None, _stop_revno=None, |
656 | + tag_selector=None): |
657 | result = GitBranchPushResult() |
658 | result.source_branch = self.source |
659 | result.target_branch = self.target |
660 | @@ -1466,7 +1488,7 @@ |
661 | stop_revision, stop_revno=_stop_revno) |
662 | |
663 | def update_refs(old_refs): |
664 | - return self._update_refs(result, old_refs, new_refs, overwrite) |
665 | + return self._update_refs(result, old_refs, new_refs, overwrite, tag_selector) |
666 | try: |
667 | result.revidmap, old_refs, new_refs = ( |
668 | self.interrepo.fetch_refs( |
669 | |
670 | === modified file 'breezy/git/dir.py' |
671 | --- breezy/git/dir.py 2020-01-18 16:14:28 +0000 |
672 | +++ breezy/git/dir.py 2020-02-19 23:22:37 +0000 |
673 | @@ -223,7 +223,8 @@ |
674 | def clone_on_transport(self, transport, revision_id=None, |
675 | force_new_repo=False, preserve_stacking=False, |
676 | stacked_on=None, create_prefix=False, |
677 | - use_existing_dir=True, no_tree=False): |
678 | + use_existing_dir=True, no_tree=False, |
679 | + tag_selector=None): |
680 | """See ControlDir.clone_on_transport.""" |
681 | from ..repository import InterRepository |
682 | from .mapping import default_mapping |
683 | @@ -245,7 +246,7 @@ |
684 | interrepo = InterRepository.get(source_repo, target_repo) |
685 | if revision_id is not None: |
686 | determine_wants = interrepo.get_determine_wants_revids( |
687 | - [revision_id], include_tags=True) |
688 | + [revision_id], include_tags=True, tag_selector=tag_selector) |
689 | else: |
690 | determine_wants = interrepo.determine_wants_all |
691 | (pack_hint, _, refs) = interrepo.fetch_objects(determine_wants, |
692 | @@ -317,7 +318,7 @@ |
693 | |
694 | def push_branch(self, source, revision_id=None, overwrite=False, |
695 | remember=False, create_prefix=False, lossy=False, |
696 | - name=None): |
697 | + name=None, tag_selector=None): |
698 | """Push the source branch into this ControlDir.""" |
699 | push_result = GitPushResult() |
700 | push_result.workingtree_updated = None |
701 | @@ -330,7 +331,7 @@ |
702 | target = self.open_branch(name, nascent_ok=True) |
703 | push_result.branch_push_result = source.push( |
704 | target, overwrite=overwrite, stop_revision=revision_id, |
705 | - lossy=lossy) |
706 | + lossy=lossy, tag_selector=tag_selector) |
707 | push_result.new_revid = push_result.branch_push_result.new_revid |
708 | push_result.old_revid = push_result.branch_push_result.old_revid |
709 | try: |
710 | |
711 | === modified file 'breezy/git/interrepo.py' |
712 | --- breezy/git/interrepo.py 2020-01-20 00:26:26 +0000 |
713 | +++ breezy/git/interrepo.py 2020-02-19 23:22:37 +0000 |
714 | @@ -81,6 +81,7 @@ |
715 | ) |
716 | from .refs import ( |
717 | is_tag, |
718 | + ref_to_tag_name, |
719 | ) |
720 | from .repository import ( |
721 | GitRepository, |
722 | @@ -409,7 +410,7 @@ |
723 | def _target_has_shas(self, shas): |
724 | raise NotImplementedError(self._target_has_shas) |
725 | |
726 | - def get_determine_wants_heads(self, wants, include_tags=False): |
727 | + def get_determine_wants_heads(self, wants, include_tags=False, tag_selector=None): |
728 | wants = set(wants) |
729 | |
730 | def determine_wants(refs): |
731 | @@ -422,7 +423,11 @@ |
732 | for k, sha in viewitems(refs): |
733 | if k.endswith(ANNOTATED_TAG_SUFFIX): |
734 | continue |
735 | - if not is_tag(k): |
736 | + try: |
737 | + tag_name = ref_to_tag_name(k) |
738 | + except ValueError: |
739 | + continue |
740 | + if tag_selector and not tag_selector(tag_name): |
741 | continue |
742 | if sha == ZERO_SHA: |
743 | continue |
744 | @@ -508,14 +513,15 @@ |
745 | """ |
746 | raise NotImplementedError(self.fetch_objects) |
747 | |
748 | - def get_determine_wants_revids(self, revids, include_tags=False): |
749 | + def get_determine_wants_revids(self, revids, include_tags=False, tag_selector=None): |
750 | wants = set() |
751 | for revid in set(revids): |
752 | if self.target.has_revision(revid): |
753 | continue |
754 | git_sha, mapping = self.source.lookup_bzr_revision_id(revid) |
755 | wants.add(git_sha) |
756 | - return self.get_determine_wants_heads(wants, include_tags=include_tags) |
757 | + return self.get_determine_wants_heads( |
758 | + wants, include_tags=include_tags, tag_selector=tag_selector) |
759 | |
760 | def fetch(self, revision_id=None, find_ghosts=False, |
761 | mapping=None, fetch_spec=None, include_tags=False, lossy=False): |
762 | @@ -688,14 +694,14 @@ |
763 | result.refs = wants_recorder.remote_refs |
764 | return result |
765 | |
766 | - def get_determine_wants_revids(self, revids, include_tags=False): |
767 | + def get_determine_wants_revids(self, revids, include_tags=False, tag_selector=None): |
768 | wants = set() |
769 | for revid in set(revids): |
770 | if revid == NULL_REVISION: |
771 | continue |
772 | git_sha, mapping = self.source.lookup_bzr_revision_id(revid) |
773 | wants.add(git_sha) |
774 | - return self.get_determine_wants_heads(wants, include_tags=include_tags) |
775 | + return self.get_determine_wants_heads(wants, include_tags=include_tags, tag_selector=tag_selector) |
776 | |
777 | def get_determine_wants_branches(self, branches, include_tags=False): |
778 | def determine_wants(refs): |
779 | |
780 | === modified file 'breezy/git/workingtree.py' |
781 | --- breezy/git/workingtree.py 2020-01-19 01:29:22 +0000 |
782 | +++ breezy/git/workingtree.py 2020-02-19 23:22:37 +0000 |
783 | @@ -1213,12 +1213,12 @@ |
784 | |
785 | def pull(self, source, overwrite=False, stop_revision=None, |
786 | change_reporter=None, possible_transports=None, local=False, |
787 | - show_base=False): |
788 | + show_base=False, tag_selector=None): |
789 | with self.lock_write(), source.lock_read(): |
790 | old_revision = self.branch.last_revision() |
791 | count = self.branch.pull(source, overwrite, stop_revision, |
792 | possible_transports=possible_transports, |
793 | - local=local) |
794 | + local=local, tag_selector=tag_selector) |
795 | self._update_git_tree( |
796 | old_revision=old_revision, |
797 | new_revision=self.branch.last_revision(), |
798 | |
799 | === modified file 'breezy/plugins/propose/github.py' |
800 | --- breezy/plugins/propose/github.py 2020-02-15 14:33:33 +0000 |
801 | +++ breezy/plugins/propose/github.py 2020-02-19 23:22:37 +0000 |
802 | @@ -379,7 +379,7 @@ |
803 | |
804 | def publish_derived(self, local_branch, base_branch, name, project=None, |
805 | owner=None, revision_id=None, overwrite=False, |
806 | - allow_lossy=True): |
807 | + allow_lossy=True, tag_selector=None): |
808 | base_owner, base_project, base_branch_name = parse_github_branch_url(base_branch) |
809 | base_repo = self._get_repo(base_owner, base_project) |
810 | if owner is None: |
811 | @@ -399,13 +399,14 @@ |
812 | try: |
813 | push_result = remote_dir.push_branch( |
814 | local_branch, revision_id=revision_id, overwrite=overwrite, |
815 | - name=name) |
816 | + name=name, tag_selector=tag_selector) |
817 | except errors.NoRoundtrippingSupport: |
818 | if not allow_lossy: |
819 | raise |
820 | push_result = remote_dir.push_branch( |
821 | local_branch, revision_id=revision_id, |
822 | - overwrite=overwrite, name=name, lossy=True) |
823 | + overwrite=overwrite, name=name, lossy=True, |
824 | + tag_selector=tag_selector) |
825 | return push_result.target_branch, github_url_to_bzr_url( |
826 | remote_repo['html_url'], name) |
827 | |
828 | |
829 | === modified file 'breezy/plugins/propose/gitlabs.py' |
830 | --- breezy/plugins/propose/gitlabs.py 2020-01-28 23:33:16 +0000 |
831 | +++ breezy/plugins/propose/gitlabs.py 2020-02-19 23:22:37 +0000 |
832 | @@ -418,7 +418,7 @@ |
833 | |
834 | def publish_derived(self, local_branch, base_branch, name, project=None, |
835 | owner=None, revision_id=None, overwrite=False, |
836 | - allow_lossy=True): |
837 | + allow_lossy=True, tag_selector=None): |
838 | (host, base_project, base_branch_name) = parse_gitlab_branch_url(base_branch) |
839 | if owner is None: |
840 | owner = self._get_logged_in_username() |
841 | @@ -433,13 +433,13 @@ |
842 | try: |
843 | push_result = remote_dir.push_branch( |
844 | local_branch, revision_id=revision_id, overwrite=overwrite, |
845 | - name=name) |
846 | + name=name, tag_selector=tag_selector) |
847 | except errors.NoRoundtrippingSupport: |
848 | if not allow_lossy: |
849 | raise |
850 | push_result = remote_dir.push_branch( |
851 | local_branch, revision_id=revision_id, overwrite=overwrite, |
852 | - name=name, lossy=True) |
853 | + name=name, lossy=True, tag_selector=tag_selector) |
854 | public_url = gitlab_url_to_bzr_url( |
855 | target_project['http_url_to_repo'], name) |
856 | return push_result.target_branch, public_url |
857 | |
858 | === modified file 'breezy/plugins/propose/launchpad.py' |
859 | --- breezy/plugins/propose/launchpad.py 2020-01-28 23:33:16 +0000 |
860 | +++ breezy/plugins/propose/launchpad.py 2020-02-19 23:22:37 +0000 |
861 | @@ -260,7 +260,8 @@ |
862 | return "~%s/%s" % (owner, project) |
863 | |
864 | def _publish_git(self, local_branch, base_path, name, owner, project=None, |
865 | - revision_id=None, overwrite=False, allow_lossy=True): |
866 | + revision_id=None, overwrite=False, allow_lossy=True, |
867 | + tag_selector=None): |
868 | to_path = self._get_derived_git_path(base_path, owner, project) |
869 | to_transport = get_transport("git+ssh://git.launchpad.net/" + to_path) |
870 | try: |
871 | @@ -272,21 +273,23 @@ |
872 | if dir_to is None: |
873 | try: |
874 | br_to = local_branch.create_clone_on_transport( |
875 | - to_transport, revision_id=revision_id, name=name) |
876 | + to_transport, revision_id=revision_id, name=name, |
877 | + tag_selector=tag_selector) |
878 | except errors.NoRoundtrippingSupport: |
879 | br_to = local_branch.create_clone_on_transport( |
880 | to_transport, revision_id=revision_id, name=name, |
881 | - lossy=True) |
882 | + lossy=True, tag_selector=tag_selector) |
883 | else: |
884 | try: |
885 | dir_to = dir_to.push_branch( |
886 | - local_branch, revision_id, overwrite=overwrite, name=name) |
887 | + local_branch, revision_id, overwrite=overwrite, name=name, |
888 | + tag_selector=tag_selector) |
889 | except errors.NoRoundtrippingSupport: |
890 | if not allow_lossy: |
891 | raise |
892 | dir_to = dir_to.push_branch( |
893 | local_branch, revision_id, overwrite=overwrite, name=name, |
894 | - lossy=True) |
895 | + lossy=True, tag_selector=tag_selector) |
896 | br_to = dir_to.target_branch |
897 | return br_to, ( |
898 | "https://git.launchpad.net/%s/+ref/%s" % (to_path, name)) |
899 | @@ -312,7 +315,7 @@ |
900 | |
901 | def _publish_bzr(self, local_branch, base_branch, name, owner, |
902 | project=None, revision_id=None, overwrite=False, |
903 | - allow_lossy=True): |
904 | + allow_lossy=True, tag_selector=None): |
905 | to_path = self._get_derived_bzr_path(base_branch, name, owner, project) |
906 | to_transport = get_transport("lp:" + to_path) |
907 | try: |
908 | @@ -323,10 +326,11 @@ |
909 | |
910 | if dir_to is None: |
911 | br_to = local_branch.create_clone_on_transport( |
912 | - to_transport, revision_id=revision_id) |
913 | + to_transport, revision_id=revision_id, tag_selector=tag_selector) |
914 | else: |
915 | br_to = dir_to.push_branch( |
916 | - local_branch, revision_id, overwrite=overwrite).target_branch |
917 | + local_branch, revision_id, overwrite=overwrite, |
918 | + tag_selector=tag_selector).target_branch |
919 | return br_to, ("https://code.launchpad.net/" + to_path) |
920 | |
921 | def _split_url(self, url): |
922 | @@ -343,7 +347,7 @@ |
923 | |
924 | def publish_derived(self, local_branch, base_branch, name, project=None, |
925 | owner=None, revision_id=None, overwrite=False, |
926 | - allow_lossy=True): |
927 | + allow_lossy=True, tag_selector=None): |
928 | """Publish a branch to the site, derived from base_branch. |
929 | |
930 | :param base_branch: branch to derive the new branch from |
931 | @@ -362,12 +366,12 @@ |
932 | return self._publish_bzr( |
933 | local_branch, base_branch, name, project=project, owner=owner, |
934 | revision_id=revision_id, overwrite=overwrite, |
935 | - allow_lossy=allow_lossy) |
936 | + allow_lossy=allow_lossy, tag_selector=tag_selector) |
937 | elif base_vcs == 'git': |
938 | return self._publish_git( |
939 | local_branch, base_path, name, project=project, owner=owner, |
940 | revision_id=revision_id, overwrite=overwrite, |
941 | - allow_lossy=allow_lossy) |
942 | + allow_lossy=allow_lossy, tag_selector=tag_selector) |
943 | else: |
944 | raise AssertionError('not a valid Launchpad URL') |
945 | |
946 | |
947 | === modified file 'breezy/plugins/weave_fmt/bzrdir.py' |
948 | --- breezy/plugins/weave_fmt/bzrdir.py 2020-01-31 10:39:02 +0000 |
949 | +++ breezy/plugins/weave_fmt/bzrdir.py 2020-02-19 23:22:37 +0000 |
950 | @@ -747,7 +747,7 @@ |
951 | return self._format.__class__() |
952 | |
953 | def clone(self, url, revision_id=None, force_new_repo=False, |
954 | - preserve_stacking=False): |
955 | + preserve_stacking=False, tag_selector=None): |
956 | """See ControlDir.clone(). |
957 | |
958 | force_new_repo has no effect, since this family of formats always |
959 | @@ -759,7 +759,7 @@ |
960 | result = self._format._initialize_for_clone(url) |
961 | self.open_repository().clone(result, revision_id=revision_id) |
962 | from_branch = self.open_branch() |
963 | - from_branch.clone(result, revision_id=revision_id) |
964 | + from_branch.clone(result, revision_id=revision_id, tag_selector=tag_selector) |
965 | try: |
966 | tree = self.open_workingtree() |
967 | except errors.NotLocalUrl: |
968 | |
969 | === modified file 'breezy/propose.py' |
970 | --- breezy/propose.py 2020-01-28 23:33:16 +0000 |
971 | +++ breezy/propose.py 2020-02-19 23:22:37 +0000 |
972 | @@ -239,7 +239,7 @@ |
973 | |
974 | def publish_derived(self, new_branch, base_branch, name, project=None, |
975 | owner=None, revision_id=None, overwrite=False, |
976 | - allow_lossy=True): |
977 | + allow_lossy=True, tag_selector=None): |
978 | """Publish a branch to the site, derived from base_branch. |
979 | |
980 | :param base_branch: branch to derive the new branch from |
981 | |
982 | === modified file 'breezy/tag.py' |
983 | --- breezy/tag.py 2020-02-19 03:30:42 +0000 |
984 | +++ breezy/tag.py 2020-02-19 23:22:37 +0000 |
985 | @@ -35,20 +35,13 @@ |
986 | from .inter import InterObject |
987 | from .registry import Registry |
988 | from .sixish import text_type |
989 | -from .lazy_import import lazy_import |
990 | -lazy_import(globals(), """ |
991 | - |
992 | -from breezy import ( |
993 | +from . import ( |
994 | cleanup, |
995 | - ) |
996 | -""") |
997 | - |
998 | -from . import ( |
999 | errors, |
1000 | ) |
1001 | |
1002 | |
1003 | -def _reconcile_tags(source_dict, dest_dict, overwrite): |
1004 | +def _reconcile_tags(source_dict, dest_dict, overwrite, selector): |
1005 | """Do a two-way merge of two tag dictionaries. |
1006 | |
1007 | * only in source => source value |
1008 | @@ -64,6 +57,8 @@ |
1009 | updates = {} |
1010 | result = dict(dest_dict) # copy |
1011 | for name, target in source_dict.items(): |
1012 | + if selector and not selector(name): |
1013 | + continue |
1014 | if result.get(name) == target: |
1015 | pass |
1016 | elif name not in result or overwrite: |
1017 | @@ -93,7 +88,7 @@ |
1018 | rev[d[key]].add(key) |
1019 | return rev |
1020 | |
1021 | - def merge_to(self, to_tags, overwrite=False, ignore_master=False): |
1022 | + def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None): |
1023 | """Copy tags between repositories if necessary and possible. |
1024 | |
1025 | This method has common command-line behaviour about handling |
1026 | @@ -115,7 +110,9 @@ |
1027 | done. |
1028 | """ |
1029 | intertags = InterTags.get(self, to_tags) |
1030 | - return intertags.merge(overwrite=overwrite, ignore_master=ignore_master) |
1031 | + return intertags.merge( |
1032 | + overwrite=overwrite, ignore_master=ignore_master, |
1033 | + selector=selector) |
1034 | |
1035 | def set_tag(self, tag_name, revision): |
1036 | """Set a tag. |
1037 | @@ -174,7 +171,7 @@ |
1038 | lookup_tag = _not_supported |
1039 | delete_tag = _not_supported |
1040 | |
1041 | - def merge_to(self, to_tags, overwrite=False, ignore_master=False): |
1042 | + def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None): |
1043 | # we never have anything to copy |
1044 | return {}, [] |
1045 | |
1046 | @@ -199,7 +196,7 @@ |
1047 | # This is the default implementation |
1048 | return True |
1049 | |
1050 | - def merge(self, overwrite=False, ignore_master=False): |
1051 | + def merge(self, overwrite=False, ignore_master=False, selector=None): |
1052 | """Copy tags between repositories if necessary and possible. |
1053 | |
1054 | This method has common command-line behaviour about handling |
1055 | @@ -212,6 +209,9 @@ |
1056 | :param overwrite: Overwrite conflicting tags in the target branch |
1057 | :param ignore_master: Do not modify the tags in the target's master |
1058 | branch (if any). Default is false (so the master will be updated). |
1059 | + :param selector: Callback that determines whether a tag should be |
1060 | + copied. It should take a tag name and as argument and return a |
1061 | + boolean. |
1062 | |
1063 | :returns: Tuple with tag_updates and tag_conflicts. |
1064 | tag_updates is a dictionary with new tags, None is used for |
1065 | @@ -250,10 +250,11 @@ |
1066 | master = self.target.branch.get_master_branch() |
1067 | if master is not None: |
1068 | stack.enter_context(master.lock_write()) |
1069 | - updates, conflicts = self._merge_to(self.target, source_dict, overwrite) |
1070 | + updates, conflicts = self._merge_to( |
1071 | + self.target, source_dict, overwrite, selector=selector) |
1072 | if master is not None: |
1073 | - extra_updates, extra_conflicts = self._merge_to(master.tags, |
1074 | - source_dict, overwrite) |
1075 | + extra_updates, extra_conflicts = self._merge_to( |
1076 | + master.tags, source_dict, overwrite, selector=selector) |
1077 | updates.update(extra_updates) |
1078 | conflicts += extra_conflicts |
1079 | # We use set() to remove any duplicate conflicts from the master |
1080 | @@ -261,10 +262,10 @@ |
1081 | return updates, set(conflicts) |
1082 | |
1083 | @classmethod |
1084 | - def _merge_to(cls, to_tags, source_dict, overwrite): |
1085 | + def _merge_to(cls, to_tags, source_dict, overwrite, selector): |
1086 | dest_dict = to_tags.get_tag_dict() |
1087 | result, updates, conflicts = _reconcile_tags( |
1088 | - source_dict, dest_dict, overwrite) |
1089 | + source_dict, dest_dict, overwrite, selector) |
1090 | if result != dest_dict: |
1091 | to_tags._set_tag_dict(result) |
1092 | return updates, conflicts |
1093 | @@ -303,11 +304,11 @@ |
1094 | def _set_tag_dict(self, result): |
1095 | self._tag_dict = dict(result.items()) |
1096 | |
1097 | - def merge_to(self, to_tags, overwrite=False, ignore_master=False): |
1098 | + def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None): |
1099 | source_dict = self.get_tag_dict() |
1100 | dest_dict = to_tags.get_tag_dict() |
1101 | result, updates, conflicts = _reconcile_tags( |
1102 | - source_dict, dest_dict, overwrite) |
1103 | + source_dict, dest_dict, overwrite, selector) |
1104 | if result != dest_dict: |
1105 | to_tags._set_tag_dict(result) |
1106 | return updates, conflicts |
1107 | |
1108 | === modified file 'breezy/tests/per_branch/test_pull.py' |
1109 | --- breezy/tests/per_branch/test_pull.py 2018-11-17 20:50:40 +0000 |
1110 | +++ breezy/tests/per_branch/test_pull.py 2020-02-19 23:22:37 +0000 |
1111 | @@ -118,7 +118,7 @@ |
1112 | self.assertEqual(p1, result.old_revid) |
1113 | self.assertEqual(2, result.new_revno) |
1114 | self.assertEqual(m1, result.new_revid) |
1115 | - self.assertEqual([], result.tag_conflicts) |
1116 | + self.assertEqual([], list(result.tag_conflicts)) |
1117 | |
1118 | def test_pull_overwrite(self): |
1119 | tree_a = self.make_branch_and_tree('tree_a') |
1120 | |
1121 | === modified file 'breezy/tests/per_branch/test_tags.py' |
1122 | --- breezy/tests/per_branch/test_tags.py 2019-02-02 21:58:23 +0000 |
1123 | +++ breezy/tests/per_branch/test_tags.py 2020-02-19 23:22:37 +0000 |
1124 | @@ -142,6 +142,21 @@ |
1125 | self.assertEqual(updates, {}) |
1126 | self.assertEqual(b2.tags.lookup_tag('conflicts'), revid2) |
1127 | |
1128 | + def test_merge_tags_selector(self): |
1129 | + b1, [revid, revid1] = self.make_branch_with_revision_tuple('b1', 2) |
1130 | + w2 = b1.controldir.sprout('b2', revision_id=revid).open_workingtree() |
1131 | + revid2 = w2.commit('revision 2') |
1132 | + b2 = w2.branch |
1133 | + # if there are tags in the source and not the destination, then they |
1134 | + # just go across |
1135 | + b1.tags.set_tag('tag1', revid) |
1136 | + b1.tags.set_tag('tag2', revid2) |
1137 | + updates, conflicts = b1.tags.merge_to(b2.tags, selector=lambda x: x == 'tag1') |
1138 | + self.assertEqual({'tag1': revid}, updates) |
1139 | + self.assertEqual(set(), set(conflicts)) |
1140 | + self.assertEqual(b2.tags.lookup_tag('tag1'), revid) |
1141 | + self.assertRaises(errors.NoSuchTag, b2.tags.lookup_tag, 'tag2') |
1142 | + |
1143 | def test_unicode_tag(self): |
1144 | tag_name = u'\u3070' |
1145 | b1, [revid] = self.make_branch_with_revision_tuple('b', 1) |
1146 | |
1147 | === modified file 'breezy/tests/per_controldir/test_push.py' |
1148 | --- breezy/tests/per_controldir/test_push.py 2019-02-15 03:42:06 +0000 |
1149 | +++ breezy/tests/per_controldir/test_push.py 2020-02-19 23:22:37 +0000 |
1150 | @@ -99,3 +99,14 @@ |
1151 | self.assertEqual(2, result.branch_push_result.new_revno) |
1152 | self.assertEqual(tree.branch.base, result.source_branch.base) |
1153 | self.assertEqual(dir.open_branch().base, result.target_branch.base) |
1154 | + |
1155 | + def test_push_tag_selector(self): |
1156 | + tree, rev1 = self.create_simple_tree() |
1157 | + try: |
1158 | + tree.branch.tags.set_tag('tag1', rev1) |
1159 | + except TagsNotSupported: |
1160 | + raise TestNotApplicable('tags not supported') |
1161 | + tree.branch.tags.set_tag('tag2', rev1) |
1162 | + dir = self.make_repository('dir').controldir |
1163 | + dir.push_branch(tree.branch, tag_selector=lambda x: x == 'tag1') |
1164 | + self.assertEqual({'tag1': rev1}, dir.open_branch().tags.get_tag_dict()) |
1165 | |
1166 | === modified file 'breezy/tests/per_interbranch/test_pull.py' |
1167 | --- breezy/tests/per_interbranch/test_pull.py 2018-11-11 04:08:32 +0000 |
1168 | +++ breezy/tests/per_interbranch/test_pull.py 2020-02-19 23:22:37 +0000 |
1169 | @@ -144,7 +144,7 @@ |
1170 | self.assertEqual(p1, result.old_revid) |
1171 | self.assertEqual(2, result.new_revno) |
1172 | self.assertEqual(m1, result.new_revid) |
1173 | - self.assertEqual([], result.tag_conflicts) |
1174 | + self.assertEqual([], list(result.tag_conflicts)) |
1175 | |
1176 | def test_pull_overwrite(self): |
1177 | tree_a = self.make_from_branch_and_tree('tree_a') |
1178 | @@ -180,6 +180,26 @@ |
1179 | self.assertEqual(tree_b.branch.last_revision(), |
1180 | tree_a.branch.last_revision()) |
1181 | |
1182 | + def test_pull_tag_selector(self): |
1183 | + if not self.branch_format_from.supports_tags(): |
1184 | + raise TestNotApplicable('from format does not support tags') |
1185 | + if not self.branch_format_to.supports_tags(): |
1186 | + raise TestNotApplicable('to format does not support tags') |
1187 | + tree_a = self.make_from_branch_and_tree('tree_a') |
1188 | + revid1 = tree_a.commit('message 1') |
1189 | + try: |
1190 | + tree_b = self.sprout_to( |
1191 | + tree_a.controldir, 'tree_b').open_workingtree() |
1192 | + except errors.NoRoundtrippingSupport: |
1193 | + raise TestNotApplicable( |
1194 | + 'lossless push between %r and %r not supported' % |
1195 | + (self.branch_format_from, self.branch_format_to)) |
1196 | + tree_b.branch.tags.set_tag('tag1', revid1) |
1197 | + tree_b.branch.tags.set_tag('tag2', revid1) |
1198 | + tree_b.branch.get_config_stack().set('branch.fetch_tags', True) |
1199 | + tree_a.pull(tree_b.branch, tag_selector=lambda x: x == 'tag1') |
1200 | + self.assertEqual({'tag1': revid1}, tree_a.branch.tags.get_tag_dict()) |
1201 | + |
1202 | |
1203 | class TestPullHook(TestCaseWithInterBranch): |
1204 | |
1205 | |
1206 | === modified file 'breezy/tests/per_interbranch/test_push.py' |
1207 | --- breezy/tests/per_interbranch/test_push.py 2018-11-16 11:37:47 +0000 |
1208 | +++ breezy/tests/per_interbranch/test_push.py 2020-02-19 23:22:37 +0000 |
1209 | @@ -375,6 +375,26 @@ |
1210 | self.overrideAttr(SmartServerRepositoryGetParentMap, |
1211 | 'no_extra_results', True) |
1212 | |
1213 | + def test_push_tag_selector(self): |
1214 | + if not self.branch_format_from.supports_tags(): |
1215 | + raise tests.TestNotApplicable('from format does not support tags') |
1216 | + if not self.branch_format_to.supports_tags(): |
1217 | + raise tests.TestNotApplicable('to format does not support tags') |
1218 | + tree_a = self.make_from_branch_and_tree('tree_a') |
1219 | + revid1 = tree_a.commit('message 1') |
1220 | + try: |
1221 | + tree_b = self.sprout_to( |
1222 | + tree_a.controldir, 'tree_b').open_workingtree() |
1223 | + except errors.NoRoundtrippingSupport: |
1224 | + raise tests.TestNotApplicable( |
1225 | + 'lossless push between %r and %r not supported' % |
1226 | + (self.branch_format_from, self.branch_format_to)) |
1227 | + tree_b.branch.tags.set_tag('tag1', revid1) |
1228 | + tree_b.branch.tags.set_tag('tag2', revid1) |
1229 | + tree_b.branch.get_config_stack().set('branch.fetch_tags', True) |
1230 | + tree_b.branch.push(tree_a.branch, tag_selector=lambda x: x == 'tag1') |
1231 | + self.assertEqual({'tag1': revid1}, tree_a.branch.tags.get_tag_dict()) |
1232 | + |
1233 | |
1234 | class TestPushHook(TestCaseWithInterBranch): |
1235 | |
1236 | |
1237 | === modified file 'breezy/tests/test_foreign.py' |
1238 | --- breezy/tests/test_foreign.py 2018-11-25 20:44:56 +0000 |
1239 | +++ breezy/tests/test_foreign.py 2020-02-19 23:22:37 +0000 |
1240 | @@ -171,7 +171,7 @@ |
1241 | def is_compatible(source, target): |
1242 | return isinstance(target, DummyForeignVcsBranch) |
1243 | |
1244 | - def push(self, overwrite=False, stop_revision=None, lossy=False): |
1245 | + def push(self, overwrite=False, stop_revision=None, lossy=False, tag_selector=None): |
1246 | if not lossy: |
1247 | raise errors.NoRoundtrippingSupport(self.source, self.target) |
1248 | result = branch.BranchPushResult() |
1249 | |
1250 | === modified file 'breezy/tests/test_tag.py' |
1251 | --- breezy/tests/test_tag.py 2020-02-18 01:32:25 +0000 |
1252 | +++ breezy/tests/test_tag.py 2020-02-19 23:22:37 +0000 |
1253 | @@ -122,6 +122,17 @@ |
1254 | self.assertEqual({u'tag-2': b'z'}, updates) |
1255 | self.assertEqual(b'z', b.tags.lookup_tag('tag-2')) |
1256 | |
1257 | + def test_merge_to_with_selector(self): |
1258 | + a = self.make_branch_supporting_tags('a') |
1259 | + b = self.make_branch_supporting_tags('b') |
1260 | + # simple merge |
1261 | + a.tags.set_tag('tag-1', b'x') |
1262 | + a.tags.set_tag('tag-2', b'y') |
1263 | + updates, conflicts = a.tags.merge_to(b.tags, selector=lambda x: x == 'tag-1') |
1264 | + self.assertEqual(list(conflicts), []) |
1265 | + self.assertEqual({u'tag-1': b'x'}, updates) |
1266 | + self.assertRaises(errors.NoSuchTag, b.tags.lookup_tag, 'tag-2') |
1267 | + |
1268 | |
1269 | class TestTagsInCheckouts(TestCaseWithTransport): |
1270 | """Tests for how tags are synchronised between the master and child branch |
1271 | |
1272 | === modified file 'breezy/workingtree.py' |
1273 | --- breezy/workingtree.py 2020-01-30 17:54:42 +0000 |
1274 | +++ breezy/workingtree.py 2020-02-19 23:22:37 +0000 |
1275 | @@ -821,13 +821,13 @@ |
1276 | |
1277 | def pull(self, source, overwrite=False, stop_revision=None, |
1278 | change_reporter=None, possible_transports=None, local=False, |
1279 | - show_base=False): |
1280 | + show_base=False, tag_selector=None): |
1281 | with self.lock_write(), source.lock_read(): |
1282 | old_revision_info = self.branch.last_revision_info() |
1283 | basis_tree = self.basis_tree() |
1284 | count = self.branch.pull(source, overwrite, stop_revision, |
1285 | possible_transports=possible_transports, |
1286 | - local=local) |
1287 | + local=local, tag_selector=tag_selector) |
1288 | new_revision_info = self.branch.last_revision_info() |
1289 | if new_revision_info != old_revision_info: |
1290 | repository = self.branch.repository |
Running landing tests failed /ci.breezy- vcs.org/ job/brz- 3.1/job/ brz-3.1- land/9/
https:/