57
59
lookup_tag = _not_supported
58
60
delete_tag = _not_supported
60
def merge_to(self, to_tags, overwrite=False):
62
def merge_to(self, to_tags, overwrite=False, ignore_master=False):
61
63
# we never have anything to copy
177
179
raise ValueError("failed to deserialize tag dictionary %r: %s"
178
180
% (tag_content, e))
180
def merge_to(self, to_tags, overwrite=False):
182
def merge_to(self, to_tags, overwrite=False, ignore_master=False):
181
183
"""Copy tags between repositories if necessary and possible.
183
185
This method has common command-line behaviour about handling
189
191
:param to_tags: Branch to receive these tags
190
192
:param overwrite: Overwrite conflicting tags in the target branch
193
:param ignore_master: Do not modify the tags in the target's master
194
branch (if any). Default is false (so the master will be updated).
192
:returns: A list of tags that conflicted, each of which is
197
:returns: A set of tags that conflicted, each of which is
193
198
(tagname, source_target, dest_target), or None if no copying was
201
operation = cleanup.OperationWithCleanups(self._merge_to_operation)
202
return operation.run(to_tags, overwrite, ignore_master)
204
def _merge_to_operation(self, operation, to_tags, overwrite, ignore_master):
205
add_cleanup = operation.add_cleanup
196
206
if self.branch == to_tags.branch:
198
208
if not self.branch.supports_tags():
203
213
# no tags in the source, and we don't want to clobber anything
204
214
# that's in the destination
206
to_tags.branch.lock_write()
208
dest_dict = to_tags.get_tag_dict()
209
result, conflicts = self._reconcile_tags(source_dict, dest_dict,
211
if result != dest_dict:
212
to_tags._set_tag_dict(result)
214
to_tags.branch.unlock()
216
# We merge_to both master and child individually.
218
# It's possible for master and child to have differing sets of
219
# tags, in which case it's possible to have different sets of
220
# conflicts. We report the union of both conflict sets. In
221
# that case it's likely the child and master have accepted
222
# different tags from the source, which may be a surprising result, but
223
# the best we can do in the circumstances.
225
# Ideally we'd improve this API to report the different conflicts
226
# more clearly to the caller, but we don't want to break plugins
227
# such as bzr-builddeb that use this API.
228
add_cleanup(to_tags.branch.lock_write().unlock)
232
master = to_tags.branch.get_master_branch()
233
if master is not None:
234
add_cleanup(master.lock_write().unlock)
235
conflicts = self._merge_to(to_tags, source_dict, overwrite)
236
if master is not None:
237
conflicts += self._merge_to(master.tags, source_dict,
239
# We use set() to remove any duplicate conflicts from the master
241
return set(conflicts)
243
def _merge_to(self, to_tags, source_dict, overwrite):
244
dest_dict = to_tags.get_tag_dict()
245
result, conflicts = self._reconcile_tags(source_dict, dest_dict,
247
if result != dest_dict:
248
to_tags._set_tag_dict(result)
217
251
def rename_revisions(self, rename_map):
249
283
return result, conflicts
252
def _merge_tags_if_possible(from_branch, to_branch):
253
from_branch.tags.merge_to(to_branch.tags)
286
def _merge_tags_if_possible(from_branch, to_branch, ignore_master=False):
287
# Try hard to support merge_to implementations that don't expect
288
# 'ignore_master' (new in bzr 2.3). First, if the flag isn't set then we
289
# can safely avoid passing ignore_master at all.
290
if not ignore_master:
291
from_branch.tags.merge_to(to_branch.tags)
293
# If the flag is set, try to pass it, but be ready to catch TypeError.
295
from_branch.tags.merge_to(to_branch.tags, ignore_master=ignore_master)
297
# Probably this implementation of 'merge_to' is from a plugin that
298
# doesn't expect the 'ignore_master' keyword argument (e.g. bzr-svn
299
# 1.0.4). There's a small risk that the TypeError is actually caused
300
# by a completely different problem (which is why we don't catch it for
301
# the ignore_master=False case), but even then there's probably no harm
302
# in calling a second time.
303
symbol_versioning.warn(
304
symbol_versioning.deprecated_in((2,3)) % (
305
"Tags.merge_to (of %r) that doesn't accept ignore_master kwarg"
306
% (from_branch.tags,),),
308
from_branch.tags.merge_to(to_branch.tags)