/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/branch.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-11-16 18:59:44 UTC
  • mfrom: (7143.15.15 more-cleanups)
  • Revision ID: breezy.the.bot@gmail.com-20181116185944-biefv1sub37qfybm
Sprinkle some PEP8iness.

Merged from https://code.launchpad.net/~jelmer/brz/more-cleanups/+merge/358611

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
class UnstackableBranchFormat(errors.BzrError):
57
57
 
58
58
    _fmt = ("The branch '%(url)s'(%(format)s) is not a stackable format. "
59
 
        "You will need to upgrade the branch to permit branch stacking.")
 
59
            "You will need to upgrade the branch to permit branch stacking.")
60
60
 
61
61
    def __init__(self, format, url):
62
62
        errors.BzrError.__init__(self)
154
154
        repository._iter_for_revno(
155
155
            self.repository, self._partial_revision_history_cache,
156
156
            stop_index=stop_index, stop_revision=stop_revision)
157
 
        if self._partial_revision_history_cache[-1] == _mod_revision.NULL_REVISION:
 
157
        if self._partial_revision_history_cache[-1] == \
 
158
                _mod_revision.NULL_REVISION:
158
159
            self._partial_revision_history_cache.pop()
159
160
 
160
161
    def _get_check_refs(self):
172
173
        For instance, if the branch is at URL/.bzr/branch,
173
174
        Branch.open(URL) -> a Branch instance.
174
175
        """
175
 
        control = controldir.ControlDir.open(base,
176
 
            possible_transports=possible_transports, _unsupported=_unsupported)
177
 
        return control.open_branch(unsupported=_unsupported,
 
176
        control = controldir.ControlDir.open(
 
177
            base, possible_transports=possible_transports,
 
178
            _unsupported=_unsupported)
 
179
        return control.open_branch(
 
180
            unsupported=_unsupported,
178
181
            possible_transports=possible_transports)
179
182
 
180
183
    @staticmethod
181
184
    def open_from_transport(transport, name=None, _unsupported=False,
182
 
            possible_transports=None):
 
185
                            possible_transports=None):
183
186
        """Open the branch rooted at transport"""
184
 
        control = controldir.ControlDir.open_from_transport(transport, _unsupported)
185
 
        return control.open_branch(name=name, unsupported=_unsupported,
 
187
        control = controldir.ControlDir.open_from_transport(
 
188
            transport, _unsupported)
 
189
        return control.open_branch(
 
190
            name=name, unsupported=_unsupported,
186
191
            possible_transports=possible_transports)
187
192
 
188
193
    @staticmethod
193
198
 
194
199
        Basically we keep looking up until we find the control directory or
195
200
        run into the root.  If there isn't one, raises NotBranchError.
196
 
        If there is one and it is either an unrecognised format or an unsupported
197
 
        format, UnknownFormatError or UnsupportedFormatError are raised.
198
 
        If there is one, it is returned, along with the unused portion of url.
 
201
        If there is one and it is either an unrecognised format or an
 
202
        unsupported format, UnknownFormatError or UnsupportedFormatError are
 
203
        raised.  If there is one, it is returned, along with the unused portion
 
204
        of url.
199
205
        """
200
 
        control, relpath = controldir.ControlDir.open_containing(url,
201
 
                                                         possible_transports)
 
206
        control, relpath = controldir.ControlDir.open_containing(
 
207
            url, possible_transports)
202
208
        branch = control.open_branch(possible_transports=possible_transports)
203
209
        return (branch, relpath)
204
210
 
270
276
                # Silently fall back to local implicit nick if the master is
271
277
                # unavailable
272
278
                mutter("Could not connect to bound branch, "
273
 
                    "falling back to local nick.\n " + str(e))
 
279
                       "falling back to local nick.\n " + str(e))
274
280
        return config.get_nickname()
275
281
 
276
282
    def _set_nick(self, nick):
299
305
        new_history = []
300
306
        check_not_reserved_id = _mod_revision.check_not_reserved_id
301
307
        # Do not include ghosts or graph origin in revision_history
302
 
        while (current_rev_id in parents_map and
303
 
               len(parents_map[current_rev_id]) > 0):
 
308
        while (current_rev_id in parents_map
 
309
               and len(parents_map[current_rev_id]) > 0):
304
310
            check_not_reserved_id(current_rev_id)
305
311
            new_history.append(current_rev_id)
306
312
            current_rev_id = parents_map[current_rev_id][0]
407
413
            This dictionary should not be modified by the caller.
