/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: Martin Pool
  • Date: 2005-07-11 06:13:18 UTC
  • mfrom: (unknown (missing))
  • Revision ID: mbp@sourcefrog.net-20050711061318-80557a9f045b1f38
- merge john's revision-naming code

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
import sys
19
 
import os
 
18
import sys, os
20
19
 
21
20
import bzrlib
22
21
from bzrlib.trace import mutter, note
23
 
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, \
24
 
     splitpath, \
 
22
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, splitpath, \
25
23
     sha_file, appendpath, file_kind
26
 
from bzrlib.errors import BzrError, InvalidRevisionNumber, InvalidRevisionId
27
 
import bzrlib.errors
28
 
from bzrlib.textui import show_status
29
 
from bzrlib.revision import Revision
30
 
from bzrlib.xml import unpack_xml
31
 
from bzrlib.delta import compare_trees
32
 
from bzrlib.tree import EmptyTree, RevisionTree
33
 
        
 
24
from bzrlib.errors import BzrError
 
25
 
34
26
BZR_BRANCH_FORMAT = "Bazaar-NG branch, format 0.0.4\n"
35
27
## TODO: Maybe include checks for common corruption of newlines, etc?
36
28
 
37
29
 
38
 
# TODO: Some operations like log might retrieve the same revisions
39
 
# repeatedly to calculate deltas.  We could perhaps have a weakref
40
 
# cache in memory to make this faster.
41
 
 
42
30
 
43
31
def find_branch(f, **args):
44
32
    if f and (f.startswith('http://') or f.startswith('https://')):
130
118
        Exception.__init__(self, "These branches have diverged.")
131
119
 
132
120
 
 
121
class NoSuchRevision(BzrError):
 
122
    def __init__(self, branch, revision):
 
123
        self.branch = branch
 
124
        self.revision = revision
 
125
        msg = "Branch %s has no revision %d" % (branch, revision)
 
126
        BzrError.__init__(self, msg)
 
127
 
 
128
 
133
129
######################################################################
134
130
# branch objects
135
131
 
316
312
            self.controlfile(f, 'w').write('')
317
313
        mutter('created control directory in ' + self.base)
318
314
 
319
 
        pack_xml(Inventory(gen_root_id()), self.controlfile('inventory','w'))
 
315
        pack_xml(Inventory(), self.controlfile('inventory','w'))
320
316
 
321
317
 
322
318
    def _check_format(self):
337
333
                           ['use a different bzr version',
338
334
                            'or remove the .bzr directory and "bzr init" again'])
339
335
 
340
 
    def get_root_id(self):
341
 
        """Return the id of this branches root"""
342
 
        inv = self.read_working_inventory()
343
 
        return inv.root.file_id
344
336
 
345
 
    def set_root_id(self, file_id):
346
 
        inv = self.read_working_inventory()
347
 
        orig_root_id = inv.root.file_id
348
 
        del inv._byid[inv.root.file_id]
349
 
        inv.root.file_id = file_id
350
 
        inv._byid[inv.root.file_id] = inv.root
351
 
        for fid in inv:
352
 
            entry = inv[fid]
353
 
            if entry.parent_id in (None, orig_root_id):
354
 
                entry.parent_id = inv.root.file_id
355
 
        self._write_inventory(inv)
356
337
 
357
338
    def read_working_inventory(self):
358
339
        """Read the working inventory."""
365
346
            # ElementTree does its own conversion from UTF-8, so open in
366
347
            # binary.
367
348
            inv = unpack_xml(Inventory,
368
 
                             self.controlfile('inventory', 'rb'))
 
349
                                  self.controlfile('inventory', 'rb'))
369
350
            mutter("loaded inventory of %d items in %f"
370
351
                   % (len(inv), time() - before))
371
352
            return inv
426
407
              add all non-ignored children.  Perhaps do that in a
427
408
              higher-level method.
428
409
        """
 
410
        from bzrlib.textui import show_status
429
411
        # TODO: Re-adding a file that is removed in the working copy
430
412
        # should probably put it back with the previous ID.
431
413
        if isinstance(files, basestring):
504
486
        is the opposite of add.  Removing it is consistent with most
505
487
        other tools.  Maybe an option.
506
488
        """
 
489
        from bzrlib.textui import show_status
507
490
        ## TODO: Normalize names
508
491
        ## TODO: Remove nested loops; better scalability
509
492
        if isinstance(files, basestring):
538
521
    # FIXME: this doesn't need to be a branch method
539
522
    def set_inventory(self, new_inventory_list):
540
523
        from bzrlib.inventory import Inventory, InventoryEntry
541
 
        inv = Inventory(self.get_root_id())
 
524
        inv = Inventory()
542
525
        for path, file_id, parent, kind in new_inventory_list:
543
526
            name = os.path.basename(path)
544
527
            if name == "":
566
549
        return self.working_tree().unknowns()
567
550
 
568
551
 
569
 
    def append_revision(self, *revision_ids):
 
552
    def append_revision(self, revision_id):
570
553
        from bzrlib.atomicfile import AtomicFile
571
554
 
572
 
        for revision_id in revision_ids:
573
 
            mutter("add {%s} to revision-history" % revision_id)
574
 
 
575
 
        rev_history = self.revision_history()
576
 
        rev_history.extend(revision_ids)
 
555
        mutter("add {%s} to revision-history" % revision_id)
 
556
        rev_history = self.revision_history() + [revision_id]
577
557
 
578
558
        f = AtomicFile(self.controlfilename('revision-history'))
579
559
        try:
584
564
            f.close()
585
565
 
586
566
 
