~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Aaron Bentley
  • Date: 2008-06-06 16:40:46 UTC
  • mfrom: (3482 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3483.
  • Revision ID: aaron@aaronbentley.com-20080606164046-ghbxplxuhtpcb9iz
Merge with bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
425
425
        else:
426
426
            return (0, _mod_revision.NULL_REVISION)
427
427
 
 
428
    @deprecated_method(deprecated_in((1, 6, 0)))
428
429
    def missing_revisions(self, other, stop_revision=None):
429
430
        """Return a list of new revisions that would perfectly fit.
430
431
        
447
448
                raise errors.NoSuchRevision(self, stop_revision)
448
449
        return other_history[self_len:stop_revision]
449
450
 
450
 
    def update_revisions(self, other, stop_revision=None):
 
451
    @needs_write_lock
 
452
    def update_revisions(self, other, stop_revision=None, overwrite=False,
 
453
                         graph=None):
451
454
        """Pull in new perfect-fit revisions.
452
455
 
453
456
        :param other: Another Branch to pull from
454
457
        :param stop_revision: Updated until the given revision
 
458
        :param overwrite: Always set the branch pointer, rather than checking
 
459
            to see if it is a proper descendant.
 
460
        :param graph: A Graph object that can be used to query history
 
461
            information. This can be None.
455
462
        :return: None
456
463
        """
457
 
        raise NotImplementedError(self.update_revisions)
 
464
        other.lock_read()
 
465
        try:
 
466
            other_revno, other_last_revision = other.last_revision_info()
 
467
            stop_revno = None # unknown
 
468
            if stop_revision is None:
 
469
                stop_revision = other_last_revision
 
470
                if _mod_revision.is_null(stop_revision):
 
471
                    # if there are no commits, we're done.
 
472
                    return
 
473
                stop_revno = other_revno
 
474
 
 
475
            # what's the current last revision, before we fetch [and change it
 
476
            # possibly]
 
477
            last_rev = _mod_revision.ensure_null(self.last_revision())
 
478
            # we fetch here so that we don't process data twice in the common
 
479
            # case of having something to pull, and so that the check for 
 
480
            # already merged can operate on the just fetched graph, which will
 
481
            # be cached in memory.
 
482
            self.fetch(other, stop_revision)
 
483
            # Check to see if one is an ancestor of the other
 
484
            if not overwrite:
 
485
                if graph is None:
 
486
                    graph = self.repository.get_graph()
 
487
                heads = graph.heads([stop_revision, last_rev])
 
488
                if heads == set([last_rev]):
 
489
                    # The current revision is a decendent of the target,
 
490
                    # nothing to do
 
491
                    return
 
492
                elif heads == set([stop_revision, last_rev]):
 
493
                    # These branches have diverged
 
494
                    raise errors.DivergedBranches(self, other)
 
495
                elif heads != set([stop_revision]):
 
496
                    raise AssertionError("invalid heads: %r" % heads)
 
497
            if stop_revno is None:
 
498
                if graph is None:
 
499
                    graph = self.repository.get_graph()
 
500
                this_revno, this_last_revision = self.last_revision_info()
 
501
                stop_revno = graph.find_distance_to_null(stop_revision,
 
502
                                [(other_last_revision, other_revno),
 
503
                                 (this_last_revision, this_revno)])
 
504
            self.set_last_revision_info(stop_revno, stop_revision)
 
505
        finally:
 
506
            other.unlock()
 
507
 
 
508
 
458
509
 
459
510
    def revision_id_to_revno(self, revision_id):
460
511
        """Given a revision id, return its revno"""
913
964
            for (filename, content) in utf8_files:
914
965
                branch_transport.put_bytes(
915
966
                    filename, content,
916
 
                    mode=control_files._file_mode)
 
967
                    mode=a_bzrdir._get_file_mode())
917
968
        finally:
918
969
            control_files.unlock()
919
970
        return self.open(a_bzrdir, _found=True)
1407
1458
        It is intended to be called by BzrBranch5.set_revision_history."""
1408
1459
        self._transport.put_bytes(
1409
1460
            'revision-history', '\n'.join(history),
1410
 
            mode=self.control_files._file_mode)
 
1461
            mode=self.bzrdir._get_file_mode())
1411
1462
 
1412
1463
    @needs_write_lock
1413
1464
    def set_revision_history(self, rev_history):
1500
1551
        self.set_revision_history(self._lefthand_history(revision_id,
1501
1552
            last_rev, other_branch))
1502
1553
 
1503
 
    @needs_write_lock
1504
 
    def update_revisions(self, other, stop_revision=None, overwrite=False):
1505
 
        """See Branch.update_revisions."""
1506
 
        other.lock_read()
1507
 
        try:
1508
 
            other_last_revno, other_last_revision = other.last_revision_info()
