~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2005-05-05 06:38:18 UTC
  • Revision ID: mbp@sourcefrog.net-20050505063818-3eb3260343878325
- do upload CHANGELOG to web server, even though it's autogenerated

Show diffs side-by-side

added added

removed removed

Lines of Context:
123
123
    def lock(self, mode='w'):
124
124
        """Lock the on-disk branch, excluding other processes."""
125
125
        try:
126
 
            import fcntl, errno
 
126
            import fcntl
127
127
 
128
128
            if mode == 'w':
129
129
                lm = fcntl.LOCK_EX
134
134
            else:
135
135
                raise BzrError("invalid locking mode %r" % mode)
136
136
 
137
 
            try:
138
 
                lockfile = os.open(self.controlfilename('branch-lock'), om)
139
 
            except OSError, e:
140
 
                if e.errno == errno.ENOENT:
141
 
                    # might not exist on branches from <0.0.4
142
 
                    self.controlfile('branch-lock', 'w').close()
143
 
                    lockfile = os.open(self.controlfilename('branch-lock'), om)
144
 
                else:
145
 
                    raise e
146
 
            
 
137
            # XXX: Old branches might not have the lock file, and
 
138
            # won't get one until someone does a write-mode command on
 
139
            # them or creates it by hand.
 
140
 
 
141
            lockfile = os.open(self.controlfilename('branch-lock'), om)
147
142
            fcntl.lockf(lockfile, lm)
148
143
            def unlock():
149
144
                fcntl.lockf(lockfile, fcntl.LOCK_UN)
691
686
        return [l.rstrip('\r\n') for l in self.controlfile('revision-history', 'r').readlines()]
692
687
 
693
688
 
694
 
    def enum_history(self, direction):
695
 
        """Return (revno, revision_id) for history of branch.
696
 
 
697
 
        direction
698
 
            'forward' is from earliest to latest
699
 
            'reverse' is from latest to earliest
700
 
        """
701
 
        rh = self.revision_history()
702
 
        if direction == 'forward':
703
 
            i = 1
704
 
            for rid in rh:
705
 
                yield i, rid
706
 
                i += 1
707
 
        elif direction == 'reverse':
708
 
            i = len(rh)
709
 
            while i > 0:
710
 
                yield i, rh[i-1]
711
 
                i -= 1
712
 
        else:
713
 
            raise BzrError('invalid history direction %r' % direction)
714
 
 
715
 
 
716
689
    def revno(self):
717
690
        """Return current revision number for this branch.
718
691
 
795
768
 
796
769
 
797
770
 
 
771
    def write_log(self, show_timezone='original', verbose=False):
 
772
        """Write out human-readable log of commits to this branch
 
773
 
 
774
        utc -- If true, show dates in universal time, not local time."""
 
775
        self._need_readlock()
 
776
        ## TODO: Option to choose either original, utc or local timezone
 
777
        revno = 1
 
778
        precursor = None
 
779
        for p in self.revision_history():
 
780
            print '-' * 40
 
781
            print 'revno:', revno
 
782
            ## TODO: Show hash if --id is given.
 
783
            ##print 'revision-hash:', p
 
784
            rev = self.get_revision(p)
 
785
            print 'committer:', rev.committer
 
786
            print 'timestamp: %s' % (format_date(rev.timestamp, rev.timezone or 0,
 
787
                                                 show_timezone))
 
788
 
 
789
            ## opportunistic consistency check, same as check_patch_chaining
 
790
            if rev.precursor != precursor:
 
791
                bailout("mismatched precursor!")
 
792
 
 
793
            print 'message:'
 
794
            if not rev.message:
 
795
                print '  (no message)'
 
796
            else:
 
797
                for l in rev.message.split('\n'):
 
798
                    print '  ' + l
 
799
 
 
800
            if verbose == True and precursor != None:
 
801
                print 'changed files:'
 
802
                tree = self.revision_tree(p)
 
803
                prevtree = self.revision_tree(precursor)
 
804
                
 
805
                for file_state, fid, old_name, new_name, kind in \
 
806
                                        diff_trees(prevtree, tree, ):
 
807
                    if file_state == 'A' or file_state == 'M':
 
808
                        show_status(file_state, kind, new_name)
 
809
                    elif file_state == 'D':
 
810
                        show_status(file_state, kind, old_name)
 
811
                    elif file_state == 'R':
 
812
                        show_status(file_state, kind,
 
813
                            old_name + ' => ' + new_name)
 
814
                
 
815
            revno += 1
 
816
            precursor = p
 
817
 
 
818
 
798
819
    def rename_one(self, from_rel, to_rel):
799
820
        """Rename one file.
800
821
 
906
927
 
907
928
 
908
929
 
909
 
    def show_status(self, show_all=False, file_list=None):
 
930
    def show_status(self, show_all=False):
910
931
        """Display single-line status for non-ignored working files.
911
932
 
912
933
        The list is show sorted in order by file name.
922
943
        >>> os.unlink(b.abspath('foo'))
923
944
        >>> b.show_status()
924
945
        D       foo
 
946
        
 
947
        TODO: Get state for single files.
925
948
        """
926
949
        self._need_readlock()
927
950
 
937
960
        old = self.basis_tree()
938
961
        new = self.working_tree()
939
962
 
940
 
        items = diff_trees(old, new)
941
 
        # We want to filter out only if any file was provided in the file_list.
942
 
        if isinstance(file_list, list) and len(file_list):
943
 
            items = [item for item in items if item[3] in file_list]
944
 
 
945
 
        for fs, fid, oldname, newname, kind in items:
 
963
        for fs, fid, oldname, newname, kind in diff_trees(old, new):
946
964
            if fs == 'R':
947
965
                show_status(fs, kind,
948
966
                            oldname + ' => ' + newname)
970
988
    >>> isdir(b.base)
971
989
    True
972
990
    >>> bd = b.base
973
 
    >>> b.destroy()
 
991
    >>> del b
974
992
    >>> isdir(bd)
975
993
    False
976
994
    """
990
1008
 
991
1009
 
992
1010
    def __del__(self):
993
 
        self.destroy()
994
 
 
995
 
    def destroy(self):
996
1011
        """Destroy the test branch, removing the scratch directory."""
997
1012
        try:
998
 
            mutter("delete ScratchBranch %s" % self.base)
999
1013
            shutil.rmtree(self.base)
1000
 
        except OSError, e:
 
1014
        except OSError:
1001
1015
            # Work around for shutil.rmtree failing on Windows when
1002
1016
            # readonly files are encountered
1003
 
            mutter("hit exception in destroying ScratchBranch: %s" % e)
1004
1017
            for root, dirs, files in os.walk(self.base, topdown=False):
1005
1018
                for name in files:
1006
1019
                    os.chmod(os.path.join(root, name), 0700)
1007
1020
            shutil.rmtree(self.base)
1008
 
        self.base = None
1009
1021
 
1010
1022
    
1011
1023