38
37
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
39
ReusingTransform, CantMoveRoot,
38
ReusingTransform, NotVersionedError, CantMoveRoot,
40
39
ExistingLimbo, ImmortalLimbo, NoFinalPath,
41
40
UnableCreateSymlink)
42
41
from bzrlib.filters import filtered_output_bytes, ContentFilterContext
929
928
return _PreviewTree(self)
931
def commit(self, branch, message, merge_parents=None, strict=False,
932
timestamp=None, timezone=None, committer=None, authors=None,
933
revprops=None, revision_id=None):
930
def commit(self, branch, message, merge_parents=None, strict=False):
934
931
"""Commit the result of this TreeTransform to a branch.
936
933
:param branch: The branch to commit to.
937
934
:param message: The message to attach to the commit.
938
:param merge_parents: Additional parent revision-ids specified by
940
:param strict: If True, abort the commit if there are unversioned
942
:param timestamp: if not None, seconds-since-epoch for the time and
943
date. (May be a float.)
944
:param timezone: Optional timezone for timestamp, as an offset in
946
:param committer: Optional committer in email-id format.
947
(e.g. "J Random Hacker <jrandom@example.com>")
948
:param authors: Optional list of authors in email-id format.
949
:param revprops: Optional dictionary of revision properties.
950
:param revision_id: Optional revision id. (Specifying a revision-id
951
may reduce performance for some non-native formats.)
935
:param merge_parents: Additional parents specified by pending merges.
952
936
:return: The revision_id of the revision committed.
954
938
self._check_malformed()
971
955
if self._tree.get_revision_id() != last_rev_id:
972
956
raise ValueError('TreeTransform not based on branch basis: %s' %
973
957
self._tree.get_revision_id())
974
revprops = commit.Commit.update_revprops(revprops, branch, authors)
975
builder = branch.get_commit_builder(parent_ids,
980
revision_id=revision_id)
958
builder = branch.get_commit_builder(parent_ids)
981
959
preview = self.get_preview_tree()
982
960
list(builder.record_iter_changes(preview, last_rev_id,
983
961
self.iter_changes()))
1182
1160
if trans_id not in self._new_contents:
1184
1162
new_path = self._limbo_name(trans_id)
1185
osutils.rename(old_path, new_path)
1163
os.rename(old_path, new_path)
1186
1164
for descendant in self._limbo_descendants(trans_id):
1187
1165
desc_path = self._limbo_files[descendant]
1188
1166
desc_path = new_path + desc_path[len(old_path):]
1657
1635
or trans_id in self._new_parent):
1659
1637
mover.rename(full_path, self._limbo_name(trans_id))
1660
except errors.TransformRenameFailed, e:
1661
1639
if e.errno != errno.ENOENT:
1688
1666
if trans_id in self._needs_rename:
1690
1668
mover.rename(self._limbo_name(trans_id), full_path)
1691
except errors.TransformRenameFailed, e:
1692
1670
# We may be renaming a dangling inventory id
1693
1671
if e.errno != errno.ENOENT:
1792
1770
parent_keys = [(file_id, self._file_revision(t, file_id)) for t in
1793
1771
self._iter_parent_trees()]
1794
1772
vf.add_lines((file_id, tree_revision), parent_keys,
1795
self.get_file_lines(file_id))
1773
self.get_file(file_id).readlines())
1796
1774
repo = self._get_repository()
1797
1775
base_vf = repo.texts
1798
1776
if base_vf not in vf.fallback_versionedfiles:
1820
1798
executable = self.is_executable(file_id, path)
1821
1799
return kind, executable, None
1823
def is_locked(self):
1826
1801
def lock_read(self):
1827
1802
# Perhaps in theory, this should lock the TreeTransform?
1830
1805
def unlock(self):
2291
2266
for num, _unused in enumerate(wt.all_file_ids()):
2292
2267
if num > 0: # more than just a root
2293
2268
raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
2269
existing_files = set()
2270
for dir, files in wt.walkdirs():
2271
existing_files.update(f[0] for f in files)
2294
2272
file_trans_id = {}
2295
2273
top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
2296
2274
pp = ProgressPhase("Build phase", 2, top_pb)
2320
2298
precomputed_delta = []
2322
2300
precomputed_delta = None
2323
# Check if tree inventory has content. If so, we populate
2324
# existing_files with the directory content. If there are no
2325
# entries we skip populating existing_files as its not used.
2326
# This improves performance and unncessary work on large
2327
# directory trees. (#501307)
2329
existing_files = set()
2330
for dir, files in wt.walkdirs():
2331
existing_files.update(f[0] for f in files)
2332
2301
for num, (tree_path, entry) in \
2333
2302
enumerate(tree.inventory.iter_entries_by_dir()):
2334
2303
pb.update("Building tree", num - len(deferred_contents), total)
2466
2435
if entry.kind == "directory":
2468
2437
if entry.kind == "file":
2469
f = file(target_path, 'rb')
2471
if tree.get_file_text(file_id) == f.read():
2438
if tree.get_file(file_id).read() == file(target_path, 'rb').read():
2475
2440
elif entry.kind == "symlink":
2476
2441
if tree.get_symlink_target(file_id) == os.readlink(target_path):
2933
2898
self.pending_deletions = []
2935
2900
def rename(self, from_, to):
2936
"""Rename a file from one path to another."""
2901
"""Rename a file from one path to another. Functions like os.rename"""
2938
osutils.rename(from_, to)
2939
except (IOError, OSError), e:
2903
os.rename(from_, to)
2940
2905
if e.errno in (errno.EEXIST, errno.ENOTEMPTY):
2941
2906
raise errors.FileExists(to, str(e))
2942
# normal OSError doesn't include filenames so it's hard to see where
2943
# the problem is, see https://bugs.launchpad.net/bzr/+bug/491763
2944
raise errors.TransformRenameFailed(from_, to, str(e), e.errno)
2945
2908
self.past_renames.append((from_, to))
2947
2910
def pre_delete(self, from_, to):
2957
2920
def rollback(self):
2958
2921
"""Reverse all renames that have been performed"""
2959
2922
for from_, to in reversed(self.past_renames):
2961
osutils.rename(to, from_)
2962
except (OSError, IOError), e:
2963
raise errors.TransformRenameFailed(to, from_, str(e), e.errno)
2923
os.rename(to, from_)
2964
2924
# after rollback, don't reuse _FileMover
2965
2925
past_renames = None
2966
2926
pending_deletions = None