355
347
path = osutils.getcwd()
356
348
control, relpath = bzrdir.BzrDir.open_containing(path)
357
350
return control.open_workingtree(), relpath
360
def open_containing_paths(file_list, default_directory=None,
361
canonicalize=True, apply_view=True):
362
"""Open the WorkingTree that contains a set of paths.
364
Fail if the paths given are not all in a single tree.
366
This is used for the many command-line interfaces that take a list of
367
any number of files and that require they all be in the same tree.
369
if default_directory is None:
370
default_directory = u'.'
371
# recommended replacement for builtins.internal_tree_files
372
if file_list is None or len(file_list) == 0:
373
tree = WorkingTree.open_containing(default_directory)[0]
374
# XXX: doesn't really belong here, and seems to have the strange
375
# side effect of making it return a bunch of files, not the whole
376
# tree -- mbp 20100716
377
if tree.supports_views() and apply_view:
378
view_files = tree.views.lookup_view()
380
file_list = view_files
381
view_str = views.view_display_str(view_files)
382
note("Ignoring files outside view. View is %s" % view_str)
383
return tree, file_list
384
if default_directory == u'.':
387
seed = default_directory
388
file_list = [osutils.pathjoin(default_directory, f)
390
tree = WorkingTree.open_containing(seed)[0]
391
return tree, tree.safe_relpath_files(file_list, canonicalize,
392
apply_view=apply_view)
394
def safe_relpath_files(self, file_list, canonicalize=True, apply_view=True):
395
"""Convert file_list into a list of relpaths in tree.
397
:param self: A tree to operate on.
398
:param file_list: A list of user provided paths or None.
399
:param apply_view: if True and a view is set, apply it or check that
400
specified files are within it
401
:return: A list of relative paths.
402
:raises errors.PathNotChild: When a provided path is in a different self
405
if file_list is None:
407
if self.supports_views() and apply_view:
408
view_files = self.views.lookup_view()
412
# self.relpath exists as a "thunk" to osutils, but canonical_relpath
413
# doesn't - fix that up here before we enter the loop.
415
fixer = lambda p: osutils.canonical_relpath(self.basedir, p)
418
for filename in file_list:
419
relpath = fixer(osutils.dereference_path(filename))
420
if view_files and not osutils.is_inside_any(view_files, relpath):
421
raise errors.FileOutsideView(filename, view_files)
422
new_list.append(relpath)
426
353
def open_downlevel(path=None):
427
354
"""Open an unsupported working tree.
1456
1380
# check the inventory for source and destination
1457
1381
if from_id is None:
1458
1382
raise errors.BzrMoveFailedError(from_rel,to_rel,
1459
errors.NotVersionedError(path=from_rel))
1383
errors.NotVersionedError(path=str(from_rel)))
1460
1384
if to_id is not None:
1461
1385
raise errors.BzrMoveFailedError(from_rel,to_rel,
1462
errors.AlreadyVersionedError(path=to_rel))
1386
errors.AlreadyVersionedError(path=str(to_rel)))
1464
1388
# try to determine the mode for rename (only change inv or change
1465
1389
# inv and file system)
1467
1391
if not self.has_filename(to_rel):
1468
1392
raise errors.BzrMoveFailedError(from_id,to_rel,
1469
errors.NoSuchFile(path=to_rel,
1393
errors.NoSuchFile(path=str(to_rel),
1470
1394
extra="New file has not been created yet"))
1471
1395
only_change_inv = True
1472
1396
elif not self.has_filename(from_rel) and self.has_filename(to_rel):
1865
1798
raise errors.ObjectNotLocked(self)
1867
1800
def lock_read(self):
1868
"""Lock the tree for reading.
1870
This also locks the branch, and can be unlocked via self.unlock().
1872
:return: A bzrlib.lock.LogicalLockResult.
1801
"""See Branch.lock_read, and WorkingTree.unlock."""
1874
1802
if not self.is_locked():
1875
1803
self._reset_data()
1876
1804
self.branch.lock_read()
1878
self._control_files.lock_read()
1879
return LogicalLockResult(self.unlock)
1806
return self._control_files.lock_read()
1881
1808
self.branch.unlock()
1884
1811
def lock_tree_write(self):
1885
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1887
:return: A bzrlib.lock.LogicalLockResult.
1812
"""See MutableTree.lock_tree_write, and WorkingTree.unlock."""
1889
1813
if not self.is_locked():
1890
1814
self._reset_data()
1891
1815
self.branch.lock_read()
1893
self._control_files.lock_write()
1894
return LogicalLockResult(self.unlock)
1817
return self._control_files.lock_write()
1896
1819
self.branch.unlock()
1899
1822
def lock_write(self):
1900
"""See MutableTree.lock_write, and WorkingTree.unlock.
1902
:return: A bzrlib.lock.LogicalLockResult.
1823
"""See MutableTree.lock_write, and WorkingTree.unlock."""
1904
1824
if not self.is_locked():
1905
1825
self._reset_data()
1906
1826
self.branch.lock_write()
1908
self._control_files.lock_write()
1909
return LogicalLockResult(self.unlock)
1828
return self._control_files.lock_write()
1911
1830
self.branch.unlock()
2032
all_files = set() # specified and nested files
2033
1952
unknown_nested_files=set()
2034
1953
if to_file is None:
2035
1954
to_file = sys.stdout
2037
files_to_backup = []
2039
1956
def recurse_directory_to_add_files(directory):
2040
1957
# Recurse directory and add all files
2041
1958
# so we can check if they have changed.
2042
for parent_info, file_infos in self.walkdirs(directory):
1959
for parent_info, file_infos in\
1960
self.walkdirs(directory):
2043
1961
for relpath, basename, kind, lstat, fileid, kind in file_infos:
2044
1962
# Is it versioned or ignored?
2045
if self.path2id(relpath):
1963
if self.path2id(relpath) or self.is_ignored(relpath):
2046
1964
# Add nested content for deletion.
2047
all_files.add(relpath)
1965
new_files.add(relpath)
2049
# Files which are not versioned
1967
# Files which are not versioned and not ignored
2050
1968
# should be treated as unknown.
2051
files_to_backup.append(relpath)
1969
unknown_nested_files.add((relpath, None, kind))
2053
1971
for filename in files:
2054
1972
# Get file name into canonical form.
2055
1973
abspath = self.abspath(filename)
2056
1974
filename = self.relpath(abspath)
2057
1975
if len(filename) > 0:
2058
all_files.add(filename)
1976
new_files.add(filename)
2059
1977
recurse_directory_to_add_files(filename)
2061
files = list(all_files)
1979
files = list(new_files)
2063
1981
if len(files) == 0:
2064
1982
return # nothing to do
2069
1987
# Bail out if we are going to delete files we shouldn't
2070
1988
if not keep_files and not force:
2071
for (file_id, path, content_change, versioned, parent_id, name,
2072
kind, executable) in self.iter_changes(self.basis_tree(),
2073
include_unchanged=True, require_versioned=False,
2074
want_unversioned=True, specific_files=files):
2075
if versioned[0] == False:
2076
# The record is unknown or newly added
2077
files_to_backup.append(path[1])
2078
elif (content_change and (kind[1] is not None) and
2079
osutils.is_inside_any(files, path[1])):
2080
# Versioned and changed, but not deleted, and still
2081
# in one of the dirs to be deleted.
2082
files_to_backup.append(path[1])
1989
has_changed_files = len(unknown_nested_files) > 0
1990
if not has_changed_files:
1991
for (file_id, path, content_change, versioned, parent_id, name,
1992
kind, executable) in self.iter_changes(self.basis_tree(),
1993
include_unchanged=True, require_versioned=False,
1994
want_unversioned=True, specific_files=files):
1995
if versioned == (False, False):
1996
# The record is unknown ...
1997
if not self.is_ignored(path[1]):
1998
# ... but not ignored
1999
has_changed_files = True
2001
elif content_change and (kind[1] is not None):
2002
# Versioned and changed, but not deleted
2003
has_changed_files = True
2084
def backup(file_to_backup):
2085
backup_name = self.bzrdir._available_backup_name(file_to_backup)
2086
osutils.rename(abs_path, self.abspath(backup_name))
2087
return "removed %s (but kept a copy: %s)" % (file_to_backup,
2006
if has_changed_files:
2007
# Make delta show ALL applicable changes in error message.
2008
tree_delta = self.changes_from(self.basis_tree(),
2009
require_versioned=False, want_unversioned=True,
2010
specific_files=files)
2011
for unknown_file in unknown_nested_files:
2012
if unknown_file not in tree_delta.unversioned:
2013
tree_delta.unversioned.extend((unknown_file,))
2014
raise errors.BzrRemoveChangedFilesError(tree_delta)
2090
2016
# Build inv_delta and delete files where applicable,
2091
2017
# do this before any modifications to inventory.
2427
2347
def add_conflicts(self, arg):
2428
2348
raise errors.UnsupportedOperation(self.add_conflicts, self)
2430
2351
def conflicts(self):
2431
raise NotImplementedError(self.conflicts)
2352
conflicts = _mod_conflicts.ConflictList()
2353
for conflicted in self._iter_conflicts():
2356
if file_kind(self.abspath(conflicted)) != "file":
2358
except errors.NoSuchFile:
2361
for suffix in ('.THIS', '.OTHER'):
2363
kind = file_kind(self.abspath(conflicted+suffix))
2366
except errors.NoSuchFile:
2370
ctype = {True: 'text conflict', False: 'contents conflict'}[text]
2371
conflicts.append(_mod_conflicts.Conflict.factory(ctype,
2373
file_id=self.path2id(conflicted)))
2433
2376
def walkdirs(self, prefix=""):
2434
2377
"""Walk the directories of this tree.
2656
def check_state(self):
2657
"""Check that the working state is/isn't valid."""
2658
check_refs = self._get_check_refs()
2660
for ref in check_refs:
2663
refs[ref] = self.branch.repository.revision_tree(value)
2666
@needs_tree_write_lock
2667
def reset_state(self, revision_ids=None):
2668
"""Reset the state of the working tree.
2670
This does a hard-reset to a last-known-good state. This is a way to
2671
fix if something got corrupted (like the .bzr/checkout/dirstate file)
2673
if revision_ids is None:
2674
revision_ids = self.get_parent_ids()
2675
if not revision_ids:
2676
rt = self.branch.repository.revision_tree(
2677
_mod_revision.NULL_REVISION)
2679
rt = self.branch.repository.revision_tree(revision_ids[0])
2680
self._write_inventory(rt.inventory)
2681
self.set_parent_ids(revision_ids)
2683
2598
def _get_rules_searcher(self, default_searcher):
2684
2599
"""See Tree._get_rules_searcher."""
2685
2600
if self._rules_searcher is None:
2693
2608
return ShelfManager(self, self._transport)
2611
class WorkingTree2(WorkingTree):
2612
"""This is the Format 2 working tree.
2614
This was the first weave based working tree.
2615
- uses os locks for locking.
2616
- uses the branch last-revision.
2619
def __init__(self, *args, **kwargs):
2620
super(WorkingTree2, self).__init__(*args, **kwargs)
2621
# WorkingTree2 has more of a constraint that self._inventory must
2622
# exist. Because this is an older format, we don't mind the overhead
2623
# caused by the extra computation here.
2625
# Newer WorkingTree's should only have self._inventory set when they
2627
if self._inventory is None:
2628
self.read_working_inventory()
2630
def _get_check_refs(self):
2631
"""Return the references needed to perform a check of this tree."""
2632
return [('trees', self.last_revision())]
2634
def lock_tree_write(self):
2635
"""See WorkingTree.lock_tree_write().
2637
In Format2 WorkingTrees we have a single lock for the branch and tree
2638
so lock_tree_write() degrades to lock_write().
2640
self.branch.lock_write()
2642
return self._control_files.lock_write()
2644
self.branch.unlock()
2648
# do non-implementation specific cleanup
2651
# we share control files:
2652
if self._control_files._lock_count == 3:
2653
# _inventory_is_modified is always False during a read lock.
2654
if self._inventory_is_modified:
2656
self._write_hashcache_if_dirty()
2658
# reverse order of locking.
2660
return self._control_files.unlock()
2662
self.branch.unlock()
2696
2665
class WorkingTree3(WorkingTree):
2697
2666
"""This is the Format 3 working tree.
2772
2740
self.branch.unlock()
2775
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2776
"""Registry for working tree formats."""
2778
def __init__(self, other_registry=None):
2779
super(WorkingTreeFormatRegistry, self).__init__(other_registry)
2780
self._default_format = None
2782
def get_default(self):
2783
"""Return the current default format."""
2784
return self._default_format
2786
def set_default(self, format):
2787
self._default_format = format
2790
format_registry = WorkingTreeFormatRegistry()
2793
class WorkingTreeFormat(controldir.ControlComponentFormat):
2743
def get_conflicted_stem(path):
2744
for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
2745
if path.endswith(suffix):
2746
return path[:-len(suffix)]
2749
class WorkingTreeFormat(object):
2794
2750
"""An encapsulation of the initialization and open routines for a format.
2796
2752
Formats provide three things:
2808
2764
object will be created every time regardless.
2767
_default_format = None
2768
"""The default format used for new trees."""
2771
"""The known formats."""
2811
2773
requires_rich_root = False
2813
2775
upgrade_recommended = False
2815
requires_normalized_unicode_filenames = False
2817
case_sensitive_filename = "FoRMaT"
2819
missing_parent_conflicts = False
2820
"""If this format supports missing parent conflicts."""
2823
2778
def find_format(klass, a_bzrdir):
2824
2779
"""Return the format for the working tree object in a_bzrdir."""
2826
2781
transport = a_bzrdir.get_workingtree_transport(None)
2827
2782
format_string = transport.get_bytes("format")
2828
return format_registry.get(format_string)
2783
return klass._formats[format_string]
2829
2784
except errors.NoSuchFile:
2830
2785
raise errors.NoWorkingTree(base=transport.base)
2831
2786
except KeyError:
2832
2787
raise errors.UnknownFormatError(format=format_string,
2833
2788
kind="working tree")
2835
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2836
accelerator_tree=None, hardlink=False):
2837
"""Initialize a new working tree in a_bzrdir.
2839
:param a_bzrdir: BzrDir to initialize the working tree in.
2840
:param revision_id: allows creating a working tree at a different
2841
revision than the branch is at.
2842
:param from_branch: Branch to checkout
2843
:param accelerator_tree: A tree which can be used for retrieving file
2844
contents more quickly than the revision tree, i.e. a workingtree.
2845
The revision tree will be used for cases where accelerator_tree's
2846
content is different.
2847
:param hardlink: If true, hard-link files from accelerator_tree,
2850
raise NotImplementedError(self.initialize)
2852
2790
def __eq__(self, other):
2853
2791
return self.__class__ is other.__class__
2891
@symbol_versioning.deprecated_method(
2892
symbol_versioning.deprecated_in((2, 4, 0)))
2893
2827
def register_format(klass, format):
2894
format_registry.register(format)
2897
@symbol_versioning.deprecated_method(
2898
symbol_versioning.deprecated_in((2, 4, 0)))
2899
def register_extra_format(klass, format):
2900
format_registry.register_extra(format)
2903
@symbol_versioning.deprecated_method(
2904
symbol_versioning.deprecated_in((2, 4, 0)))
2905
def unregister_extra_format(klass, format):
2906
format_registry.unregister_extra(format)
2909
@symbol_versioning.deprecated_method(
2910
symbol_versioning.deprecated_in((2, 4, 0)))
2911
def get_formats(klass):
2912
return format_registry._get_all()
2915
@symbol_versioning.deprecated_method(
2916
symbol_versioning.deprecated_in((2, 4, 0)))
2828
klass._formats[format.get_format_string()] = format
2917
2831
def set_default_format(klass, format):
2918
format_registry.set_default(format)
2832
klass._default_format = format
2921
@symbol_versioning.deprecated_method(
2922
symbol_versioning.deprecated_in((2, 4, 0)))
2923
2835
def unregister_format(klass, format):
2924
format_registry.remove(format)
2836
del klass._formats[format.get_format_string()]
2839
class WorkingTreeFormat2(WorkingTreeFormat):
2840
"""The second working tree format.
2842
This format modified the hash cache from the format 1 hash cache.
2845
upgrade_recommended = True
2847
def get_format_description(self):
2848
"""See WorkingTreeFormat.get_format_description()."""
2849
return "Working tree format 2"
2851
def _stub_initialize_on_transport(self, transport, file_mode):
2852
"""Workaround: create control files for a remote working tree.
2854
This ensures that it can later be updated and dealt with locally,
2855
since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
2856
no working tree. (See bug #43064).
2859
inv = inventory.Inventory()
2860
xml5.serializer_v5.write_inventory(inv, sio, working=True)
2862
transport.put_file('inventory', sio, file_mode)
2863
transport.put_bytes('pending-merges', '', file_mode)
2865
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2866
accelerator_tree=None, hardlink=False):
2867
"""See WorkingTreeFormat.initialize()."""
2868
if not isinstance(a_bzrdir.transport, LocalTransport):
2869
raise errors.NotLocalUrl(a_bzrdir.transport.base)
2870
if from_branch is not None:
2871
branch = from_branch
2873
branch = a_bzrdir.open_branch()
2874
if revision_id is None:
2875
revision_id = _mod_revision.ensure_null(branch.last_revision())
2878
branch.generate_revision_history(revision_id)
2881
inv = inventory.Inventory()
2882
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2888
basis_tree = branch.repository.revision_tree(revision_id)
2889
if basis_tree.inventory.root is not None:
2890
wt.set_root_id(basis_tree.get_root_id())
2891
# set the parent list and cache the basis tree.
2892
if _mod_revision.is_null(revision_id):
2895
parent_trees = [(revision_id, basis_tree)]
2896
wt.set_parent_trees(parent_trees)
2897
transform.build_tree(basis_tree, wt)
2901
super(WorkingTreeFormat2, self).__init__()
2902
self._matchingbzrdir = bzrdir.BzrDirFormat6()
2904
def open(self, a_bzrdir, _found=False):
2905
"""Return the WorkingTree object for a_bzrdir
2907
_found is a private parameter, do not use it. It is used to indicate
2908
if format probing has already been done.
2911
# we are being called directly and must probe.
2912
raise NotImplementedError
2913
if not isinstance(a_bzrdir.transport, LocalTransport):
2914
raise errors.NotLocalUrl(a_bzrdir.transport.base)
2915
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2927
2921
class WorkingTreeFormat3(WorkingTreeFormat):
2928
2922
"""The second working tree format updated to record a format marker.
3060
3052
__default_format = WorkingTreeFormat6()
3061
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3062
"bzrlib.workingtree_4", "WorkingTreeFormat4")
3063
format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",
3064
"bzrlib.workingtree_4", "WorkingTreeFormat5")
3065
format_registry.register_lazy("Bazaar Working Tree Format 6 (bzr 1.14)\n",
3066
"bzrlib.workingtree_4", "WorkingTreeFormat6")
3067
format_registry.register(WorkingTreeFormat3())
3068
format_registry.set_default(__default_format)
3053
WorkingTreeFormat.register_format(__default_format)
3054
WorkingTreeFormat.register_format(WorkingTreeFormat5())
3055
WorkingTreeFormat.register_format(WorkingTreeFormat4())
3056
WorkingTreeFormat.register_format(WorkingTreeFormat3())
3057
WorkingTreeFormat.set_default_format(__default_format)
3058
# formats which have no format string are not discoverable
3059
# and not independently creatable, so are not registered.
3060
_legacy_formats = [WorkingTreeFormat2(),