3235
3225
class GenericInterBranch(InterBranch):
3236
"""InterBranch implementation that uses public Branch functions.
3226
"""InterBranch implementation that uses public Branch functions."""
3229
def is_compatible(klass, source, target):
3230
# GenericBranch uses the public API, so always compatible
3240
3234
def _get_branch_formats_to_test():
3241
3235
return BranchFormat._default_format, BranchFormat._default_format
3238
def unwrap_format(klass, format):
3239
if isinstance(format, remote.RemoteBranchFormat):
3240
format._ensure_real()
3241
return format._custom_format
3245
def copy_content_into(self, revision_id=None):
3246
"""Copy the content of source into target
3248
revision_id: if not None, the revision history in the new branch will
3249
be truncated to end with revision_id.
3251
self.source.update_references(self.target)
3252
self.source._synchronize_history(self.target, revision_id)
3254
parent = self.source.get_parent()
3255
except errors.InaccessibleParent, e:
3256
mutter('parent was not accessible to copy: %s', e)
3259
self.target.set_parent(parent)
3260
if self.source._push_should_merge_tags():
3261
self.source.tags.merge_to(self.target.tags)
3243
3264
def update_revisions(self, stop_revision=None, overwrite=False,
3245
3266
"""See InterBranch.update_revisions()."""
3246
self.source.lock_read()
3248
other_revno, other_last_revision = self.source.last_revision_info()
3249
stop_revno = None # unknown
3250
if stop_revision is None:
3251
stop_revision = other_last_revision
3252
if _mod_revision.is_null(stop_revision):
3253
# if there are no commits, we're done.
3255
stop_revno = other_revno
3267
other_revno, other_last_revision = self.source.last_revision_info()
3268
stop_revno = None # unknown
3269
if stop_revision is None:
3270
stop_revision = other_last_revision
3271
if _mod_revision.is_null(stop_revision):
3272
# if there are no commits, we're done.
3274
stop_revno = other_revno
3257
# what's the current last revision, before we fetch [and change it
3259
last_rev = _mod_revision.ensure_null(self.target.last_revision())
3260
# we fetch here so that we don't process data twice in the common
3261
# case of having something to pull, and so that the check for
3262
# already merged can operate on the just fetched graph, which will
3263
# be cached in memory.
3264
self.target.fetch(self.source, stop_revision)
3265
# Check to see if one is an ancestor of the other
3268
graph = self.target.repository.get_graph()
3269
if self.target._check_if_descendant_or_diverged(
3270
stop_revision, last_rev, graph, self.source):
3271
# stop_revision is a descendant of last_rev, but we aren't
3272
# overwriting, so we're done.
3274
if stop_revno is None:
3276
graph = self.target.repository.get_graph()
3277
this_revno, this_last_revision = \
3278
self.target.last_revision_info()
3279
stop_revno = graph.find_distance_to_null(stop_revision,
3280
[(other_last_revision, other_revno),
3281
(this_last_revision, this_revno)])
3282
self.target.set_last_revision_info(stop_revno, stop_revision)
3284
self.source.unlock()
3276
# what's the current last revision, before we fetch [and change it
3278
last_rev = _mod_revision.ensure_null(self.target.last_revision())
3279
# we fetch here so that we don't process data twice in the common
3280
# case of having something to pull, and so that the check for
3281
# already merged can operate on the just fetched graph, which will
3282
# be cached in memory.
3283
self.target.fetch(self.source, stop_revision)
3284
# Check to see if one is an ancestor of the other
3287
graph = self.target.repository.get_graph()
3288
if self.target._check_if_descendant_or_diverged(
3289
stop_revision, last_rev, graph, self.source):
3290
# stop_revision is a descendant of last_rev, but we aren't
3291
# overwriting, so we're done.
3293
if stop_revno is None:
3295
graph = self.target.repository.get_graph()
3296
this_revno, this_last_revision = \
3297
self.target.last_revision_info()
3298
stop_revno = graph.find_distance_to_null(stop_revision,
3299
[(other_last_revision, other_revno),
3300
(this_last_revision, this_revno)])
3301
self.target.set_last_revision_info(stop_revno, stop_revision)
3286
3303
def pull(self, overwrite=False, stop_revision=None,
3287
possible_transports=None, _hook_master=None, run_hooks=True,
3304
possible_transports=None, run_hooks=True,
3288
3305
_override_hook_target=None, local=False):
3306
"""Pull from source into self, updating my master if any.
3291
:param _hook_master: Private parameter - set the branch to
3292
be supplied as the master to pull hooks.
3293
3308
:param run_hooks: Private parameter - if false, this branch
3294
3309
is being called because it's the master of the primary branch,
3295
3310
so it should not run its hooks.
3296
:param _override_hook_target: Private parameter - set the branch to be
3297
supplied as the target_branch to pull hooks.
3298
:param local: Only update the local branch, and not the bound branch.
3300
# This type of branch can't be bound.
3312
bound_location = self.target.get_bound_location()
3313
if local and not bound_location:
3302
3314
raise errors.LocalRequiresBoundBranch()
3303
result = PullResult()
3304
result.source_branch = self.source
3305
if _override_hook_target is None:
3306
result.target_branch = self.target
3308
result.target_branch = _override_hook_target
3309
self.source.lock_read()
3315
master_branch = None
3316
if not local and bound_location and self.source.user_url != bound_location:
3317
# not pulling from master, so we need to update master.
3318
master_branch = self.target.get_master_branch(possible_transports)
3319
master_branch.lock_write()
3311
# We assume that during 'pull' the target repository is closer than
3313
self.source.update_references(self.target)
3314
graph = self.target.repository.get_graph(self.source.repository)
3315
# TODO: Branch formats should have a flag that indicates
3316
# that revno's are expensive, and pull() should honor that flag.
3318
result.old_revno, result.old_revid = \
3319
self.target.last_revision_info()
3320
self.target.update_revisions(self.source, stop_revision,
3321
overwrite=overwrite, graph=graph)
3322
# TODO: The old revid should be specified when merging tags,
3323
# so a tags implementation that versions tags can only
3324
# pull in the most recent changes. -- JRV20090506
3325
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3327
result.new_revno, result.new_revid = self.target.last_revision_info()
3329
result.master_branch = _hook_master
3330
result.local_branch = result.target_branch
3332
result.master_branch = result.target_branch
3333
result.local_branch = None
3335
for hook in Branch.hooks['post_pull']:
3322
# pull from source into master.
3323
master_branch.pull(self.source, overwrite, stop_revision,
3325
return self._pull(overwrite,
3326
stop_revision, _hook_master=master_branch,
3327
run_hooks=run_hooks,
3328
_override_hook_target=_override_hook_target)
3338
self.source.unlock()
3331
master_branch.unlock()
3341
3333
def push(self, overwrite=False, stop_revision=None,
3342
3334
_override_hook_source_branch=None):
3408
def is_compatible(self, source, target):
3409
# GenericBranch uses the public API, so always compatible
3413
class InterToBranch5(GenericInterBranch):
3416
def _get_branch_formats_to_test():
3417
return BranchFormat._default_format, BzrBranchFormat5()
3419
def pull(self, overwrite=False, stop_revision=None,
3420
possible_transports=None, run_hooks=True,
3399
def _pull(self, overwrite=False, stop_revision=None,
3400
possible_transports=None, _hook_master=None, run_hooks=True,
3421
3401
_override_hook_target=None, local=False):
3422
"""Pull from source into self, updating my master if any.
3404
This function is the core worker, used by GenericInterBranch.pull to
3405
avoid duplication when pulling source->master and source->local.
3407
:param _hook_master: Private parameter - set the branch to
3408
be supplied as the master to pull hooks.
3424
3409
:param run_hooks: Private parameter - if false, this branch
3425
3410
is being called because it's the master of the primary branch,
3426
3411
so it should not run its hooks.
3412
:param _override_hook_target: Private parameter - set the branch to be
3413
supplied as the target_branch to pull hooks.
3414
:param local: Only update the local branch, and not the bound branch.
3428
bound_location = self.target.get_bound_location()
3429
if local and not bound_location:
3416
# This type of branch can't be bound.
3430
3418
raise errors.LocalRequiresBoundBranch()
3431
master_branch = None
3432
if not local and bound_location and self.source.user_url != bound_location:
3433
# not pulling from master, so we need to update master.
3434
master_branch = self.target.get_master_branch(possible_transports)
3435
master_branch.lock_write()
3419
result = PullResult()
3420
result.source_branch = self.source
3421
if _override_hook_target is None:
3422
result.target_branch = self.target
3424
result.target_branch = _override_hook_target
3425
self.source.lock_read()
3438
# pull from source into master.
3439
master_branch.pull(self.source, overwrite, stop_revision,
3441
return super(InterToBranch5, self).pull(overwrite,
3442
stop_revision, _hook_master=master_branch,
3443
run_hooks=run_hooks,
3444
_override_hook_target=_override_hook_target)
3427
# We assume that during 'pull' the target repository is closer than
3429
self.source.update_references(self.target)
3430
graph = self.target.repository.get_graph(self.source.repository)
3431
# TODO: Branch formats should have a flag that indicates
3432
# that revno's are expensive, and pull() should honor that flag.
3434
result.old_revno, result.old_revid = \
3435
self.target.last_revision_info()
3436
self.target.update_revisions(self.source, stop_revision,
3437
overwrite=overwrite, graph=graph)
3438
# TODO: The old revid should be specified when merging tags,
3439
# so a tags implementation that versions tags can only
3440
# pull in the most recent changes. -- JRV20090506
3441
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
3443
result.new_revno, result.new_revid = self.target.last_revision_info()
3445
result.master_branch = _hook_master
3446
result.local_branch = result.target_branch
3448
result.master_branch = result.target_branch
3449
result.local_branch = None
3451
for hook in Branch.hooks['post_pull']:
3447
master_branch.unlock()
3454
self.source.unlock()
3450
3458
InterBranch.register_optimiser(GenericInterBranch)
3451
InterBranch.register_optimiser(InterToBranch5)