408
414
        """
409
415
        if 'evil' in debug.debug_flags:
410
 
            mutter_callsite(3, "get_revision_id_to_revno_map scales with ancestry.")
 
416
            mutter_callsite(
 
417
                3, "get_revision_id_to_revno_map scales with ancestry.")
411
418
        with self.lock_read():
412
419
            if self._revision_id_to_revno_cache is not None:
413
420
                mapping = self._revision_id_to_revno_cache
414
421
            else:
415
422
                mapping = self._gen_revno_map()
416
423
                self._cache_revision_id_to_revno(mapping)
417
 
            # TODO: jam 20070417 Since this is being cached, should we be returning
418
 
            #       a copy?
419
 
            # I would rather not, and instead just declare that users should not
420
 
            # modify the return value.
 
424
            # TODO: jam 20070417 Since this is being cached, should we be
 
425
            # returning a copy?
 
426
            # I would rather not, and instead just declare that users should
 
427
            # not modify the return value.
421
428
            return mapping
422
429
 
423
430
    def _gen_revno_map(self):
430
437
 
431
438
        :return: A dictionary mapping revision_id => dotted revno.
432
439
        """
433
 
        revision_id_to_revno = dict((rev_id, revno)
434
 
            for rev_id, depth, revno, end_of_merge
435
 
             in self.iter_merge_sorted_revisions())
 
440
        revision_id_to_revno = {
 
441
            rev_id: revno for rev_id, depth, revno, end_of_merge
 
442
            in self.iter_merge_sorted_revisions()}
436
443
        return revision_id_to_revno
437
444
 
438
445
    def iter_merge_sorted_revisions(self, start_revision_id=None,
439
 
            stop_revision_id=None, stop_rule='exclude', direction='reverse'):
 
446
                                    stop_revision_id=None,
 
447
                                    stop_rule='exclude', direction='reverse'):
440
448
        """Walk the revisions for a branch in merge sorted order.
441
449
 
442
450
        Merge sorted order is the output from a merge-aware,
454
462
            * 'include' - the stop revision is the last item in the result
455
463
            * 'with-merges' - include the stop revision and all of its
456
464
              merged revisions in the result
457
 
            * 'with-merges-without-common-ancestry' - filter out revisions 
 
465
            * 'with-merges-without-common-ancestry' - filter out revisions
458
466
              that are in both ancestries
459
467
        :param direction: either 'reverse' or 'forward':
460
468
 
503
511
                raise ValueError('invalid direction %r' % direction)
504
512
 
505
513
    def _filter_merge_sorted_revisions(self, merge_sorted_revisions,
506
 
        start_revision_id, stop_revision_id, stop_rule):
 
514
                                       start_revision_id, stop_revision_id,
 
515
                                       stop_rule):
507
516
        """Iterate over an inclusive range of sorted revisions."""
508
517
        rev_iter = iter(merge_sorted_revisions)
509
518
        if start_revision_id is not None:
564
573
                if rev_id == left_parent:
565
574
                    # reached the left parent after the stop_revision
566
575
                    return
567
 
                if (not reached_stop_revision_id or
568
 
                        rev_id in revision_id_whitelist):
 
576
                if (not reached_stop_revision_id
 
577
                        or rev_id in revision_id_whitelist):
569
578
                    yield (rev_id, node.merge_depth, node.revno,
570
 
                       node.end_of_merge)
 
579
                           node.end_of_merge)
571
580
                    if reached_stop_revision_id or rev_id == stop_revision_id:
572
581
                        # only do the merged revs of rev_id from now on
573
582
                        rev = self.repository.get_revision(rev_id)
629
638
        """Tell this branch object not to release the physical lock when this
630
639
        object is unlocked.
631
640
 
632
 
        If lock_write doesn't return a token, then this method is not supported.
 
641
        If lock_write doesn't return a token, then this method is not
 
642
        supported.
633
643
        """
634
644
        self.control_files.leave_in_place()
635
645
 
637
647
        """Tell this branch object to release the physical lock when this
638
648
        object is unlocked, even if it didn't originally acquire it.
639
649
 
640
 
        If lock_write doesn't return a token, then this method is not supported.
 
650
        If lock_write doesn't return a token, then this method is not
 
651
        supported.
641
652
        """
642
653
        self.control_files.dont_leave_in_place()
643
654
 
680
691
        """
681
692
        with self.lock_write():
682
693
            return InterBranch.get(from_branch, self).fetch(
683
 
                    last_revision, limit=limit)
 
694
                last_revision, limit=limit)
684
695
 
685
696
    def get_bound_location(self):
686
697
        """Return the URL of the branch we are bound to.
708
719
        :param revprops: Optional dictionary of revision properties.
709
720
        :param revision_id: Optional revision id.
710
721
        :param lossy: Whether to discard data that can not be natively
711
 
            represented, when pushing to a foreign VCS 
 
722
            represented, when pushing to a foreign VCS
712
723
        """
713
724
 
714
725
        if config_stack is None:
715
726
            config_stack = self.get_config_stack()
