~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2005-08-25 09:17:19 UTC
  • Revision ID: mbp@sourcefrog.net-20050825091719-b2d7be7bf56bb35a
- fix a few errors in new merge code

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, \
24
24
     splitpath, \
25
25
     sha_file, appendpath, file_kind
 
26
 
26
27
from bzrlib.errors import BzrError, InvalidRevisionNumber, InvalidRevisionId
27
28
import bzrlib.errors
28
29
from bzrlib.textui import show_status
30
31
from bzrlib.xml import unpack_xml
31
32
from bzrlib.delta import compare_trees
32
33
from bzrlib.tree import EmptyTree, RevisionTree
33
 
        
 
34
import bzrlib.ui
 
35
 
 
36
 
 
37
 
34
38
BZR_BRANCH_FORMAT = "Bazaar-NG branch, format 0.0.4\n"
35
39
## TODO: Maybe include checks for common corruption of newlines, etc?
36
40
 
39
43
# repeatedly to calculate deltas.  We could perhaps have a weakref
40
44
# cache in memory to make this faster.
41
45
 
 
46
# TODO: please move the revision-string syntax stuff out of the branch
 
47
# object; it's clutter
 
48
 
42
49
 
43
50
def find_branch(f, **args):
44
51
    if f and (f.startswith('http://') or f.startswith('https://')):
101
108
    It is not necessary that f exists.
102
109
 
103
110
    Basically we keep looking up until we find the control directory or
104
 
    run into the root."""
 
111
    run into the root.  If there isn't one, raises NotBranchError.
 
112
    """
105
113
    if f == None:
106
114
        f = os.getcwd()
107
115
    elif hasattr(os.path, 'realpath'):
120
128
        head, tail = os.path.split(f)
121
129
        if head == f:
122
130
            # reached the root, whatever that may be
123
 
            raise BzrError('%r is not in a branch' % orig_f)
 
131
            raise bzrlib.errors.NotBranchError('%s is not in a branch' % orig_f)
124
132
        f = head
125
 
    
 
133
 
 
134
 
 
135
 
 
136
# XXX: move into bzrlib.errors; subclass BzrError    
126
137
class DivergedBranches(Exception):
127
138
    def __init__(self, branch1, branch2):
128
139
        self.branch1 = branch1
660
671
        from bzrlib.inventory import Inventory
661
672
        from bzrlib.xml import unpack_xml
662
673
 
663
 
        return unpack_xml(Inventory, self.inventory_store[inventory_id])
 
674
        return unpack_xml(Inventory, self.get_inventory_xml(inventory_id))
 
675
 
 
676
 
 
677
    def get_inventory_xml(self, inventory_id):
 
678
        """Get inventory XML as a file object."""
 
679
        return self.inventory_store[inventory_id]
664
680
            
665
681
 
666
682
    def get_inventory_sha1(self, inventory_id):
667
683
        """Return the sha1 hash of the inventory entry
668
684
        """
669
 
        return sha_file(self.inventory_store[inventory_id])
 
685
        return sha_file(self.get_inventory_xml(inventory_id))
670
686
 
671
687
 
672
688
    def get_revision_inventory(self, revision_id):
758
774
            return None
759
775
 
760
776
 
761
 
    def missing_revisions(self, other, stop_revision=None):
 
777
    def missing_revisions(self, other, stop_revision=None, diverged_ok=False):
762
778
        """
763
779
        If self and other have not diverged, return a list of the revisions
764
780
        present in other, but missing from self.
797
813
        if stop_revision is None:
798
814
            stop_revision = other_len
799
815
        elif stop_revision > other_len:
800
 
            raise NoSuchRevision(self, stop_revision)
 
816
            raise bzrlib.errors.NoSuchRevision(self, stop_revision)
801
817
        
802
818
        return other_history[self_len:stop_revision]
803
819
 
804
820
 
805
821
    def update_revisions(self, other, stop_revision=None):
806
822
        """Pull in all new revisions from other branch.
807
 
        
808
 
        >>> from bzrlib.commit import commit
809
 
        >>> bzrlib.trace.silent = True
810
 
        >>> br1 = ScratchBranch(files=['foo', 'bar'])
811
 
        >>> br1.add('foo')
812
 
        >>> br1.add('bar')
813
 
        >>> commit(br1, "lala!", rev_id="REVISION-ID-1", verbose=False)
814
 
        >>> br2 = ScratchBranch()
815
 
        >>> br2.update_revisions(br1)
816
 
        Added 2 texts.
817
 
        Added 1 inventories.
818
 
        Added 1 revisions.
819
 
        >>> br2.revision_history()
