~bzr-pqm/bzr/2.0

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Johan Walles
  • Date: 2009-05-06 05:36:28 UTC
  • mfrom: (4332 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4343.
  • Revision ID: johan.walles@gmail.com-20090506053628-tbf1wz4a0m9t684g
MergeĀ fromĀ upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
855
855
        """
856
856
        raise NotImplementedError(self.pull)
857
857
 
858
 
    def push(self, target, overwrite=False, stop_revision=None):
 
858
    def push(self, target, overwrite=False, stop_revision=None, *args,
 
859
        **kwargs):
859
860
        """Mirror this branch into target.
860
861
 
861
862
        This branch is considered to be 'local', having low latency.
862
863
        """
863
 
        raise NotImplementedError(self.push)
 
864
        return InterBranch.get(self, target).push(overwrite, stop_revision,
 
865
            *args, **kwargs)
864
866
 
865
867
    def basis_tree(self):
866
868
        """Return `Tree` object for last revision."""
2228
2230
                pass
2229
2231
        return None
2230
2232
 
2231
 
    @needs_read_lock
2232
 
    def push(self, target, overwrite=False, stop_revision=None,
2233
 
             _override_hook_source_branch=None):
2234
 
        """See Branch.push.
2235
 
 
2236
 
        This is the basic concrete implementation of push()
2237
 
 
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.
2242
 
        """
2243
 
        # TODO: Public option to disable running hooks - should be trivial but
2244
 
        # needs tests.
2245
 
        return _run_with_write_locked_target(
2246
 
            target, self._push_with_bound_branches, target, overwrite,
2247
 
            stop_revision,
2248
 
            _override_hook_source_branch=_override_hook_source_branch)
2249
 
 
2250
 
    def _push_with_bound_branches(self, target, overwrite,
2251
 
            stop_revision,
2252
 
            _override_hook_source_branch=None):
2253
 
        """Push from self into target, and into target's master if any.
2254
 
 
2255
 
        This is on the base BzrBranch class even though it doesn't support
2256
 
        bound branches because the *target* might be bound.
2257
 
        """
2258
 
        def _run_hooks():
2259
 
            if _override_hook_source_branch:
2260
 
                result.source_branch = _override_hook_source_branch
2261
 
            for hook in Branch.hooks['post_push']:
2262
 
                hook(result)
2263
 
 
2264
 
        bound_location = target.get_bound_location()
2265
 
        if bound_location and target.base != bound_location:
2266
 
            # there is a master branch.
2267
 
            #
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()
2272
 
            try:
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
2277
 
                # repository.
2278
 
                result = self._basic_push(target, overwrite, stop_revision)
2279
 
                result.master_branch = master_branch
2280
 
                result.local_branch = target
2281
 
                _run_hooks()
2282
 
                return result
2283
 
            finally:
2284
 
                master_branch.unlock()
2285
 
        else:
2286
 
            # no master branch
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
2290
 
            # 20070504
2291
 
            result.master_branch = target
2292
 
            result.local_branch = None
2293
 
            _run_hooks()
2294
 
            return result
2295
 
 
2296
2233
    def _basic_push(self, target, overwrite, stop_revision):
2297
2234
        """Basic implementation of push without bound branches or hooks.
2298
2235
 
2299
 
        Must be called with self read locked and target write locked.
 
2236
        Must be called with source read locked and target write locked.
2300
2237
        """
2301
2238
        result = BranchPushResult()
2302
2239
        result.source_branch = self
2307
2244
            # We assume that during 'push' this repository is closer than
2308
2245
            # the target.
2309
2246
            graph = self.repository.get_graph(target.repository)
2310
 
            target.update_revisions(self, stop_revision, overwrite=overwrite,
2311
 
                                    graph=graph)
 
2247
            target.update_revisions(self, stop_revision,
 
2248
                overwrite=overwrite, graph=graph)
2312
2249
        if self._push_should_merge_tags():
2313
 
            result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
 
2250
            result.tag_conflicts = self.tags.merge_to(target.tags,
 
2251
                overwrite)
2314
2252
        result.new_revno, result.new_revid = target.last_revision_info()
2315
2253
        return result
2316
2254
 
3016
2954
        """
3017
2955
        raise NotImplementedError(self.update_revisions)
3018
2956
 
 
2957
    def push(self, overwrite=False, stop_revision=None,
 
2958
             _override_hook_source_branch=None):
 
2959
        """Mirror the source branch into the target branch.
 
2960
 
 
2961
        The source branch is considered to be 'local', having low latency.
 
2962
        """
 
2963
        raise NotImplementedError(self.push)
 
2964
 
3019
2965
 
3020
2966
class GenericInterBranch(InterBranch):
3021
2967
    """InterBranch implementation that uses public Branch functions.
3068
3014
        finally:
3069
3015
            self.source.unlock()
3070
3016
 
 
3017
    def push(self, overwrite=False, stop_revision=None,
 
3018
             _override_hook_source_branch=None):
 
3019
        """See InterBranch.push.
 
3020
 
 
3021
        This is the basic concrete implementation of push()
 
3022
 
 
3023
        :param _override_hook_source_branch: If specified, run
 
3024
        the hooks passing this Branch as the source, rather than self.
 
3025
        This is for use of RemoteBranch, where push is delegated to the
 
3026
        underlying vfs-based Branch.
 
3027
        """
 
3028
        # TODO: Public option to disable running hooks - should be trivial but
 
3029
        # needs tests.
 
3030
        self.source.lock_read()
 
3031
        try:
 
3032
            return _run_with_write_locked_target(
 
3033
                self.target, self._push_with_bound_branches, overwrite,
 
3034
                stop_revision,
 
3035
                _override_hook_source_branch=_override_hook_source_branch)
 
3036
        finally:
 
3037
            self.source.unlock()
 
3038
 
 
3039
    def _push_with_bound_branches(self, overwrite, stop_revision,
 
3040
            _override_hook_source_branch=None):
 
3041
        """Push from source into target, and into target's master if any.
 
3042
        """
 
3043
        def _run_hooks():
 
3044
            if _override_hook_source_branch:
 
3045
                result.source_branch = _override_hook_source_branch
 
3046
            for hook in Branch.hooks['post_push']:
 
3047
                hook(result)
 
3048
 
 
3049
        bound_location = self.target.get_bound_location()
 
3050
        if bound_location and self.target.base != bound_location:
 
3051
            # there is a master branch.
 
3052
            #
 
3053
            # XXX: Why the second check?  Is it even supported for a branch to
 
3054
            # be bound to itself? -- mbp 20070507
 
3055
            master_branch = self.target.get_master_branch()
 
3056
            master_branch.lock_write()
 
3057
            try:
 
3058
                # push into the master from the source branch.
 
3059
                self.source._basic_push(master_branch, overwrite, stop_revision)
 
3060
                # and push into the target branch from the source. Note that we
 
3061
                # push from the source branch again, because its considered the
 
3062
                # highest bandwidth repository.
 
3063
                result = self.source._basic_push(self.target, overwrite,
 
3064
                    stop_revision)
 
3065
                result.master_branch = master_branch
 
3066
                result.local_branch = self.target
 
3067
                _run_hooks()
 
3068
                return result
 
3069
            finally:
 
3070
                master_branch.unlock()
 
3071
        else:
 
3072
            # no master branch
 
3073
            result = self.source._basic_push(self.target, overwrite,
 
3074
                stop_revision)
 
3075
            # TODO: Why set master_branch and local_branch if there's no
 
3076
            # binding?  Maybe cleaner to just leave them unset? -- mbp
 
3077
            # 20070504
 
3078
            result.master_branch = self.target
 
3079
            result.local_branch = None
 
3080
            _run_hooks()
 
3081
            return result
 
3082
 
3071
3083
    @classmethod
3072
3084
    def is_compatible(self, source, target):
3073
3085
        # GenericBranch uses the public API, so always compatible