716
727
 
717
 
        return self.repository.get_commit_builder(self, parents, config_stack,
718
 
            timestamp, timezone, committer, revprops, revision_id,
719
 
            lossy)
 
728
        return self.repository.get_commit_builder(
 
729
            self, parents, config_stack, timestamp, timezone, committer,
 
730
            revprops, revision_id, lossy)
720
731
 
721
732
    def get_master_branch(self, possible_transports=None):
722
733
        """Return the branch we are bound to.
761
772
                if not graph.is_ancestor(last_rev, revision_id):
762
773
                    # our previous tip is not merged into stop_revision
763
774
                    raise errors.DivergedBranches(self, other_branch)
764
 
            revno = graph.find_distance_to_null(revision_id, known_revision_ids)
 
775
            revno = graph.find_distance_to_null(
 
776
                revision_id, known_revision_ids)
765
777
            self.set_last_revision_info(revno, revision_id)
766
778
 
767
779
    def set_parent(self, url):
775
787
                try:
776
788
                    url.encode('ascii')
777
789
                except UnicodeEncodeError:
778
 
                    raise urlutils.InvalidURL(url,
779
 
                        "Urls must be 7-bit ascii, "
 
790
                    raise urlutils.InvalidURL(
 
791
                        url, "Urls must be 7-bit ascii, "
780
792
                        "use breezy.urlutils.escape")
781
793
            url = urlutils.relative_url(self.base, url)
782
794
        with self.lock_write():
793
805
        if not self._format.supports_stacking():
794
806
            raise UnstackableBranchFormat(self._format, self.user_url)
795
807
        with self.lock_write():
796
 
            # XXX: Changing from one fallback repository to another does not check
797
 
            # that all the data you need is present in the new fallback.
 
808
            # XXX: Changing from one fallback repository to another does not
 
809
            # check that all the data you need is present in the new fallback.
798
810
            # Possibly it should.
799
811
            self._check_stackable_repo()
800
812
            if not url:
801
813
                try:
802
 
                    old_url = self.get_stacked_on_url()
 
814
                    self.get_stacked_on_url()
803
815
                except (errors.NotStacked, UnstackableBranchFormat,
804
 
                    errors.UnstackableRepositoryFormat):
 
816
                        errors.UnstackableRepositoryFormat):
805
817
                    return
806
818
                self._unstack()
807
819
            else:
808
 
                self._activate_fallback_location(url,
809
 
                    possible_transports=[self.controldir.root_transport])
 
820
                self._activate_fallback_location(
 
821
                    url, possible_transports=[self.controldir.root_transport])
810
822
            # write this out after the repository is stacked to avoid setting a
811
823
            # stacked config that doesn't work.
812
824
            self._set_config_location('stacked_on_location', url)
820
832
            pb.update(gettext("Unstacking"))
821
833
            # The basic approach here is to fetch the tip of the branch,
822
834
            # including all available ghosts, from the existing stacked
823
 
            # repository into a new repository object without the fallbacks. 
 
835
            # repository into a new repository object without the fallbacks.
824
836
            #
825
837
            # XXX: See <https://launchpad.net/bugs/397286> - this may not be
826
838
            # correct for CHKMap repostiories
827
839
            old_repository = self.repository
828
840
            if len(old_repository._fallback_repositories) != 1:
829
 
                raise AssertionError("can't cope with fallback repositories "
830
 
                    "of %r (fallbacks: %r)" % (old_repository,
831
 
                        old_repository._fallback_repositories))
 
841
                raise AssertionError(
 
842
                    "can't cope with fallback repositories "
 
843
                    "of %r (fallbacks: %r)" % (
 
844
                        old_repository, old_repository._fallback_repositories))
832
845
            # Open the new repository object.
833
846
            # Repositories don't offer an interface to remove fallback
834
847
            # repositories today; take the conceptually simpler option and just
841
854
                self.controldir.root_transport.base)
842
855
            new_repository = new_bzrdir.find_repository()
843
856
            if new_repository._fallback_repositories:
844
 
                raise AssertionError("didn't expect %r to have "
845
 
                    "fallback_repositories"
 
857
                raise AssertionError(
 
858
                    "didn't expect %r to have fallback_repositories"
846
859
                    % (self.repository,))
847
860
            # Replace self.repository with the new repository.
848
861
            # Do our best to transfer the lock state (i.e. lock-tokens and
875
888
            if old_lock_count == 0:
876
889
                raise AssertionError(
877
890
                    'old_repository should have been locked at least once.')
878
 
            for i in range(old_lock_count-1):
 
891
            for i in range(old_lock_count - 1):
879
892
                self.repository.lock_write()
880
893
            # Fetch from the old repository into the new.
881
894
            with old_repository.lock_read():
886
899
                    tags_to_fetch = set(self.tags.get_reverse_tag_dict())
887
900
                except errors.TagsNotSupported:
888
901
                    tags_to_fetch = set()
889
 
                fetch_spec = vf_search.NotInOtherForRevs(self.repository,
890
 
                    old_repository, required_ids=[self.last_revision()],
 
902
                fetch_spec = vf_search.NotInOtherForRevs(
 
903
                    self.repository, old_repository,
 
904
                    required_ids=[self.last_revision()],
891
905
                    if_present_ids=tags_to_fetch, find_ghosts=True).execute()
892
906
                self.repository.fetch(old_repository, fetch_spec=fetch_spec)
893
907
 
975
989
        """
