31
31
joinpath, sha_string, file_kind, local_time_offset, appendpath
32
32
from store import ImmutableStore
33
33
from revision import Revision
34
from errors import bailout, BzrError
34
from errors import bailout
35
35
from textui import show_status
36
36
from diff import diff_trees
300
301
self._write_inventory(inv)
303
def print_file(self, file, revno):
304
"""Print `file` to stdout."""
305
tree = self.revision_tree(self.lookup_revision(revno))
306
# use inventory as it was in that revision
307
file_id = tree.inventory.path2id(file)
309
bailout("%r is not present in revision %d" % (file, revno))
310
tree.print_file(file_id)
313
305
def remove(self, files, verbose=False):
314
306
"""Mark nominated files for removal from the inventory.
555
547
## TODO: Also calculate and store the inventory SHA1
556
548
mutter("committing patch r%d" % (self.revno() + 1))
550
mutter("append to revision-history")
551
f = self.controlfile('revision-history', 'at')
552
f.write(rev_id + '\n')
559
self.append_revision(rev_id)
562
556
note("commited r%d" % self.revno())
565
def append_revision(self, revision_id):
566
mutter("add {%s} to revision-history" % revision_id)
567
rev_history = self.revision_history()
569
tmprhname = self.controlfilename('revision-history.tmp')
570
rhname = self.controlfilename('revision-history')
572
f = file(tmprhname, 'wt')
573
rev_history.append(revision_id)
574
f.write('\n'.join(rev_history))
578
if sys.platform == 'win32':
580
os.rename(tmprhname, rhname)
584
559
def get_revision(self, revision_id):
585
560
"""Return the Revision object for a named revision"""
586
561
r = Revision.read_xml(self.revision_store[revision_id])
732
def rename_one(self, from_rel, to_rel):
733
tree = self.working_tree()
735
if not tree.has_filename(from_rel):
736
bailout("can't rename: old working file %r does not exist" % from_rel)
737
if tree.has_filename(to_rel):
738
bailout("can't rename: new working file %r already exists" % to_rel)
740
file_id = inv.path2id(from_rel)
742
bailout("can't rename: old name %r is not versioned" % from_rel)
744
if inv.path2id(to_rel):
745
bailout("can't rename: new name %r is already versioned" % to_rel)
747
to_dir, to_tail = os.path.split(to_rel)
748
to_dir_id = inv.path2id(to_dir)
749
if to_dir_id == None and to_dir != '':
750
bailout("can't determine destination directory id for %r" % to_dir)
752
mutter("rename_one:")
753
mutter(" file_id {%s}" % file_id)
754
mutter(" from_rel %r" % from_rel)
755
mutter(" to_rel %r" % to_rel)
756
mutter(" to_dir %r" % to_dir)
757
mutter(" to_dir_id {%s}" % to_dir_id)
759
inv.rename(file_id, to_dir_id, to_tail)
761
print "%s => %s" % (from_rel, to_rel)
763
from_abs = self.abspath(from_rel)
764
to_abs = self.abspath(to_rel)
766
os.rename(from_abs, to_abs)
768
bailout("failed to rename %r to %r: %s"
769
% (from_abs, to_abs, e[1]),
770
["rename rolled back"])
772
self._write_inventory(inv)
776
def move(self, from_paths, to_name):
706
def rename(self, from_paths, to_name):
779
to_name must exist as a versioned directory.
781
709
If to_name exists and is a directory, the files are moved into
782
710
it, keeping their old names. If it is a directory,
788
716
assert not isinstance(from_paths, basestring)
789
717
tree = self.working_tree()
790
718
inv = tree.inventory
791
to_abs = self.abspath(to_name)
792
if not isdir(to_abs):
793
bailout("destination %r is not a directory" % to_abs)
794
if not tree.has_filename(to_name):
795
bailout("destination %r not in working directory" % to_abs)
796
to_dir_id = inv.path2id(to_name)
797
if to_dir_id == None and to_name != '':
798
bailout("destination %r is not a versioned directory" % to_name)
799
to_dir_ie = inv[to_dir_id]
800
if to_dir_ie.kind not in ('directory', 'root_directory'):
801
bailout("destination %r is not a directory" % to_abs)
803
to_idpath = Set(inv.get_idpath(to_dir_id))
806
if not tree.has_filename(f):
807
bailout("%r does not exist in working tree" % f)
808
f_id = inv.path2id(f)
810
bailout("%r is not versioned" % f)
811
name_tail = splitpath(f)[-1]
812
dest_path = appendpath(to_name, name_tail)
813
if tree.has_filename(dest_path):
814
bailout("destination %r already exists" % dest_path)
815
if f_id in to_idpath:
816
bailout("can't move %r to a subdirectory of itself" % f)
818
# OK, so there's a race here, it's possible that someone will
819
# create a file in this interval and then the rename might be
820
# left half-done. But we should have caught most problems.
823
name_tail = splitpath(f)[-1]
824
dest_path = appendpath(to_name, name_tail)
825
print "%s => %s" % (f, dest_path)
826
inv.rename(inv.path2id(f), to_dir_id, name_tail)
719
dest_dir = isdir(self.abspath(to_name))
721
# TODO: Wind back properly if some can't be moved?
722
dest_dir_id = inv.path2id(to_name)
723
if not dest_dir_id and to_name != '':
724
bailout("destination %r is not a versioned directory" % to_name)
726
name_tail = splitpath(f)[-1]
727
dest_path = appendpath(to_name, name_tail)
728
print "%s => %s" % (f, dest_path)
729
inv.rename(inv.path2id(f), dest_dir_id, name_tail)
828
730
os.rename(self.abspath(f), self.abspath(dest_path))
830
bailout("failed to rename %r to %r: %s" % (f, dest_path, e[1]),
831
["rename rolled back"])
833
self._write_inventory(inv)
837
def show_status(self, show_all=False):
731
self._write_inventory(inv)
733
if len(from_paths) != 1:
734
bailout("when moving multiple files, destination must be a directory")
735
bailout("rename to non-directory %r not implemented sorry" % to_name)
739
def show_status(branch, show_all=False):
838
740
"""Display single-line status for non-ignored working files.
840
742
The list is show sorted in order by file name.
867
769
# Interesting case: the old ID for a file has been removed,
868
770
# but a new file has been created under that name.
870
old = self.basis_tree()
871
new = self.working_tree()
772
old = branch.basis_tree()
773
old_inv = old.inventory
774
new = branch.working_tree()
775
new_inv = new.inventory
873
777
for fs, fid, oldname, newname, kind in diff_trees(old, new):