587
 
    def get_revision_xml(self, revision_id):
588
 
        """Return XML file object for revision object."""
589
 
        if not revision_id or not isinstance(revision_id, basestring):
590
 
            raise InvalidRevisionId(revision_id)
591
 
 
592
 
        self.lock_read()
593
 
        try:
594
 
            try:
595
 
                return self.revision_store[revision_id]
596
 
            except IndexError:
597
 
                raise bzrlib.errors.NoSuchRevision(revision_id)
598
 
        finally:
599
 
            self.unlock()
600
 
 
601
 
 
602
567
    def get_revision(self, revision_id):
603
568
        """Return the Revision object for a named revision"""
604
 
        xml_file = self.get_revision_xml(revision_id)
 
569
        from bzrlib.revision import Revision
 
570
        from bzrlib.xml import unpack_xml
605
571
 
 
572
        self.lock_read()
606
573
        try:
607
 
            r = unpack_xml(Revision, xml_file)
608
 
        except SyntaxError, e:
609
 
            raise bzrlib.errors.BzrError('failed to unpack revision_xml',
610
 
                                         [revision_id,
611
 
                                          str(e)])
 
574
            if not revision_id or not isinstance(revision_id, basestring):
 
575
                raise ValueError('invalid revision-id: %r' % revision_id)
 
576
            r = unpack_xml(Revision, self.revision_store[revision_id])
 
577
        finally:
 
578
            self.unlock()
612
579
            
613
580
        assert r.revision_id == revision_id
614
581
        return r
615
 
 
616
 
 
617
 
    def get_revision_delta(self, revno):
618
 
        """Return the delta for one revision.
619
 
 
620
 
        The delta is relative to its mainline predecessor, or the
621
 
        empty tree for revision 1.
622
 
        """
623
 
        assert isinstance(revno, int)
624
 
        rh = self.revision_history()
625
 
        if not (1 <= revno <= len(rh)):
626
 
            raise InvalidRevisionNumber(revno)
627
 
 
628
 
        # revno is 1-based; list is 0-based
629
 
 
630
 
        new_tree = self.revision_tree(rh[revno-1])
631
 
        if revno == 1:
632
 
            old_tree = EmptyTree()
633
 
        else:
634
 
            old_tree = self.revision_tree(rh[revno-2])
635
 
 
636
 
        return compare_trees(old_tree, new_tree)
637
 
 
638
582
        
639
583
 
640
584
    def get_revision_sha1(self, revision_id):
645
589
        # the revision, (add signatures/remove signatures) and still
646
590
        # have all hash pointers stay consistent.
647
591
        # But for now, just hash the contents.
648
 
        return bzrlib.osutils.sha_file(self.get_revision_xml(revision_id))
 
592
        return sha_file(self.revision_store[revision_id])
649
593
 
650
594
 
651
595
    def get_inventory(self, inventory_id):
672
616
        # must be the same as its revision, so this is trivial.
673
617
        if revision_id == None:
674
618
            from bzrlib.inventory import Inventory
675
 
            return Inventory(self.get_root_id())
 
619
            return Inventory()
676
620
        else:
677
621
            return self.get_inventory(revision_id)
678
622
 
735
679
                return r+1, my_history[r]
736
680
        return None, None
737
681
 
 
682
    def enum_history(self, direction):
 
683
        """Return (revno, revision_id) for history of branch.
 
684
 
 
685
        direction
 
686
            'forward' is from earliest to latest
 
687
            'reverse' is from latest to earliest
 
688
        """
 
689
        rh = self.revision_history()
 
690
        if direction == 'forward':
 
691
            i = 1
 
692
            for rid in rh:
 
693
                yield i, rid
 
694
                i += 1
 
695
        elif direction == 'reverse':
 
696
            i = len(rh)
 
697
            while i > 0:
 
698
                yield i, rh[i-1]
 
699
                i -= 1
 
700
        else:
 
701
            raise ValueError('invalid history direction', direction)
 
702
 
738
703
 
739
704
    def revno(self):
740
705
        """Return current revision number for this branch.
823
788
        True
824
789
        """
825
790
        from bzrlib.progress import ProgressBar
 
791
        try:
 
792
            set
 
793
        except NameError:
 
794
            from sets import Set as set
826
795
 
827
796
        pb = ProgressBar()
828
797
 
979
948
        elif val.lower() == 'tomorrow':
980
949
            dt = today + datetime.timedelta(days=1)
981
950
        else:
982
 
            import re
983
951
            # This should be done outside the function to avoid recompiling it.
984
952
            _date_re = re.compile(
985
953
                    r'(?P<date>(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d))?'
1035
1003
 
1036
1004
        `revision_id` may be None for the null revision, in which case
1037
1005
        an `EmptyTree` is returned."""
 
1006
        from bzrlib.tree import EmptyTree, RevisionTree
1038
1007
        # TODO: refactor this to use an existing revision object
1039
1008
        # so we don't need to read it in twice.
1040
1009
        if revision_id == None:
1055
1024
 
1056
1025
        If there are no revisions yet, return an `EmptyTree`.
1057
1026
        """
 
1027
        from bzrlib.tree import EmptyTree, RevisionTree
1058
1028
        r = self.last_patch()
1059
1029
        if r == None:
1060
1030
            return EmptyTree()
1380
1350
 
1381
1351
    s = hexlify(rand_bytes(8))
1382
1352
    return '-'.join((name, compact_date(time()), s))
1383
 
 
1384
 
 
1385
 
def gen_root_id():
1386
 
    """Return a new tree-root file id."""
1387
 
    return gen_file_id('TREE_ROOT')
1388