976
990
        with self.lock_read():
977
991
            if self._last_revision_info_cache is None:
978
 
                self._last_revision_info_cache = self._read_last_revision_info()
 
992
                self._last_revision_info_cache = (
 
993
                    self._read_last_revision_info())
979
994
            return self._last_revision_info_cache
980
995
 
981
996
    def _read_last_revision_info(self):
1035
1050
 
1036
1051
        :returns: PullResult instance
1037
1052
        """
1038
 
        return InterBranch.get(source, self).pull(overwrite=overwrite,
1039
 
            stop_revision=stop_revision,
 
1053
        return InterBranch.get(source, self).pull(
 
1054
            overwrite=overwrite, stop_revision=stop_revision,
1040
1055
            possible_transports=possible_transports, *args, **kwargs)
1041
1056
 
1042
1057
    def push(self, target, overwrite=False, stop_revision=None, lossy=False,
1043
 
            *args, **kwargs):
 
1058
             *args, **kwargs):
1044
1059
        """Mirror this branch into target.
1045
1060
 
1046
1061
        This branch is considered to be 'local', having low latency.
1047
1062
        """
1048
 
        return InterBranch.get(self, target).push(overwrite, stop_revision,
1049
 
            lossy, *args, **kwargs)
 
1063
        return InterBranch.get(self, target).push(
 
1064
            overwrite, stop_revision, lossy, *args, **kwargs)
1050
1065
 
1051
1066
    def basis_tree(self):
1052
1067
        """Return `Tree` object for last revision."""
1068
1083
            parent = urlutils.local_path_to_url(parent)
1069
1084
        try:
1070
1085
            return urlutils.join(self.base[:-1], parent)
1071
 
        except urlutils.InvalidURLJoin as e:
 
1086
        except urlutils.InvalidURLJoin:
1072
1087
            raise errors.InaccessibleParent(parent, self.user_url)
1073
1088
 
1074
1089
    def _get_parent_location(self):
1200
1215
        return result
1201
1216
 
1202
1217
    def sprout(self, to_controldir, revision_id=None, repository_policy=None,
1203
 
            repository=None, lossy=False):
 
1218
               repository=None, lossy=False):
1204
1219
        """Create a new line of development from the branch, into to_controldir.
1205
1220
 
1206
1221
        to_controldir controls the branch format.
1208
1223
        revision_id: if not None, the revision history in the new branch will
1209
1224
                     be truncated to end with revision_id.
1210
1225
        """
1211
 
        if (repository_policy is not None and
1212
 
            repository_policy.requires_stacking()):
 
1226
        if (repository_policy is not None
 
1227
                and repository_policy.requires_stacking()):
1213
1228
            to_controldir._format.require_stacking(_skip_repo=True)
1214
1229
        result = to_controldir.create_branch(repository=repository)
1215
1230
        if lossy:
1243
1258
        else:
1244
1259
            graph = self.repository.get_graph()
1245
1260
            try:
1246
 
                revno = graph.find_distance_to_null(revision_id, 
1247
 
                    [(source_revision_id, source_revno)])
 
1261
                revno = graph.find_distance_to_null(
 
1262
                    revision_id, [(source_revision_id, source_revno)])
1248
1263
            except errors.GhostRevisionsHaveNoRevno:
1249
1264
                # Default to 1, if we can't find anything else
1250
1265
                revno = 1
1295
1310
            if actual_revno != last_revno:
1296
1311
                result.errors.append(errors.BzrCheckError(
1297
1312
                    'revno does not match len(mainline) %s != %s' % (
1298
 
                    last_revno, actual_revno)))
 
1313
                        last_revno, actual_revno)))
1299
1314
            # TODO: We should probably also check that self.revision_history
1300
1315
            # matches the repository for older branch formats.
1301
 
            # If looking for the code that cross-checks repository parents against
1302
 
            # the Graph.iter_lefthand_ancestry output, that is now a repository
1303
 
            # specific check.
 
1316
            # If looking for the code that cross-checks repository parents
 
1317
            # against the Graph.iter_lefthand_ancestry output, that is now a
 
1318
            # repository specific check.
1304
1319
            return result
1305
1320
 
1306
1321
    def _get_checkout_format(self, lightweight=False):
1312
1327
        return format
1313
1328
 
1314
1329
    def create_clone_on_transport(self, to_transport, revision_id=None,
1315
 
        stacked_on=None, create_prefix=False, use_existing_dir=False,
1316
 
        no_tree=None):
 
1330
                                  stacked_on=None, create_prefix=False,
 
1331
                                  use_existing_dir=False, no_tree=None):
1317
1332
        """Create a clone of this branch and its bzrdir.
