616
615
# should probably put it back with the previous ID.
617
616
# the read and write working inventory should not occur in this
618
617
# function - they should be part of lock_write and unlock.
619
inv = self.read_working_inventory()
620
619
for f, file_id, kind in zip(files, ids, kinds):
621
620
assert kind is not None
622
621
if file_id is None:
625
624
file_id = osutils.safe_file_id(file_id)
626
625
inv.add_path(f, kind=kind, file_id=file_id)
627
self._write_inventory(inv)
626
self._inventory_is_modified = True
629
628
@needs_tree_write_lock
630
629
def _gather_kinds(self, files, kinds):
813
812
to_revision = osutils.safe_revision_id(to_revision)
814
813
merger.other_rev_id = to_revision
815
814
if merger.other_rev_id is None:
816
raise error.NoCommits(branch)
815
raise errors.NoCommits(branch)
817
816
self.branch.fetch(branch, last_revision=merger.other_rev_id)
818
817
merger.other_basis = merger.other_rev_id
819
818
merger.other_tree = self.branch.repository.revision_tree(
1783
1782
def recurse_directory_to_add_files(directory):
1784
1783
# recurse directory and add all files
1785
1784
# so we can check if they have changed.
1786
for contained_dir_info in self.walkdirs(directory):
1787
for file_info in contained_dir_info[1]:
1788
if file_info[2] == 'file':
1789
relpath = self.relpath(file_info[0])
1790
if file_info[4]: #is it versioned?
1785
for parent_info, file_infos in\
1786
osutils.walkdirs(self.abspath(directory),
1788
for relpath, basename, kind, lstat, abspath in file_infos:
1790
if self.path2id(relpath): #is it versioned?
1791
1791
new_files.add(relpath)
1793
1793
unknown_files_in_directory.add(
1794
(relpath, None, file_info[2]))
1794
(relpath, None, kind))
1796
1796
for filename in files:
1797
1797
# Get file name into canonical form.
1798
filename = self.relpath(self.abspath(filename))
1798
abspath = self.abspath(filename)
1799
filename = self.relpath(abspath)
1799
1800
if len(filename) > 0:
1800
1801
new_files.add(filename)
1801
if osutils.isdir(filename) and len(os.listdir(filename)) > 0:
1802
if osutils.isdir(abspath):
1802
1803
recurse_directory_to_add_files(filename)
1803
1804
files = [f for f in new_files]
1829
1830
new_status = 'I'
1831
1832
new_status = '?'
1832
textui.show_status(new_status, inv[fid].kind, f,
1833
textui.show_status(new_status, self.kind(fid), f,
1833
1834
to_file=to_file)
1834
1835
# unversion file
1836
inv_delta.append((f, None, fid, None))
1836
1837
message="removed %s" % (f,)
1838
1839
if not keep_files:
1852
1853
# print only one message (if any) per file.
1853
1854
if message is not None:
1855
self._write_inventory(inv)
1856
self.apply_inventory_delta(inv_delta)
1857
1858
@needs_tree_write_lock
1858
1859
def revert(self, filenames, old_tree=None, backups=True,
1970
1971
raise NotImplementedError(self.unlock)
1973
def update(self, change_reporter=None):
1973
1974
"""Update a working tree along its branch.
1975
1976
This will update the branch if its bound too, which means we have
2005
2006
old_tip = self.branch.update()
2008
return self._update_tree(old_tip)
2009
return self._update_tree(old_tip, change_reporter)
2012
2013
@needs_tree_write_lock
2013
def _update_tree(self, old_tip=None):
2014
def _update_tree(self, old_tip=None, change_reporter=None):
2014
2015
"""Update a tree to the master branch.
2016
2017
:param old_tip: if supplied, the previous tip revision the branch,
2083
2085
# inventory and calls tree._write_inventory(). Ultimately we
2084
2086
# should be able to remove this extra flush.
2086
from bzrlib.revision import common_ancestor
2088
base_rev_id = common_ancestor(self.branch.last_revision(),
2090
self.branch.repository)
2091
except errors.NoCommonAncestor:
2088
graph = self.branch.repository.get_graph()
2089
base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
2093
2091
base_tree = self.branch.repository.revision_tree(base_rev_id)
2094
2092
other_tree = self.branch.repository.revision_tree(old_tip)
2095
2093
result += merge.merge_inner(
2098
change_reporter=change_reporter)
2102
2101
def _write_hashcache_if_dirty(self):
2774
2773
# and not independently creatable, so are not registered.
2775
2774
_legacy_formats = [WorkingTreeFormat2(),
2779
class WorkingTreeTestProviderAdapter(object):
2780
"""A tool to generate a suite testing multiple workingtree formats at once.
2782
This is done by copying the test once for each transport and injecting
2783
the transport_server, transport_readonly_server, and workingtree_format
2784
classes into each copy. Each copy is also given a new id() to make it
2788
def __init__(self, transport_server, transport_readonly_server, formats):
2789
self._transport_server = transport_server
2790
self._transport_readonly_server = transport_readonly_server
2791
self._formats = formats
2793
def _clone_test(self, test, bzrdir_format, workingtree_format, variation):
2794
"""Clone test for adaption."""
2795
new_test = deepcopy(test)
2796
new_test.transport_server = self._transport_server
2797
new_test.transport_readonly_server = self._transport_readonly_server
2798
new_test.bzrdir_format = bzrdir_format
2799
new_test.workingtree_format = workingtree_format
2800
def make_new_test_id():
2801
new_id = "%s(%s)" % (test.id(), variation)
2802
return lambda: new_id
2803
new_test.id = make_new_test_id()
2806
def adapt(self, test):
2807
from bzrlib.tests import TestSuite
2808
result = TestSuite()
2809
for workingtree_format, bzrdir_format in self._formats:
2810
new_test = self._clone_test(
2813
workingtree_format, workingtree_format.__class__.__name__)
2814
result.addTest(new_test)