~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
138
138
        """
139
139
        return bzrdir.BzrDir.create_standalone_workingtree(base).branch
140
140
 
 
141
    @deprecated_function(zero_eight)
141
142
    def setup_caching(self, cache_root):
142
143
        """Subclasses that care about caching should override this, and set
143
144
        up cached stores located under cache_root.
 
145
        
 
146
        NOTE: This is unused.
144
147
        """
145
 
        # seems to be unused, 2006-01-13 mbp
146
 
        warn('%s is deprecated' % self.setup_caching)
147
 
        self.cache_root = cache_root
 
148
        pass
148
149
 
149
150
    def get_config(self):
150
151
        return bzrlib.config.BranchConfig(self)
293
294
 
294
295
    def revision_history(self):
295
296
        """Return sequence of revision hashes on to this branch."""
296
 
        raise NotImplementedError('revision_history is abstract')
 
297
        raise NotImplementedError(self.revision_history)
297
298
 
298
299
    def revno(self):
299
300
        """Return current revision number for this branch.
580
581
            mainline_parent_id = revision_id
581
582
        return BranchCheckResult(self)
582
583
 
 
584
    def _get_checkout_format(self):
 
585
        """Return the most suitable metadir for a checkout of this branch.
 
586
        Weaves are used if this branch's repostory uses weaves.
 
587
        """
 
588
        if isinstance(self.bzrdir, bzrdir.BzrDirPreSplitOut):
 
589
            from bzrlib import repository
 
590
            format = bzrdir.BzrDirMetaFormat1()
 
591
            format.repository_format = repository.RepositoryFormat7()
 
592
        else:
 
593
            format = self.repository.bzrdir.cloning_metadir()
 
594
        return format
 
595
 
583
596
    def create_checkout(self, to_location, revision_id=None, 
584
597
                        lightweight=False):
585
598
        """Create a checkout of a branch.
590
603
        produce a bound branch (heavyweight checkout)
591
604
        :return: The tree of the created checkout
592
605
        """
 
606
        t = transport.get_transport(to_location)
 
607
        try:
 
608
            t.mkdir('.')
 
609
        except errors.FileExists:
 
610
            pass
593
611
        if lightweight:
594
 
            t = transport.get_transport(to_location)
595
 
            try:
596
 
                t.mkdir('.')
597
 
            except errors.FileExists:
598
 
                pass
599
612
            checkout = bzrdir.BzrDirMetaFormat1().initialize_on_transport(t)
600
613
            BranchReferenceFormat().initialize(checkout, self)
601
614
        else:
 
615
            format = self._get_checkout_format()
602
616
            checkout_branch = bzrdir.BzrDir.create_branch_convenience(
603
 
                to_location, force_new_tree=False)
 
617
                to_location, force_new_tree=False, format=format)
604
618
            checkout = checkout_branch.bzrdir
605
619
            checkout_branch.bind(self)
606
 
            if revision_id is not None:
607
 
                rh = checkout_branch.revision_history()
608
 
                new_rh = rh[:rh.index(revision_id) + 1]
609
 
                checkout_branch.set_revision_history(new_rh)
 
620
            # pull up to the specified revision_id to set the initial 
 
621
            # branch tip correctly, and seed it with history.
 
622
            checkout_branch.pull(self, stop_revision=revision_id)
610
623
        return checkout.create_workingtree(revision_id)
611
624
 
612
625
 
958
971
 
959
972
    __repr__ = __str__
960
973
 
961
 
    def __del__(self):
962
 
        # TODO: It might be best to do this somewhere else,
963
 
        # but it is nice for a Branch object to automatically
964
 
        # cache it's information.
965
 
        # Alternatively, we could have the Transport objects cache requests
966
 
        # See the earlier discussion about how major objects (like Branch)
967
 
        # should never expect their __del__ function to run.
968
 
        # XXX: cache_root seems to be unused, 2006-01-13 mbp
969
 
        if hasattr(self, 'cache_root') and self.cache_root is not None:
970
 
            try:
971
 
                osutils.rmtree(self.cache_root)
972
 
            except:
973
 
                pass
974
 
            self.cache_root = None
975
 
 
976
974
    def _get_base(self):
977
975
        return self._base
978
976
 
1187
1185
        try:
1188
1186
            old_count = len(self.revision_history())
1189
1187
            try:
1190
 
                self.update_revisions(source,stop_revision)
 
1188
                self.update_revisions(source, stop_revision)
1191
1189
            except DivergedBranches:
1192
1190
                if not overwrite:
1193
1191
                    raise
1328
1326
 
1329
1327
    @needs_write_lock
1330
1328
    def bind(self, other):
1331
 
        """Bind the local branch the other branch.
 
1329
        """Bind this branch to the branch other.
1332
1330
 
 
1331
        This does not push or pull data between the branches, though it does
 
1332
        check for divergence to raise an error when the branches are not
 
1333
        either the same, or one a prefix of the other. That behaviour may not
 
1334
        be useful, so that check may be removed in future.
 
1335
        
1333
1336
        :param other: The branch to bind to
1334
1337
        :type other: Branch
1335
1338
        """
1340
1343
        #       but binding itself may not be.
1341
1344
        #       Since we *have* to check at commit time, we don't
1342
1345
        #       *need* to check here
1343
 
        self.pull(other)
1344
 
 
1345
 
        # we are now equal to or a suffix of other.
1346
 
 
1347
 
        # Since we have 'pulled' from the remote location,
1348
 
        # now we should try to pull in the opposite direction
1349
 
        # in case the local tree has more revisions than the
1350
 
        # remote one.
1351
 
        # There may be a different check you could do here
1352
 
        # rather than actually trying to install revisions remotely.
1353
 
        # TODO: capture an exception which indicates the remote branch
1354
 
        #       is not writable. 
1355
 
        #       If it is up-to-date, this probably should not be a failure
1356
 
        
1357
 
        # lock other for write so the revision-history syncing cannot race
1358
 
        other.lock_write()
1359
 
        try:
1360
 
            other.pull(self)
1361
 
            # if this does not error, other now has the same last rev we do
1362
 
            # it can only error if the pull from other was concurrent with
1363
 
            # a commit to other from someone else.
1364
 
 
1365
 
            # until we ditch revision-history, we need to sync them up:
1366
 
            self.set_revision_history(other.revision_history())
1367
 
            # now other and self are up to date with each other and have the
1368
 
            # same revision-history.
1369
 
        finally:
1370
 
            other.unlock()
1371
 
 
 
1346
 
 
1347
        # we want to raise diverged if:
 
1348
        # last_rev is not in the other_last_rev history, AND
 
1349
        # other_last_rev is not in our history, and do it without pulling
 
1350
        # history around
 
1351
        last_rev = self.last_revision()
 
1352
        if last_rev is not None:
 
1353
            other.lock_read()
 
1354
            try:
 
1355
                other_last_rev = other.last_revision()
 
1356
                if other_last_rev is not None:
 
1357
                    # neither branch is new, we have to do some work to
 
1358
                    # ascertain diversion.
 
1359
                    remote_graph = other.repository.get_revision_graph(
 
1360
                        other_last_rev)
 
1361
                    local_graph = self.repository.get_revision_graph(last_rev)
 
1362
                    if (last_rev not in remote_graph and
 
1363
                        other_last_rev not in local_graph):
 
1364
                        raise errors.DivergedBranches(self, other)
 
1365
            finally:
 
1366
                other.unlock()
1372
1367
        self.set_bound_location(other.base)
1373
1368
 
1374
1369
    @needs_write_lock