1318
1333
 
1319
1334
        :param to_transport: The transport to clone onto.
1326
1341
        """
1327
1342
        # XXX: Fix the bzrdir API to allow getting the branch back from the
1328
1343
        # clone call. Or something. 20090224 RBC/spiv.
1329
 
        # XXX: Should this perhaps clone colocated branches as well, 
 
1344
        # XXX: Should this perhaps clone colocated branches as well,
1330
1345
        # rather than just the default branch? 20100319 JRV
1331
1346
        if revision_id is None:
1332
1347
            revision_id = self.last_revision()
1333
 
        dir_to = self.controldir.clone_on_transport(to_transport,
1334
 
            revision_id=revision_id, stacked_on=stacked_on,
 
1348
        dir_to = self.controldir.clone_on_transport(
 
1349
            to_transport, revision_id=revision_id, stacked_on=stacked_on,
1335
1350
            create_prefix=create_prefix, use_existing_dir=use_existing_dir,
1336
1351
            no_tree=no_tree)
1337
1352
        return dir_to.open_branch()
1368
1383
                pass
1369
1384
            else:
1370
1385
                raise errors.AlreadyControlDirError(t.base)
1371
 
            if checkout.control_transport.base == self.controldir.control_transport.base:
 
1386
            if (checkout.control_transport.base
 
1387
                    == self.controldir.control_transport.base):
1372
1388
                # When checking out to the same control directory,
1373
1389
                # always create a lightweight checkout
1374
1390
                lightweight = True
1377
1393
            from_branch = checkout.set_branch_reference(target_branch=self)
1378
1394
        else:
1379
1395
            policy = checkout.determine_repository_policy()
1380
 
            repo = policy.acquire_repository()[0]
 
1396
            policy.acquire_repository()
1381
1397
            checkout_branch = checkout.create_branch()
1382
1398
            checkout_branch.bind(self)
1383
1399
            # pull up to the specified revision_id to set the initial
1601
1617
        raise NotImplementedError(self.network_name)
1602
1618
 
1603
1619
    def open(self, controldir, name=None, _found=False, ignore_fallbacks=False,
1604
 
            found_repository=None, possible_transports=None):
 
1620
             found_repository=None, possible_transports=None):
1605
1621
        """Return the branch object for controldir.
1606
1622
 
1607
1623
        :param controldir: A ControlDir that contains a branch.
1623
1639
 
1624
1640
    def supports_leaving_lock(self):
1625
1641
        """True if this format supports leaving locks in place."""
1626
 
        return False # by default
 
1642
        return False  # by default
1627
1643
 
1628
1644
    def __str__(self):
1629
1645
        return self.get_format_description().rstrip()
1659
1675
        notified.