820
 
        [u'REVISION-ID-1']
821
 
        >>> br2.update_revisions(br1)
822
 
        Added 0 texts.
823
 
        Added 0 inventories.
824
 
        Added 0 revisions.
825
 
        >>> br1.text_store.total_size() == br2.text_store.total_size()
826
 
        True
827
823
        """
828
 
        from bzrlib.progress import ProgressBar
829
 
 
830
 
        pb = ProgressBar()
831
 
 
 
824
        from bzrlib.fetch import greedy_fetch
 
825
 
 
826
        pb = bzrlib.ui.ui_factory.progress_bar()
832
827
        pb.update('comparing histories')
 
828
 
833
829
        revision_ids = self.missing_revisions(other, stop_revision)
834
830
 
 
831
        if len(revision_ids) > 0:
 
832
            count = greedy_fetch(self, other, revision_ids[-1], pb)[0]
 
833
        else:
 
834
            count = 0
 
835
        self.append_revision(*revision_ids)
 
836
        ## note("Added %d revisions." % count)
 
837
        pb.clear()
 
838
 
 
839
        
 
840
        
 
841
    def install_revisions(self, other, revision_ids, pb):
835
842
        if hasattr(other.revision_store, "prefetch"):
836
843
            other.revision_store.prefetch(revision_ids)
837
844
        if hasattr(other.inventory_store, "prefetch"):
838
845
            inventory_ids = [other.get_revision(r).inventory_id
839
846
                             for r in revision_ids]
840
847
            other.inventory_store.prefetch(inventory_ids)
 
848
 
 
849
        if pb is None:
 
850
            pb = bzrlib.ui.ui_factory.progress_bar()
841
851
                
842
852
        revisions = []
843
853
        needed_texts = set()
844
854
        i = 0
845
 
        for rev_id in revision_ids:
846
 
            i += 1
847
 
            pb.update('fetching revision', i, len(revision_ids))
848
 
            rev = other.get_revision(rev_id)
 
855
 
 
856
        failures = set()
 
857
        for i, rev_id in enumerate(revision_ids):
 
858
            pb.update('fetching revision', i+1, len(revision_ids))
 
859
            try:
 
860
                rev = other.get_revision(rev_id)
 
861
            except bzrlib.errors.NoSuchRevision:
 
862
                failures.add(rev_id)
 
863
                continue
 
864
 
849
865
            revisions.append(rev)
850
866
            inv = other.get_inventory(str(rev.inventory_id))
851
867
            for key, entry in inv.iter_entries():
856
872
 
857
873
        pb.clear()
858
874
                    
859
 
        count = self.text_store.copy_multi(other.text_store, needed_texts)
860
 
        print "Added %d texts." % count 
 
875
        count, cp_fail = self.text_store.copy_multi(other.text_store, 
 
876
                                                    needed_texts)
 
877
        #print "Added %d texts." % count 
861
878
        inventory_ids = [ f.inventory_id for f in revisions ]
862
 
        count = self.inventory_store.copy_multi(other.inventory_store, 
863
 
                                                inventory_ids)
864
 
        print "Added %d inventories." % count 
 
879
        count, cp_fail = self.inventory_store.copy_multi(other.inventory_store, 
 
880
                                                         inventory_ids)
 
881
        #print "Added %d inventories." % count 
865
882
        revision_ids = [ f.revision_id for f in revisions]
866
 
        count = self.revision_store.copy_multi(other.revision_store, 
867
 
                                               revision_ids)
868
 
        for revision_id in revision_ids:
869
 
            self.append_revision(revision_id)
870
 
        print "Added %d revisions." % count
871
 
                    
872
 
        
 
883
 
 
884
        count, cp_fail = self.revision_store.copy_multi(other.revision_store, 
 
885
                                                          revision_ids,
 
886
                                                          permit_failure=True)
 
887
        assert len(cp_fail) == 0 
 
888
        return count, failures
 
889
       
 
890
 
873
891
    def commit(self, *args, **kw):
874
892
        from bzrlib.commit import commit
875
893
        commit(self, *args, **kw)
880
898
        revno, info = self.get_revision_info(revision)
881
899
        return info
882
900
 
 
901
 
 
902
    def revision_id_to_revno(self, revision_id):
 
903
        """Given a revision id, return its revno"""
 
904
        history = self.revision_history()
 
905
        try:
 
906
            return history.index(revision_id) + 1
 
907
        except ValueError:
 
908
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
 
909
 
 
910
 
883
911
    def get_revision_info(self, revision):
884
912
        """Return (revno, revision id) for revision identifier.
885
913