/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Robert Collins
  • Date: 2005-08-25 07:48:27 UTC
  • mto: (974.1.50) (1185.1.10) (1092.3.1)
  • mto: This revision was merged to the branch mainline in revision 1139.
  • Revision ID: robertc@robertcollins.net-20050825074826-dfdf6cecb8020b93
unbreak weavebench

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
208
219
            self._lock.unlock()
209
220
 
210
221
 
211
 
 
212
222
    def lock_write(self):
213
223
        if self._lock_mode:
214
224
            if self._lock_mode != 'w':
224
234
            self._lock_count = 1
225
235
 
226
236
 
227
 
 
228
237
    def lock_read(self):
229
238
        if self._lock_mode:
230
239
            assert self._lock_mode in ('r', 'w'), \
237
246
            self._lock_mode = 'r'
238
247
            self._lock_count = 1
239
248
                        
240
 
 
241
 
            
242
249
    def unlock(self):
243
250
        if not self._lock_mode:
244
251
            from errors import LockError
251
258
            self._lock = None
252
259
            self._lock_mode = self._lock_count = None
253
260
 
254
 
 
255
261
    def abspath(self, name):
256
262
        """Return absolute filename for something in the branch"""
257
263
        return os.path.join(self.base, name)
258
264
 
259
 
 
260
265
    def relpath(self, path):
261
266
        """Return path relative to this branch of something inside it.
262
267
 
263
268
        Raises an error if path is not in this branch."""
264
269
        return _relpath(self.base, path)
265
270
 
266
 
 
267
271
    def controlfilename(self, file_or_path):
268
272
        """Return location relative to branch."""
269
273
        if isinstance(file_or_path, basestring):
296
300
        else:
297
301
            raise BzrError("invalid controlfile mode %r" % mode)
298
302
 
299
 
 
300
 
 
301
303
    def _make_control(self):
302
304
        from bzrlib.inventory import Inventory
303
305
        from bzrlib.xml import pack_xml
316
318
            self.controlfile(f, 'w').write('')
317
319
        mutter('created control directory in ' + self.base)
318
320
 
319
 
        pack_xml(Inventory(gen_root_id()), self.controlfile('inventory','w'))
320
 
 
 
321
        # if we want per-tree root ids then this is the place to set
 
322
        # them; they're not needed for now and so ommitted for
 
323
        # simplicity.
 
324
        pack_xml(Inventory(), self.controlfile('inventory','w'))
321
325
 
322
326
    def _check_format(self):
323
327
        """Check this branch format is supported.
594
598
            try:
595
599
                return self.revision_store[revision_id]
596
600
            except IndexError:
597
 
                raise bzrlib.errors.NoSuchRevision(revision_id)
 
601
                raise bzrlib.errors.NoSuchRevision(self, revision_id)
598
602
        finally:
599
603
            self.unlock()
600
604
 
657
661
        from bzrlib.inventory import Inventory
658
662
        from bzrlib.xml import unpack_xml
659
663
 
660
 
        return unpack_xml(Inventory, self.inventory_store[inventory_id])
 
664
        return unpack_xml(Inventory, self.get_inventory_xml(inventory_id))
 
665
 
 
666
 
 
667
    def get_inventory_xml(self, inventory_id):
 
668
        """Get inventory XML as a file object."""
 
669
        return self.inventory_store[inventory_id]
661
670
            
662
671
 
663
672
    def get_inventory_sha1(self, inventory_id):
664
673
        """Return the sha1 hash of the inventory entry
665
674
        """
666
 
        return sha_file(self.inventory_store[inventory_id])
 
675
        return sha_file(self.get_inventory_xml(inventory_id))
667
676
 
668
677
 
669
678
    def get_revision_inventory(self, revision_id):
755
764
            return None
756
765
 
757
766
 
758
 
    def missing_revisions(self, other, stop_revision=None):
 
767
    def missing_revisions(self, other, stop_revision=None, diverged_ok=False):
759
768
        """
760
769
        If self and other have not diverged, return a list of the revisions
761
770
        present in other, but missing from self.
794
803
        if stop_revision is None:
795
804
            stop_revision = other_len
796
805
        elif stop_revision > other_len:
797
 
            raise NoSuchRevision(self, stop_revision)
 
806
            raise bzrlib.errors.NoSuchRevision(self, stop_revision)
798
807
        
799
808
        return other_history[self_len:stop_revision]
800
809
 
801
810
 
802
811
    def update_revisions(self, other, stop_revision=None):
803
812
        """Pull in all new revisions from other branch.
804
 
        
805
 
        >>> from bzrlib.commit import commit
806
 
        >>> bzrlib.trace.silent = True
807
 
        >>> br1 = ScratchBranch(files=['foo', 'bar'])
808
 
        >>> br1.add('foo')
809
 
        >>> br1.add('bar')
810
 
        >>> commit(br1, "lala!", rev_id="REVISION-ID-1", verbose=False)
811
 
        >>> br2 = ScratchBranch()
812
 
        >>> br2.update_revisions(br1)
813
 
        Added 2 texts.
814
 
        Added 1 inventories.
815
 
        Added 1 revisions.
816
 
        >>> br2.revision_history()
817
 
        [u'REVISION-ID-1']
818
 
        >>> br2.update_revisions(br1)
819
 
        Added 0 texts.
820
 
        Added 0 inventories.
821
 
        Added 0 revisions.
822
 
        >>> br1.text_store.total_size() == br2.text_store.total_size()
823
 
        True
824
813
        """
825
 
        from bzrlib.progress import ProgressBar