1660
1676
        """
1661
1677
        Hooks.__init__(self, "breezy.branch", "Branch.hooks")
1662
 
        self.add_hook('open',
 
1678
        self.add_hook(
 
1679
            'open',
1663
1680
            "Called with the Branch object that has been opened after a "
1664
1681
            "branch is opened.", (1, 8))
1665
 
        self.add_hook('post_push',
 
1682
        self.add_hook(
 
1683
            'post_push',
1666
1684
            "Called after a push operation completes. post_push is called "
1667
 
            "with a breezy.branch.BranchPushResult object and only runs in the "
1668
 
            "bzr client.", (0, 15))
1669
 
        self.add_hook('post_pull',
 
1685
            "with a breezy.branch.BranchPushResult object and only runs in "
 
1686
            "the bzr client.", (0, 15))
 
1687
        self.add_hook(
 
1688
            'post_pull',
1670
1689
            "Called after a pull operation completes. post_pull is called "
1671
1690
            "with a breezy.branch.PullResult object and only runs in the "
1672
1691
            "bzr client.", (0, 15))
1673
 
        self.add_hook('pre_commit',
 
1692
        self.add_hook(
 
1693
            'pre_commit',
1674
1694
            "Called after a commit is calculated but before it is "
1675
1695
            "completed. pre_commit is called with (local, master, old_revno, "
1676
1696
            "old_revid, future_revno, future_revid, tree_delta, future_tree"
1680
1700
            " future_tree is an in-memory tree obtained from "
1681
1701
            "CommitBuilder.revision_tree() and hooks MUST NOT modify this "
1682
1702
            "tree.", (0, 91))
1683
 
        self.add_hook('post_commit',
 
1703
        self.add_hook(
 
1704
            'post_commit',
1684
1705
            "Called in the bzr client after a commit has completed. "
1685
1706
            "post_commit is called with (local, master, old_revno, old_revid, "
1686
1707
            "new_revno, new_revid). old_revid is NULL_REVISION for the first "
1687
1708
            "commit to a branch.", (0, 15))
1688
 
        self.add_hook('post_uncommit',
 
1709
        self.add_hook(
 
1710
            'post_uncommit',
1689
1711
            "Called in the bzr client after an uncommit completes. "
1690
1712
            "post_uncommit is called with (local, master, old_revno, "
1691
1713
            "old_revid, new_revno, new_revid) where local is the local branch "
1692
1714
            "or None, master is the target branch, and an empty branch "
1693
1715
            "receives new_revno of 0, new_revid of None.", (0, 15))
1694
 
        self.add_hook('pre_change_branch_tip',
 
1716
        self.add_hook(
 
1717
            'pre_change_branch_tip',
1695
1718
            "Called in bzr client and server before a change to the tip of a "
1696
1719
            "branch is made. pre_change_branch_tip is called with a "
1697
1720
            "breezy.branch.ChangeBranchTipParams. Note that push, pull, "
1698
1721
            "commit, uncommit will all trigger this hook.", (1, 6))
1699
 
        self.add_hook('post_change_branch_tip',
 
1722
        self.add_hook(
 
1723
            'post_change_branch_tip',
1700
1724
            "Called in bzr client and server after a change to the tip of a "
1701
1725
            "branch is made. post_change_branch_tip is called with a "
1702
1726
            "breezy.branch.ChangeBranchTipParams. Note that push, pull, "
1703
1727
            "commit, uncommit will all trigger this hook.", (1, 4))
1704
 
        self.add_hook('transform_fallback_location',
 
1728
        self.add_hook(
 
1729
            'transform_fallback_location',
1705
1730
            "Called when a stacked branch is activating its fallback "
1706
1731
            "locations. transform_fallback_location is called with (branch, "
1707
1732
            "url), and should return a new url. Returning the same url "
1713
1738
            "multiple hooks installed for transform_fallback_location, "
1714
1739
            "all are called with the url returned from the previous hook."
1715
1740
            "The order is however undefined.", (1, 9))
1716
 
        self.add_hook('automatic_tag_name',
 
1741
        self.add_hook(
 
1742
            'automatic_tag_name',
1717
1743
            "Called to determine an automatic tag name for a revision. "
1718
1744
            "automatic_tag_name is called with (branch, revision_id) and "
1719
1745
            "should return a tag name or None if no tag name could be "
1720
1746
            "determined. The first non-None tag name returned will be used.",
1721
1747
            (2, 2))
1722
 
        self.add_hook('post_branch_init',
 
1748
        self.add_hook(
 
1749
            'post_branch_init',
1723
1750
            "Called after new branch initialization completes. "
1724
1751
            "post_branch_init is called with a "
1725
1752
            "breezy.branch.BranchInitHookParams. "
1726
1753
            "Note that init, branch and checkout (both heavyweight and "
1727
1754
            "lightweight) will all trigger this hook.", (2, 2))
1728
 
        self.add_hook('post_switch',
 
1755
        self.add_hook(
 
1756
            'post_switch',
1729
1757
            "Called after a checkout switches branch. "
1730
1758
            "post_switch is called with a "
1731
1759
            "breezy.branch.SwitchHookParams.", (2, 2))
1732
1760
 
1733
1761
 
1734
 
 
1735
1762
# install the default hooks into the Branch class.
1736
1763
Branch.hooks = BranchHooks()
1737
1764
 
1842
1869
        return self.__dict__ == other.__dict__
1843
1870
 
1844
1871
    def __repr__(self):
1845
 
        return "<%s for %s to (%s, %s)>" % (self.__class__.__name__,
1846
 
            self.control_dir, self.to_branch,
 
1872
        return "<%s for %s to (%s, %s)>" % (
 
1873
            self.__class__.__name__, self.control_dir, self.to_branch,
1847
1874
            self.revision_id)
1848
1875
 
1849
1876
 
1857
1884
 
1858
1885
    def get_default(self):
1859
1886
        """Return the current default format."""
1860
 
        if (self._default_format_key is not None and
1861
 
            self._default_format is None):
 
1887
        if (self._default_format_key is not None
 
1888
                and self._default_format is None):
1862
1889
            self._default_format = self.get(self._default_format_key)
1863
1890
        return self._default_format
1864
1891
 
1993
2020
            if self.old_revid != self.new_revid:
1994
2021
                note(gettext('Pushed up to revision %d.') % self.new_revno)
1995
2022
            if tag_updates:
1996
 
                note(ngettext('%d tag updated.', '%d tags updated.', len(tag_updates)) % len(tag_updates))
 
2023
                note(ngettext('%d tag updated.', '%d tags updated.',
 
2024
                              len(tag_updates)) % len(tag_updates))
1997
2025
            if self.old_revid == self.new_revid and not tag_updates:
1998
2026
                if not tag_conflicts:
1999
2027
                    note(gettext('No new revisions or tags to push.'))
2019
2047
            if any.
2020
2048
        """