1509
 
            if stop_revision is None:
1510
 
                stop_revision = other_last_revision
1511
 
                if _mod_revision.is_null(stop_revision):
1512
 
                    # if there are no commits, we're done.
1513
 
                    return
1514
 
            # whats the current last revision, before we fetch [and change it
1515
 
            # possibly]
1516
 
            last_rev = _mod_revision.ensure_null(self.last_revision())
1517
 
            # we fetch here so that we don't process data twice in the common
1518
 
            # case of having something to pull, and so that the check for 
1519
 
            # already merged can operate on the just fetched graph, which will
1520
 
            # be cached in memory.
1521
 
            self.fetch(other, stop_revision)
1522
 
            # Check to see if one is an ancestor of the other
1523
 
            if not overwrite:
1524
 
                heads = self.repository.get_graph().heads([stop_revision,
1525
 
                                                           last_rev])
1526
 
                if heads == set([last_rev]):
1527
 
                    # The current revision is a decendent of the target,
1528
 
                    # nothing to do
1529
 
                    return
1530
 
                elif heads == set([stop_revision, last_rev]):
1531
 
                    # These branches have diverged
1532
 
                    raise errors.DivergedBranches(self, other)
1533
 
                elif heads != set([stop_revision]):
1534
 
                    raise AssertionError("invalid heads: %r" % heads)
1535
 
            if other_last_revision == stop_revision:
1536
 
                self.set_last_revision_info(other_last_revno,
1537
 
                                            other_last_revision)
1538
 
            else:
1539
 
                # TODO: jam 2007-11-29 Is there a way to determine the
1540
 
                #       revno without searching all of history??
1541
 
                if overwrite:
1542
 
                    self.generate_revision_history(stop_revision)
1543
 
                else:
1544
 
                    self.generate_revision_history(stop_revision,
1545
 
                        last_rev=last_rev, other_branch=other)
1546
 
        finally:
1547
 
            other.unlock()
1548
 
 
1549
1554
    def basis_tree(self):
1550
1555
        """See Branch.basis_tree."""
1551
1556
        return self.repository.revision_tree(self.last_revision())
1566
1571
        result.target_branch = self
1567
1572
        source.lock_read()
1568
1573
        try:
 
1574
            # We assume that during 'pull' the local repository is closer than
 
1575
            # the remote one.
 
1576
            graph = self.repository.get_graph(source.repository)
1569
1577
            result.old_revno, result.old_revid = self.last_revision_info()
1570
 
            self.update_revisions(source, stop_revision, overwrite=overwrite)
 
1578
            self.update_revisions(source, stop_revision, overwrite=overwrite,
 
1579
                                  graph=graph)
1571
1580
            result.tag_conflicts = source.tags.merge_to(self.tags, overwrite)
1572
1581
            result.new_revno, result.new_revid = self.last_revision_info()
1573
1582
            if _hook_master:
1670
1679
        result.source_branch = self
1671
1680
        result.target_branch = target
1672
1681
        result.old_revno, result.old_revid = target.last_revision_info()
1673
 
        target.update_revisions(self, stop_revision, overwrite)
 
1682
 
 
1683
        # We assume that during 'push' this repository is closer than
 
1684
        # the target.
 
1685
        graph = self.repository.get_graph(target.repository)
 
1686
        target.update_revisions(self, stop_revision, overwrite=overwrite,
 
1687
                                graph=graph)
1674
1688
        result.tag_conflicts = self.tags.merge_to(target.tags, overwrite)
1675
1689
        result.new_revno, result.new_revid = target.last_revision_info()
1676
1690
        return result
1718
1732
            self._transport.delete('parent')
1719
1733
        else:
1720
1734
            self._transport.put_bytes('parent', url + '\n',
1721
 
                mode=self.control_files._file_mode)
 
1735
                mode=self.bzrdir._get_file_mode())
1722
1736
 
1723
1737
 
1724
1738
class BzrBranch5(BzrBranch):
1897
1911
        revision_id = _mod_revision.ensure_null(revision_id)
1898
1912
        out_string = '%d %s\n' % (revno, revision_id)
1899
1913
        self._transport.put_bytes('last-revision', out_string,
1900
 
            mode=self.control_files._file_mode)
 
1914
            mode=self.bzrdir._get_file_mode())
1901
1915
 
1902
1916
    @needs_write_lock
1903
1917
    def set_last_revision_info(self, revno, revision_id):
2208
2222
        # Copying done; now update target format
2209
2223
        new_branch._transport.put_bytes('format',
2210
2224
            format.get_format_string(),
2211
 
            mode=new_branch.control_files._file_mode)
 
2225
            mode=new_branch.bzrdir._get_file_mode())
2212
2226
 
2213
2227
        # Clean up old files
2214
2228
        new_branch._transport.delete('revision-history')