~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

merge bzr.dev and tweaks to lower threads

Show diffs side-by-side

added added

removed removed

Lines of Context:
347
347
        raise NotImplementedError(self.set_revision_history)
348
348
 
349
349
    def set_stacked_on(self, url):
350
 
        """set the URL this branch is stacked against.
 
350
        """Set the URL this branch is stacked against.
351
351
 
352
352
        :raises UnstackableBranchFormat: If the branch does not support
353
353
            stacking.
473
473
                raise errors.NoSuchRevision(self, stop_revision)
474
474
        return other_history[self_len:stop_revision]
475
475
 
 
476
    @needs_write_lock
476
477
    def update_revisions(self, other, stop_revision=None, overwrite=False,
477
478
                         graph=None):
478
479
        """Pull in new perfect-fit revisions.
485
486
            information. This can be None.
486
487
        :return: None
487
488
        """
488
 
        raise NotImplementedError(self.update_revisions)
 
489
        other.lock_read()
 
490
        try:
 
491
            other_revno, other_last_revision = other.last_revision_info()
 
492
            stop_revno = None # unknown
 
493
            if stop_revision is None:
 
494
                stop_revision = other_last_revision
 
495
                if _mod_revision.is_null(stop_revision):
 
496
                    # if there are no commits, we're done.
 
497
                    return
 
498
                stop_revno = other_revno
 
499
 
 
500
            # what's the current last revision, before we fetch [and change it
 
501
            # possibly]
 
502
            last_rev = _mod_revision.ensure_null(self.last_revision())
 
503
            # we fetch here so that we don't process data twice in the common
 
504
            # case of having something to pull, and so that the check for 
 
505
            # already merged can operate on the just fetched graph, which will
 
506
            # be cached in memory.
 
507
            self.fetch(other, stop_revision)
 
508
            # Check to see if one is an ancestor of the other
 
509
            if not overwrite:
 
510
                if graph is None:
 
511
                    graph = self.repository.get_graph()
 
512
                heads = graph.heads([stop_revision, last_rev])
 
513
                if heads == set([last_rev]):
 
514
                    # The current revision is a decendent of the target,
 
515
                    # nothing to do
 
516
                    return
 
517
                elif heads == set([stop_revision, last_rev]):
 
518
                    # These branches have diverged
 
519
                    raise errors.DivergedBranches(self, other)
 
520
                elif heads != set([stop_revision]):
 
521
                    raise AssertionError("invalid heads: %r" % heads)
 
522
            if stop_revno is None:
 
523
                if graph is None:
 
524
                    graph = self.repository.get_graph()
 
525
                this_revno, this_last_revision = self.last_revision_info()
 
526
                stop_revno = graph.find_distance_to_null(stop_revision,
 
527
                                [(other_last_revision, other_revno),
 
528
                                 (this_last_revision, this_revno)])
 
529
            self.set_last_revision_info(stop_revno, stop_revision)
 
530
        finally:
 
531
            other.unlock()
 
532
 
 
533
 
489
534
 
490
535
    def revision_id_to_revno(self, revision_id):
491
536
        """Given a revision id, return its revno"""
944
989
            for (filename, content) in utf8_files:
945
990
                branch_transport.put_bytes(
946
991
                    filename, content,
947
 
                    mode=control_files._file_mode)
 
992
                    mode=a_bzrdir._get_file_mode())
948
993
        finally:
949
994
            control_files.unlock()
950
995
        return self.open(a_bzrdir, _found=True)
1143
1188
        raise NotImplementedError(self._branch_class)
1144
1189
 
1145
1190
    def open(self, a_bzrdir, _found=False):
1146
 
        """Return the branch object for a_bzrdir
 
1191
        """Return the branch object for a_bzrdir.
1147
1192
 
1148
1193
        _found is a private parameter, do not use it. It is used to indicate
1149
1194
               if format probing has already be done.
1263
1308
        utf8_files = [('last-revision', '0 null:\n'),
1264
1309
                      ('branch.conf', ''),
1265
1310
                      ('tags', ''),
1266
 
                      ('stacked-on', '\n'),
1267
1311
                      ]
1268
1312
        return self._initialize_helper(a_bzrdir, utf8_files)
1269
1313
 