2021
2049
        note(gettext('checked branch {0} format {1}').format(
2022
 
                                self.branch.user_url, self.branch._format))
 
2050
            self.branch.user_url, self.branch._format))
2023
2051
        for error in self.errors:
2024
2052
            note(gettext('found error:%s'), error)
2025
2053
 
2038
2066
    @classmethod
2039
2067
    def _get_branch_formats_to_test(klass):
2040
2068
        """Return an iterable of format tuples for testing.
2041
 
        
 
2069
 
2042
2070
        :return: An iterable of (from_format, to_format) to use when testing
2043
2071
            this InterBranch class. Each InterBranch class should define this
2044
2072
            method itself.
2136
2164
            fetch_spec_factory.source_branch_stop_revision_id = stop_revision
2137
2165
            fetch_spec_factory.source_repo = self.source.repository
2138
2166
            fetch_spec_factory.target_repo = self.target.repository
2139
 
            fetch_spec_factory.target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
 
2167
            fetch_spec_factory.target_repo_kind = (
 
2168
                fetch.TargetRepoKinds.PREEXISTING)
2140
2169
            fetch_spec_factory.limit = limit
2141
2170
            fetch_spec = fetch_spec_factory.make_fetch_spec()
2142
2171
            return self.target.repository.fetch(
2143
 
                    self.source.repository,
2144
 
                    fetch_spec=fetch_spec)
 
2172
                self.source.repository,
 
2173
                fetch_spec=fetch_spec)
2145
2174
 
2146
2175
    def _update_revisions(self, stop_revision=None, overwrite=False,
2147
 
            graph=None):
 
2176
                          graph=None):
2148
2177
        with self.source.lock_read(), self.target.lock_write():
2149
2178
            other_revno, other_last_revision = self.source.last_revision_info()
2150
 
            stop_revno = None # unknown
 
2179
            stop_revno = None  # unknown
2151
2180
            if stop_revision is None:
2152
2181
                stop_revision = other_last_revision
2153
2182
                if _mod_revision.is_null(stop_revision):
2176
2205
                if graph is None:
2177
2206
                    graph = self.target.repository.get_graph()
2178
2207
                this_revno, this_last_revision = \
2179
 
                        self.target.last_revision_info()
2180
 
                stop_revno = graph.find_distance_to_null(stop_revision,
2181
 
                                [(other_last_revision, other_revno),
2182
 
                                 (this_last_revision, this_revno)])
 
2208
                    self.target.last_revision_info()
 
2209
                stop_revno = graph.find_distance_to_null(
 
2210
                    stop_revision, [(other_last_revision, other_revno),
 
2211
                                    (this_last_revision, this_revno)])
2183
2212
            self.target.set_last_revision_info(stop_revno, stop_revision)
2184
2213
 
2185
2214
    def pull(self, overwrite=False, stop_revision=None,
2208
2237
                    source_is_master = False
2209
2238
            if not local and bound_location and not source_is_master:
2210
2239
                # not pulling from master, so we need to update master.
2211
 
                master_branch = self.target.get_master_branch(possible_transports)
 
2240
                master_branch = self.target.get_master_branch(
 
2241
                    possible_transports)
2212
2242
                master_branch.lock_write()
2213
2243
            try:
2214
2244
                if master_branch:
2215
2245
                    # pull from source into master.
2216
 
                    master_branch.pull(self.source, overwrite, stop_revision,
2217
 
                        run_hooks=False)
2218
 
                return self._pull(overwrite,
2219
 
                    stop_revision, _hook_master=master_branch,
 
2246
                    master_branch.pull(
 
2247
                        self.source, overwrite, stop_revision, run_hooks=False)
 
2248
                return self._pull(
 
2249
                    overwrite, stop_revision, _hook_master=master_branch,
2220
2250
                    run_hooks=run_hooks,
2221
2251
                    _override_hook_target=_override_hook_target,
2222
2252
                    merge_tags_to_master=not source_is_master)
2239
2269
            raise errors.LossyPushToSameVCS(self.source, self.target)
2240
2270
        # TODO: Public option to disable running hooks - should be trivial but
2241
2271
        # needs tests.
 
2272
 
2242
2273
        def _run_hooks():
2243
2274
            if _override_hook_source_branch:
2244
2275
                result.source_branch = _override_hook_source_branch
2250
2281
            if bound_location and self.target.base != bound_location:
2251
2282
                # there is a master branch.
2252
2283
                #
2253
 
                # XXX: Why the second check?  Is it even supported for a branch to
2254
 
                # be bound to itself? -- mbp 20070507
 
2284
                # XXX: Why the second check?  Is it even supported for a branch
 
2285
                # to be bound to itself? -- mbp 20070507
2255
2286
                master_branch = self.target.get_master_branch()
2256
2287
                with master_branch.lock_write():
2257
2288
                    # push into the master from the source branch.
2258
2289
                    master_inter = InterBranch.get(self.source, master_branch)
2259
2290
                    master_inter._basic_push(overwrite, stop_revision)
2260
 
                    # and push into the target branch from the source. Note that
2261
 
                    # we push from the source branch again, because it's considered
2262
 
                    # the highest bandwidth repository.
 
2291
                    # and push into the target branch from the source. Note
 
2292
                    # that we push from the source branch again, because it's
 
2293
                    # considered the highest bandwidth repository.
2263
2294
                    result = self._basic_push(overwrite, stop_revision)
2264
2295
                    result.master_branch = master_branch
2265
2296
                    result.local_branch = self.target
2291
2322
            # We assume that during 'push' this repository is closer than
2292
2323
            # the target.
2293
2324
            graph = self.source.repository.get_graph(self.target.repository)
2294
 
            self._update_revisions(stop_revision,
2295
 
                overwrite=("history" in overwrite),
2296
 
                graph=graph)
 
2325
            self._update_revisions(
 
2326
                stop_revision, overwrite=("history" in overwrite), graph=graph)
2297
2327
        if self.source._push_should_merge_tags():
2298
2328
            result.tag_updates, result.tag_conflicts = (
2299
2329
                self.source.tags.merge_to(
2300
 
                self.target.tags, "tags" in overwrite))
 
2330
                    self.target.tags, "tags" in overwrite))
2301
2331
        result.new_revno, result.new_revid = self.target.last_revision_info()
2302
2332
        return result
2303
2333
 
2304
2334
    def _pull(self, overwrite=False, stop_revision=None,
2305
 
             possible_transports=None, _hook_master=None, run_hooks=True,
2306
 
             _override_hook_target=None, local=False,
2307
 
             merge_tags_to_master=True):
 
2335
              possible_transports=None, _hook_master=None, run_hooks=True,
 
2336
              _override_hook_target=None, local=False,
 
2337
              merge_tags_to_master=True):
2308
2338
        """See Branch.pull.
