~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-06 05:53:44 UTC
  • mfrom: (2063 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061006055344-e73b97b7c6ca6e72
[merge] bzr.dev 2063

Show diffs side-by-side

added added

removed removed

Lines of Context:
299
299
 
300
300
    def revision_history(self):
301
301
        """Return sequence of revision hashes on to this branch."""
302
 
        raise NotImplementedError('revision_history is abstract')
 
302
        raise NotImplementedError(self.revision_history)
303
303
 
304
304
    def revno(self):
305
305
        """Return current revision number for this branch.
586
586
            mainline_parent_id = revision_id
587
587
        return BranchCheckResult(self)
588
588
 
 
589
    def _get_checkout_format(self):
 
590
        """Return the most suitable metadir for a checkout of this branch.
 
591
        Weaves are used if this branch's repostory uses weaves.
 
592
        """
 
593
        if isinstance(self.bzrdir, bzrdir.BzrDirPreSplitOut):
 
594
            from bzrlib import repository
 
595
            format = bzrdir.BzrDirMetaFormat1()
 
596
            format.repository_format = repository.RepositoryFormat7()
 
597
        else:
 
598
            format = self.repository.bzrdir.cloning_metadir()
 
599
        return format
 
600
 
589
601
    def create_checkout(self, to_location, revision_id=None, 
590
602
                        lightweight=False):
591
603
        """Create a checkout of a branch.
596
608
        produce a bound branch (heavyweight checkout)
597
609
        :return: The tree of the created checkout
598
610
        """
 
611
        t = transport.get_transport(to_location)
 
612
        try:
 
613
            t.mkdir('.')
 
614
        except errors.FileExists:
 
615
            pass
599
616
        if lightweight:
600
 
            t = transport.get_transport(to_location)
601
 
            try:
602
 
                t.mkdir('.')
603
 
            except errors.FileExists:
604
 
                pass
605
617
            checkout = bzrdir.BzrDirMetaFormat1().initialize_on_transport(t)
606
618
            BranchReferenceFormat().initialize(checkout, self)
607
619
        else:
 
620
            format = self._get_checkout_format()
608
621
            checkout_branch = bzrdir.BzrDir.create_branch_convenience(
609
 
                to_location, force_new_tree=False)
 
622
                to_location, force_new_tree=False, format=format)
610
623
            checkout = checkout_branch.bzrdir
611
624
            checkout_branch.bind(self)
612
 
            if revision_id is not None:
613
 
                rh = checkout_branch.revision_history()
614
 
                new_rh = rh[:rh.index(revision_id) + 1]
615
 
                checkout_branch.set_revision_history(new_rh)
 
625
            # pull up to the specified revision_id to set the initial 
 
626
            # branch tip correctly, and seed it with history.
 
627
            checkout_branch.pull(self, stop_revision=revision_id)
616
628
        return checkout.create_workingtree(revision_id)
617
629
 
618
630
 
1180
1192
        try:
1181
1193
            old_count = len(self.revision_history())
1182
1194
            try:
1183
 
                self.update_revisions(source,stop_revision)
 
1195
                self.update_revisions(source, stop_revision)
1184
1196
            except DivergedBranches:
1185
1197
                if not overwrite:
1186
1198
                    raise
1321
1333
 
1322
1334
    @needs_write_lock
1323
1335
    def bind(self, other):
1324
 
        """Bind the local branch the other branch.
 
1336
        """Bind this branch to the branch other.
1325
1337
 
 
1338
        This does not push or pull data between the branches, though it does
 
1339
        check for divergence to raise an error when the branches are not
 
1340
        either the same, or one a prefix of the other. That behaviour may not
 
1341
        be useful, so that check may be removed in future.
 
1342
        
1326
1343
        :param other: The branch to bind to
1327
1344
        :type other: Branch
1328
1345
        """
1333
1350
        #       but binding itself may not be.
1334
1351
        #       Since we *have* to check at commit time, we don't
1335
1352
        #       *need* to check here
1336
 
        self.pull(other)
1337
 
 
1338
 
        # we are now equal to or a suffix of other.
1339
 
 
1340
 
        # Since we have 'pulled' from the remote location,
1341
 
        # now we should try to pull in the opposite direction
1342
 
        # in case the local tree has more revisions than the
1343
 
        # remote one.
1344
 
        # There may be a different check you could do here
1345
 
        # rather than actually trying to install revisions remotely.
1346
 
        # TODO: capture an exception which indicates the remote branch
1347
 
        #       is not writable. 
1348
 
        #       If it is up-to-date, this probably should not be a failure
1349
 
        
1350
 
        # lock other for write so the revision-history syncing cannot race
1351
 
        other.lock_write()
1352
 
        try:
1353
 
            other.pull(self)
1354
 
            # if this does not error, other now has the same last rev we do
1355
 
            # it can only error if the pull from other was concurrent with
1356
 
            # a commit to other from someone else.
1357
 
 
1358
 
            # until we ditch revision-history, we need to sync them up:
1359
 
            self.set_revision_history(other.revision_history())
1360
 
            # now other and self are up to date with each other and have the
1361
 
            # same revision-history.
1362
 
        finally:
1363
 
            other.unlock()
1364
 
 
 
1353
 
 
1354
        # we want to raise diverged if:
 
1355
        # last_rev is not in the other_last_rev history, AND
 
1356
        # other_last_rev is not in our history, and do it without pulling
 
1357
        # history around
 
1358
        last_rev = self.last_revision()
 
1359
        if last_rev is not None:
 
1360
            other.lock_read()
 
1361
            try:
 
1362
                other_last_rev = other.last_revision()
 
1363
                if other_last_rev is not None:
 
1364
                    # neither branch is new, we have to do some work to
 
1365
                    # ascertain diversion.
 
1366
                    remote_graph = other.repository.get_revision_graph(
 
1367
                        other_last_rev)
 
1368
                    local_graph = self.repository.get_revision_graph(last_rev)
 
1369
                    if (last_rev not in remote_graph and
 
1370
                        other_last_rev not in local_graph):
 
1371
                        raise errors.DivergedBranches(self, other)
 
1372
            finally:
 
1373
                other.unlock()
1365
1374
        self.set_bound_location(other.base)
1366
1375
 
1367
1376
    @needs_write_lock