826
 
 
827
 
        pb = ProgressBar()
828
 
 
 
814
        from bzrlib.fetch import greedy_fetch
 
815
 
 
816
        pb = bzrlib.ui.ui_factory.progress_bar()
829
817
        pb.update('comparing histories')
 
818
 
830
819
        revision_ids = self.missing_revisions(other, stop_revision)
831
820
 
 
821
        if len(revision_ids) > 0:
 
822
            count = greedy_fetch(self, other, revision_ids[-1], pb)[0]
 
823
        else:
 
824
            count = 0
 
825
        self.append_revision(*revision_ids)
 
826
        ## note("Added %d revisions." % count)
 
827
 
 
828
        
 
829
    def install_revisions(self, other, revision_ids, pb):
832
830
        if hasattr(other.revision_store, "prefetch"):
833
831
            other.revision_store.prefetch(revision_ids)
834
832
        if hasattr(other.inventory_store, "prefetch"):
835
833
            inventory_ids = [other.get_revision(r).inventory_id
836
834
                             for r in revision_ids]
837
835
            other.inventory_store.prefetch(inventory_ids)
 
836
 
 
837
        if pb is None:
 
838
            pb = bzrlib.ui.ui_factory.progress_bar()
838
839
                
839
840
        revisions = []
840
841
        needed_texts = set()
841
842
        i = 0
842
 
        for rev_id in revision_ids:
843
 
            i += 1
844
 
            pb.update('fetching revision', i, len(revision_ids))
845
 
            rev = other.get_revision(rev_id)
 
843
 
 
844
        failures = set()
 
845
        for i, rev_id in enumerate(revision_ids):
 
846
            pb.update('fetching revision', i+1, len(revision_ids))
 
847
            try:
 
848
                rev = other.get_revision(rev_id)
 
849
            except bzrlib.errors.NoSuchRevision:
 
850
                failures.add(rev_id)
 
851
                continue
 
852
 
846
853
            revisions.append(rev)
847
854
            inv = other.get_inventory(str(rev.inventory_id))
848
855
            for key, entry in inv.iter_entries():
853
860
 
854
861
        pb.clear()
855
862
                    
856
 
        count = self.text_store.copy_multi(other.text_store, needed_texts)
 
863
        count, cp_fail = self.text_store.copy_multi(other.text_store, 
 
864
                                                    needed_texts)
857
865
        print "Added %d texts." % count 
858
866
        inventory_ids = [ f.inventory_id for f in revisions ]
859
 
        count = self.inventory_store.copy_multi(other.inventory_store, 
860
 
                                                inventory_ids)
 
867
        count, cp_fail = self.inventory_store.copy_multi(other.inventory_store, 
 
868
                                                         inventory_ids)
861
869
        print "Added %d inventories." % count 
862
870
        revision_ids = [ f.revision_id for f in revisions]
863
 
        count = self.revision_store.copy_multi(other.revision_store, 
864
 
                                               revision_ids)
865
 
        for revision_id in revision_ids:
866
 
            self.append_revision(revision_id)
867
 
        print "Added %d revisions." % count
868
 
                    
869
 
        
 
871
 
 
872
        count, cp_fail = self.revision_store.copy_multi(other.revision_store, 
 
873
                                                          revision_ids,
 
874
                                                          permit_failure=True)
 
875
        assert len(cp_fail) == 0 
 
876
        return count, failures
 
877
       
 
878
 
870
879
    def commit(self, *args, **kw):
871
880
        from bzrlib.commit import commit
872
881
        commit(self, *args, **kw)
877
886
        revno, info = self.get_revision_info(revision)
878
887
        return info
879
888
 
 
889
 
 
890
    def revision_id_to_revno(self, revision_id):
 
891
        """Given a revision id, return its revno"""
 
892
        history = self.revision_history()
 
893
        try:
 
894
            return history.index(revision_id) + 1
 
895
        except ValueError:
 
896
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
 
897
 
 
898
 
880
899
    def get_revision_info(self, revision):
881
900
        """Return (revno, revision id) for revision identifier.
882
901
 
1386
1405
    """Return a new tree-root file id."""
1387
1406
    return gen_file_id('TREE_ROOT')
1388
1407
 
 
1408
 
 
1409
def pull_loc(branch):
 
1410
    # TODO: Should perhaps just make attribute be 'base' in
 
1411
    # RemoteBranch and Branch?
 
1412
    if hasattr(branch, "baseurl"):
 
1413
        return branch.baseurl
 
1414
    else:
 
1415
        return branch.base
 
1416
 
 
1417
 
 
1418
def copy_branch(branch_from, to_location, revision=None):
 
1419
    """Copy branch_from into the existing directory to_location.
 
1420
 
 
1421
    If revision is not None, the head of the new branch will be revision.
 
1422
    """
 
1423
    from bzrlib.merge import merge
 
1424
    from bzrlib.branch import Branch
 
1425
    br_to = Branch(to_location, init=True)
 
1426
    br_to.set_root_id(branch_from.get_root_id())
 
1427
    if revision is None:
 
1428
        revno = branch_from.revno()
 
1429
    else:
 
1430
        revno, rev_id = branch_from.get_revision_info(revision)
 
1431
    br_to.update_revisions(branch_from, stop_revision=revno)
 
1432
    merge((to_location, -1), (to_location, 0), this_dir=to_location,
 
1433
          check_clean=False, ignore_zero=True)
 
1434
    from_location = pull_loc(branch_from)
 
1435
    br_to.controlfile("x-pull", "wb").write(from_location + "\n")
 
1436