2309
2339
 
2310
2340
        This function is the core worker, used by GenericInterBranch.pull to
2335
2365
            # the source one.
2336
2366
            self.source.update_references(self.target)
2337
2367
            graph = self.target.repository.get_graph(self.source.repository)
2338
 
            # TODO: Branch formats should have a flag that indicates 
 
2368
            # TODO: Branch formats should have a flag that indicates
2339
2369
            # that revno's are expensive, and pull() should honor that flag.
2340
2370
            # -- JRV20090506
2341
2371
            result.old_revno, result.old_revid = \
2342
2372
                self.target.last_revision_info()
2343
2373
            overwrite = _fix_overwrite_type(overwrite)
2344
 
            self._update_revisions(stop_revision,
2345
 
                overwrite=("history" in overwrite),
2346
 
                graph=graph)
2347
 
            # TODO: The old revid should be specified when merging tags, 
2348
 
            # so a tags implementation that versions tags can only 
 
2374
            self._update_revisions(
 
2375
                stop_revision, overwrite=("history" in overwrite), graph=graph)
 
2376
            # TODO: The old revid should be specified when merging tags,
 
2377
            # so a tags implementation that versions tags can only
2349
2378
            # pull in the most recent changes. -- JRV20090506
2350
2379
            result.tag_updates, result.tag_conflicts = (
2351
 
                self.source.tags.merge_to(self.target.tags,
2352
 
                    "tags" in overwrite,
 
2380
                self.source.tags.merge_to(
 
2381
                    self.target.tags, "tags" in overwrite,
2353
2382
                    ignore_master=not merge_tags_to_master))
2354
 
            result.new_revno, result.new_revid = self.target.last_revision_info()
 
2383
            result.new_revno, result.new_revid = (
 
2384
                self.target.last_revision_info())
2355
2385
            if _hook_master:
2356
2386
                result.master_branch = _hook_master
2357
2387
                result.local_branch = result.target_branch