1473
1517
        It is intended to be called by BzrBranch5.set_revision_history."""
1474
1518
        self._transport.put_bytes(
1475
1519
            'revision-history', '\n'.join(history),
1476
 
            mode=self.control_files._file_mode)
 
1520
            mode=self.bzrdir._get_file_mode())
1477
1521
 
1478
1522
    @needs_write_lock
1479
1523
    def set_revision_history(self, rev_history):
1566
1610
        self.set_revision_history(self._lefthand_history(revision_id,
1567
1611
            last_rev, other_branch))
1568
1612
 
1569
 
    @needs_write_lock
1570
 
    def update_revisions(self, other, stop_revision=None, overwrite=False,
1571
 
                         graph=None):
1572
 
        """See Branch.update_revisions."""
1573
 
        other.lock_read()
1574
 
        try:
1575
 
            other_revno, other_last_revision = other.last_revision_info()
1576
 
            stop_revno = None # unknown
1577
 
            if stop_revision is None:
1578
 
                stop_revision = other_last_revision
1579
 
                if _mod_revision.is_null(stop_revision):
1580
 
                    # if there are no commits, we're done.
1581
 
                    return
1582
 
                stop_revno = other_revno
1583
 
 
1584
 
            # what's the current last revision, before we fetch [and change it
1585
 
            # possibly]
1586
 
            last_rev = _mod_revision.ensure_null(self.last_revision())
1587
 
            # we fetch here so that we don't process data twice in the common
1588
 
            # case of having something to pull, and so that the check for 
1589
 
            # already merged can operate on the just fetched graph, which will
1590
 
            # be cached in memory.
1591
 
            self.fetch(other, stop_revision)
1592
 
            # Check to see if one is an ancestor of the other
1593
 
            if not overwrite:
1594
 
                if graph is None:
1595
 
                    graph = self.repository.get_graph()
1596
 
                heads = graph.heads([stop_revision, last_rev])
1597
 
                if heads == set([last_rev]):
1598
 
                    # The current revision is a decendent of the target,
1599
 
                    # nothing to do
1600
 
                    return
1601
 
                elif heads == set([stop_revision, last_rev]):
1602
 
                    # These branches have diverged
1603
 
                    raise errors.DivergedBranches(self, other)
1604
 
                elif heads != set([stop_revision]):
1605
 
                    raise AssertionError("invalid heads: %r" % heads)
1606
 
            if stop_revno is None:
1607
 
                if graph is None:
1608
 
                    graph = self.repository.get_graph()
1609
 
                this_revno, this_last_revision = self.last_revision_info()
1610
 
                stop_revno = graph.find_distance_to_null(stop_revision,
1611
 
                                [(other_last_revision, other_revno),
1612
 
                                 (this_last_revision, this_revno)])
1613
 
            self.set_last_revision_info(stop_revno, stop_revision)
1614
 
        finally:
1615
 
            other.unlock()
1616
 
 
1617
1613
    def basis_tree(self):
1618
1614
        """See Branch.basis_tree."""
1619
1615
        return self.repository.revision_tree(self.last_revision())
1798
1794
            self._transport.delete('parent')
1799
1795
        else:
1800
1796
            self._transport.put_bytes('parent', url + '\n',
1801
 
                mode=self.control_files._file_mode)
 
1797
                mode=self.bzrdir._get_file_mode())
1802
1798
 
1803
1799
    def set_stacked_on(self, url):
1804
1800
        raise errors.UnstackableBranchFormat(self._format, self.base)
1993
1989
        revision_id = _mod_revision.ensure_null(revision_id)
1994
1990
        out_string = '%d %s\n' % (revno, revision_id)
1995
1991
        self._transport.put_bytes('last-revision', out_string,
1996
 
            mode=self.control_files._file_mode)
 
1992
            mode=self.bzrdir._get_file_mode())
1997
1993
 
1998
1994
    @needs_write_lock
1999
1995
    def set_last_revision_info(self, revno, revision_id):
2114
2110
 
2115
2111
    def get_stacked_on(self):
2116
2112
        self._check_stackable_repo()
2117
 
        stacked_url_str = self._transport.get_bytes('stacked-on')
2118
 
        stacked_url = stacked_url_str.decode('utf_8').rstrip('\n')
2119
 
        if not stacked_url:
 
2113
        stacked_url = self._get_config_location('stacked_on_location')
 
2114
        if stacked_url is None:
2120
2115
            raise errors.NotStacked(self)
2121
2116
        return stacked_url
2122
2117
 
2146
2141
            source_repository = self._get_fallback_repository(old_url)
2147
2142
            for revision_id in chain([self.last_revision()],
2148
2143
                self.tags.get_reverse_tag_dict()):
2149
 
                self.repository.fetch(source_repository, revision_id, find_ghosts=True)
 
2144
                self.repository.fetch(source_repository, revision_id,
 
2145
                    find_ghosts=True)
2150
2146
        else:
2151
2147
            self._activate_fallback_location(url)
2152
2148
        # write this out after the repository is stacked to avoid setting a
2153
2149
        # stacked config that doesn't work.
2154
 
        self._transport.put_bytes('stacked-on', (url + '\n').encode('utf_8'))
 
2150
        self._set_config_location('stacked_on_location', url)
2155
2151
 
2156
2152
    def _get_append_revisions_only(self):
2157
2153
        value = self.get_config().get_user_option('append_revisions_only')
2236
2232
class BzrBranch6(BzrBranch7):
2237
2233
    """See BzrBranchFormat6 for the capabilities of this branch.
2238
2234
 
2239
 
    This subclass of BzrBranch7 disables the new features BzrBranch7 added.
 
2235
    This subclass of BzrBranch7 disables the new features BzrBranch7 added,
 
2236
    i.e. stacking.
2240
2237
    """
2241
2238
 
2242
2239
    def get_stacked_on(self):
2268
2265
    :ivar old_revid: Tip revision id before pull.
2269
2266
    :ivar new_revid: Tip revision id after pull.
2270
2267
    :ivar source_branch: Source (local) branch object.
2271
 
    :ivar master_branch: Master branch of the target, or None.
 
2268
    :ivar master_branch: Master branch of the target, or the target if no
 
2269
        Master
 
2270
    :ivar local_branch: target branch if there is a Master, else None
2272
2271
    :ivar target_branch: Target/destination branch object.
 
2272
    :ivar tag_conflicts: A list of tag conflicts, see BasicTags.merge_to
2273
2273
    """
2274
2274
 
2275
2275
    def __int__(self):
2350
2350
        # Copying done; now update target format
2351
2351
        new_branch._transport.put_bytes('format',
2352
2352
            format.get_format_string(),
2353
 
            mode=new_branch.control_files._file_mode)
 
2353
            mode=new_branch.bzrdir._get_file_mode())
2354
2354
 
2355
2355
        # Clean up old files
2356
2356
        new_branch._transport.delete('revision-history')
2366
2366
 
2367
2367
    def convert(self, branch):
2368
2368
        format = BzrBranchFormat7()
2369
 
        branch._transport.put_bytes('stacked-on', '\n')
 
2369
        branch._set_config_location('stacked_on_location', '')
2370
2370
        # update target format
2371
2371
        branch._transport.put_bytes('format', format.get_format_string())