135
135
raise BzrError("invalid locking mode %r" % mode)
138
lockfile = os.open(self.controlfilename('branch-lock'), om)
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)
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.
141
lockfile = os.open(self.controlfilename('branch-lock'), om)
147
142
fcntl.lockf(lockfile, lm)
149
144
fcntl.lockf(lockfile, fcntl.LOCK_UN)
691
686
return [l.rstrip('\r\n') for l in self.controlfile('revision-history', 'r').readlines()]
694
def enum_history(self, direction):
695
"""Return (revno, revision_id) for history of branch.
698
'forward' is from earliest to latest
699
'reverse' is from latest to earliest
701
rh = self.revision_history()
702
if direction == 'forward':
707
elif direction == 'reverse':
713
raise BzrError('invalid history direction %r' % direction)
717
690
"""Return current revision number for this branch.
771
def write_log(self, show_timezone='original', verbose=False):
772
"""Write out human-readable log of commits to this branch
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
779
for p in self.revision_history():
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,
789
## opportunistic consistency check, same as check_patch_chaining
790
if rev.precursor != precursor:
791
bailout("mismatched precursor!")
795
print ' (no message)'
797
for l in rev.message.split('\n'):
800
if verbose == True and precursor != None:
801
print 'changed files:'
802
tree = self.revision_tree(p)
803
prevtree = self.revision_tree(precursor)
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)
798
819
def rename_one(self, from_rel, to_rel):
799
820
"""Rename one file.
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.
912
933
The list is show sorted in order by file name.
937
960
old = self.basis_tree()
938
961
new = self.working_tree()
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]
945
for fs, fid, oldname, newname, kind in items:
963
for fs, fid, oldname, newname, kind in diff_trees(old, new):
947
965
show_status(fs, kind,
948
966
oldname + ' => ' + newname)
992
1010
def __del__(self):
996
1011
"""Destroy the test branch, removing the scratch directory."""
998
mutter("delete ScratchBranch %s" % self.base)
999
1013
shutil.rmtree(self.base)
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)