845
845
raise errors.NoSuchRevision(self, revno)
846
846
return history[revno - 1]
848
849
def pull(self, source, overwrite=False, stop_revision=None,
849
possible_transports=None, _override_hook_target=None):
850
possible_transports=None, *args, **kwargs):
850
851
"""Mirror source into this branch.
852
853
This branch is considered to be 'local', having low latency.
854
855
:returns: PullResult instance
856
raise NotImplementedError(self.pull)
857
return InterBranch.get(source, self).pull(overwrite=overwrite,
858
stop_revision=stop_revision,
859
possible_transports=possible_transports, *args, **kwargs)
858
def push(self, target, overwrite=False, stop_revision=None):
861
def push(self, target, overwrite=False, stop_revision=None, *args,
859
863
"""Mirror this branch into target.
861
865
This branch is considered to be 'local', having low latency.
863
raise NotImplementedError(self.push)
867
return InterBranch.get(self, target).push(overwrite, stop_revision,
865
870
def basis_tree(self):
866
871
"""Return `Tree` object for last revision."""
2175
2180
"""See Branch.basis_tree."""
2176
2181
return self.repository.revision_tree(self.last_revision())
2179
def pull(self, source, overwrite=False, stop_revision=None,
2180
_hook_master=None, run_hooks=True, possible_transports=None,
2181
_override_hook_target=None):
2184
:param _hook_master: Private parameter - set the branch to
2185
be supplied as the master to pull hooks.
2186
:param run_hooks: Private parameter - if false, this branch
2187
is being called because it's the master of the primary branch,
2188
so it should not run its hooks.
2189
:param _override_hook_target: Private parameter - set the branch to be
2190
supplied as the target_branch to pull hooks.
2192
result = PullResult()
2193
result.source_branch = source
2194
if _override_hook_target is None:
2195
result.target_branch = self
2197
result.target_branch = _override_hook_target
2200
# We assume that during 'pull' the local repository is closer than
2202
source.update_references(self)
2203
graph = self.repository.get_graph(source.repository)
2204
result.old_revno, result.old_revid = self.last_revision_info()
2205
self.update_revisions(source, stop_revision, overwrite=overwrite,
2207
result.tag_conflicts = source.tags.merge_to(self.tags, overwrite)
2208
result.new_revno, result.new_revid = self.last_revision_info()
2210
result.master_branch = _hook_master
2211
result.local_branch = result.target_branch
2213
result.master_branch = result.target_branch
2214
result.local_branch = None
2216
for hook in Branch.hooks['post_pull']:
2222
2183
def _get_parent_location(self):
2223
2184
_locs = ['parent', 'pull', 'x-pull']
2224
2185
for l in _locs:
2232
def push(self, target, overwrite=False, stop_revision=None,
2233
_override_hook_source_branch=None):
2236
This is the basic concrete implementation of push()
2238
:param _override_hook_source_branch: If specified, run
2239
the hooks passing this Branch as the source, rather than self.
2240
This is for use of RemoteBranch, where push is delegated to the
2241
underlying vfs-based Branch.
2243
# TODO: Public option to disable running hooks - should be trivial but
2245
return _run_with_write_locked_target(
2246
target, self._push_with_bound_branches, target, overwrite,
2248
_override_hook_source_branch=_override_hook_source_branch)
2250
def _push_with_bound_branches(self, target, overwrite,
2252
_override_hook_source_branch=None):
2253
"""Push from self into target, and into target's master if any.
2255
This is on the base BzrBranch class even though it doesn't support
2256
bound branches because the *target* might be bound.
2259
if _override_hook_source_branch:
2260
result.source_branch = _override_hook_source_branch
2261
for hook in Branch.hooks['post_push']:
2264
bound_location = target.get_bound_location()
2265
if bound_location and target.base != bound_location:
2266
# there is a master branch.
2268
# XXX: Why the second check? Is it even supported for a branch to
2269
# be bound to itself? -- mbp 20070507
2270
master_branch = target.get_master_branch()
2271
master_branch.lock_write()
2273
# push into the master from this branch.
2274
self._basic_push(master_branch, overwrite, stop_revision)
2275
# and push into the target branch from this. Note that we push from
2276
# this branch again, because its considered the highest bandwidth
2278
result = self._basic_push(target, overwrite, stop_revision)
2279
result.master_branch = master_branch
2280
result.local_branch = target
2284
master_branch.unlock()
2287
result = self._basic_push(target, overwrite, stop_revision)
2288
# TODO: Why set master_branch and local_branch if there's no
2289
# binding? Maybe cleaner to just leave them unset? -- mbp
2291
result.master_branch = target
2292
result.local_branch = None
2296
2192
def _basic_push(self, target, overwrite, stop_revision):
2297
2193
"""Basic implementation of push without bound branches or hooks.
2299
Must be called with self read locked and target write locked.
2195
Must be called with source read locked and target write locked.
2301
2197
result = BranchPushResult()
2302
2198
result.source_branch = self
2337
2234
It has support for a master_branch which is the data for bound branches.
2341
def pull(self, source, overwrite=False, stop_revision=None,
2342
run_hooks=True, possible_transports=None,
2343
_override_hook_target=None):
2344
"""Pull from source into self, updating my master if any.
2346
:param run_hooks: Private parameter - if false, this branch
2347
is being called because it's the master of the primary branch,
2348
so it should not run its hooks.
2350
bound_location = self.get_bound_location()
2351
master_branch = None
2352
if bound_location and source.base != bound_location:
2353
# not pulling from master, so we need to update master.
2354
master_branch = self.get_master_branch(possible_transports)
2355
master_branch.lock_write()
2358
# pull from source into master.
2359
master_branch.pull(source, overwrite, stop_revision,
2361
return super(BzrBranch5, self).pull(source, overwrite,
2362
stop_revision, _hook_master=master_branch,
2363
run_hooks=run_hooks,
2364
_override_hook_target=_override_hook_target)
2367
master_branch.unlock()
2369
2237
def get_bound_location(self):
2371
2239
return self._transport.get_bytes('bound')[:-1]
3069
2955
self.source.unlock()
2957
def pull(self, overwrite=False, stop_revision=None,
2958
possible_transports=None, _hook_master=None, run_hooks=True,
2959
_override_hook_target=None, local=False):
2962
:param _hook_master: Private parameter - set the branch to
2963
be supplied as the master to pull hooks.
2964
:param run_hooks: Private parameter - if false, this branch
2965
is being called because it's the master of the primary branch,
2966
so it should not run its hooks.
2967
:param _override_hook_target: Private parameter - set the branch to be
2968
supplied as the target_branch to pull hooks.
2969
:param local: Only update the local branch, and not the bound branch.
2971
# This type of branch can't be bound.
2973
raise errors.LocalRequiresBoundBranch()
2974
result = PullResult()
2975
result.source_branch = self.source
2976
if _override_hook_target is None:
2977
result.target_branch = self.target
2979
result.target_branch = _override_hook_target
2980
self.source.lock_read()
2982
# We assume that during 'pull' the target repository is closer than
2984
self.source.update_references(self.target)
2985
graph = self.target.repository.get_graph(self.source.repository)
2986
# TODO: Branch formats should have a flag that indicates
2987
# that revno's are expensive, and pull() should honor that flag.
2989
result.old_revno, result.old_revid = \
2990
self.target.last_revision_info()
2991
self.target.update_revisions(self.source, stop_revision,
2992
overwrite=overwrite, graph=graph)
2993
# TODO: The old revid should be specified when merging tags,
2994
# so a tags implementation that versions tags can only
2995
# pull in the most recent changes. -- JRV20090506
2996
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
2998
result.new_revno, result.new_revid = self.target.last_revision_info()
3000
result.master_branch = _hook_master
3001
result.local_branch = result.target_branch
3003
result.master_branch = result.target_branch
3004
result.local_branch = None
3006
for hook in Branch.hooks['post_pull']:
3009
self.source.unlock()
3012
def push(self, overwrite=False, stop_revision=None,
3013
_override_hook_source_branch=None):
3014
"""See InterBranch.push.
3016
This is the basic concrete implementation of push()
3018
:param _override_hook_source_branch: If specified, run
3019
the hooks passing this Branch as the source, rather than self.
3020
This is for use of RemoteBranch, where push is delegated to the
3021
underlying vfs-based Branch.
3023
# TODO: Public option to disable running hooks - should be trivial but
3025
self.source.lock_read()
3027
return _run_with_write_locked_target(
3028
self.target, self._push_with_bound_branches, overwrite,
3030
_override_hook_source_branch=_override_hook_source_branch)
3032
self.source.unlock()
3035
def _push_with_bound_branches(self, overwrite, stop_revision,
3036
_override_hook_source_branch=None):
3037
"""Push from source into target, and into target's master if any.
3040
if _override_hook_source_branch:
3041
result.source_branch = _override_hook_source_branch
3042
for hook in Branch.hooks['post_push']:
3045
bound_location = self.target.get_bound_location()
3046
if bound_location and self.target.base != bound_location:
3047
# there is a master branch.
3049
# XXX: Why the second check? Is it even supported for a branch to
3050
# be bound to itself? -- mbp 20070507
3051
master_branch = self.target.get_master_branch()
3052
master_branch.lock_write()
3054
# push into the master from the source branch.
3055
self.source._basic_push(master_branch, overwrite, stop_revision)
3056
# and push into the target branch from the source. Note that we
3057
# push from the source branch again, because its considered the
3058
# highest bandwidth repository.
3059
result = self.source._basic_push(self.target, overwrite,
3061
result.master_branch = master_branch
3062
result.local_branch = self.target
3066
master_branch.unlock()
3069
result = self.source._basic_push(self.target, overwrite,
3071
# TODO: Why set master_branch and local_branch if there's no
3072
# binding? Maybe cleaner to just leave them unset? -- mbp
3074
result.master_branch = self.target
3075
result.local_branch = None
3072
3080
def is_compatible(self, source, target):
3073
3081
# GenericBranch uses the public API, so always compatible
3085
class InterToBranch5(GenericInterBranch):
3088
def _get_branch_formats_to_test():
3089
return BranchFormat._default_format, BzrBranchFormat5()
3091
def pull(self, overwrite=False, stop_revision=None,
3092
possible_transports=None, run_hooks=True,
3093
_override_hook_target=None, local=False):
3094
"""Pull from source into self, updating my master if any.
3096
:param run_hooks: Private parameter - if false, this branch
3097
is being called because it's the master of the primary branch,
3098
so it should not run its hooks.
3100
bound_location = self.target.get_bound_location()
3101
if local and not bound_location:
3102
raise errors.LocalRequiresBoundBranch()
3103
master_branch = None
3104
if not local and bound_location and self.source.base != bound_location:
3105
# not pulling from master, so we need to update master.
3106
master_branch = self.target.get_master_branch(possible_transports)
3107
master_branch.lock_write()
3110
# pull from source into master.
3111
master_branch.pull(self.source, overwrite, stop_revision,
3113
return super(InterToBranch5, self).pull(overwrite,
3114
stop_revision, _hook_master=master_branch,
3115
run_hooks=run_hooks,
3116
_override_hook_target=_override_hook_target)
3119
master_branch.unlock()
3077
3122
InterBranch.register_optimiser(GenericInterBranch)
3123
InterBranch.register_optimiser(InterToBranch5)