347
346
path = osutils.getcwd()
348
347
control, relpath = bzrdir.BzrDir.open_containing(path)
350
348
return control.open_workingtree(), relpath
351
def open_containing_paths(file_list, default_directory=None,
352
canonicalize=True, apply_view=True):
353
"""Open the WorkingTree that contains a set of paths.
355
Fail if the paths given are not all in a single tree.
357
This is used for the many command-line interfaces that take a list of
358
any number of files and that require they all be in the same tree.
360
if default_directory is None:
361
default_directory = u'.'
362
# recommended replacement for builtins.internal_tree_files
363
if file_list is None or len(file_list) == 0:
364
tree = WorkingTree.open_containing(default_directory)[0]
365
# XXX: doesn't really belong here, and seems to have the strange
366
# side effect of making it return a bunch of files, not the whole
367
# tree -- mbp 20100716
368
if tree.supports_views() and apply_view:
369
view_files = tree.views.lookup_view()
371
file_list = view_files
372
view_str = views.view_display_str(view_files)
373
note("Ignoring files outside view. View is %s" % view_str)
374
return tree, file_list
375
if default_directory == u'.':
378
seed = default_directory
379
file_list = [osutils.pathjoin(default_directory, f)
381
tree = WorkingTree.open_containing(seed)[0]
382
return tree, tree.safe_relpath_files(file_list, canonicalize,
383
apply_view=apply_view)
385
def safe_relpath_files(self, file_list, canonicalize=True, apply_view=True):
386
"""Convert file_list into a list of relpaths in tree.
388
:param self: A tree to operate on.
389
:param file_list: A list of user provided paths or None.
390
:param apply_view: if True and a view is set, apply it or check that
391
specified files are within it
392
:return: A list of relative paths.
393
:raises errors.PathNotChild: When a provided path is in a different self
396
if file_list is None:
398
if self.supports_views() and apply_view:
399
view_files = self.views.lookup_view()
403
# self.relpath exists as a "thunk" to osutils, but canonical_relpath
404
# doesn't - fix that up here before we enter the loop.
406
fixer = lambda p: osutils.canonical_relpath(self.basedir, p)
409
for filename in file_list:
410
relpath = fixer(osutils.dereference_path(filename))
411
if view_files and not osutils.is_inside_any(view_files, relpath):
412
raise errors.FileOutsideView(filename, view_files)
413
new_list.append(relpath)
353
417
def open_downlevel(path=None):
354
418
"""Open an unsupported working tree.
1380
1446
# check the inventory for source and destination
1381
1447
if from_id is None:
1382
1448
raise errors.BzrMoveFailedError(from_rel,to_rel,
1383
errors.NotVersionedError(path=str(from_rel)))
1449
errors.NotVersionedError(path=from_rel))
1384
1450
if to_id is not None:
1385
1451
raise errors.BzrMoveFailedError(from_rel,to_rel,
1386
errors.AlreadyVersionedError(path=str(to_rel)))
1452
errors.AlreadyVersionedError(path=to_rel))
1388
1454
# try to determine the mode for rename (only change inv or change
1389
1455
# inv and file system)
1391
1457
if not self.has_filename(to_rel):
1392
1458
raise errors.BzrMoveFailedError(from_id,to_rel,
1393
errors.NoSuchFile(path=str(to_rel),
1459
errors.NoSuchFile(path=to_rel,
1394
1460
extra="New file has not been created yet"))
1395
1461
only_change_inv = True
1396
1462
elif not self.has_filename(from_rel) and self.has_filename(to_rel):
1798
1855
raise errors.ObjectNotLocked(self)
1800
1857
def lock_read(self):
1801
"""See Branch.lock_read, and WorkingTree.unlock."""
1858
"""Lock the tree for reading.
1860
This also locks the branch, and can be unlocked via self.unlock().
1862
:return: A bzrlib.lock.LogicalLockResult.
1802
1864
if not self.is_locked():
1803
1865
self._reset_data()
1804
1866
self.branch.lock_read()
1806
return self._control_files.lock_read()
1868
self._control_files.lock_read()
1869
return LogicalLockResult(self.unlock)
1808
1871
self.branch.unlock()
1811
1874
def lock_tree_write(self):
1812
"""See MutableTree.lock_tree_write, and WorkingTree.unlock."""
1875
"""See MutableTree.lock_tree_write, and WorkingTree.unlock.
1877
:return: A bzrlib.lock.LogicalLockResult.
1813
1879
if not self.is_locked():
1814
1880
self._reset_data()
1815
1881
self.branch.lock_read()
1817
return self._control_files.lock_write()
1883
self._control_files.lock_write()
1884
return LogicalLockResult(self.unlock)
1819
1886
self.branch.unlock()
1822
1889
def lock_write(self):
1823
"""See MutableTree.lock_write, and WorkingTree.unlock."""
1890
"""See MutableTree.lock_write, and WorkingTree.unlock.
1892
:return: A bzrlib.lock.LogicalLockResult.
1824
1894
if not self.is_locked():
1825
1895
self._reset_data()
1826
1896
self.branch.lock_write()
1828
return self._control_files.lock_write()
1898
self._control_files.lock_write()
1899
return LogicalLockResult(self.unlock)
1830
1901
self.branch.unlock()
2022
all_files = set() # specified and nested files
1952
2023
unknown_nested_files=set()
1953
2024
if to_file is None:
1954
2025
to_file = sys.stdout
2027
files_to_backup = []
1956
2029
def recurse_directory_to_add_files(directory):
1957
2030
# Recurse directory and add all files
1958
2031
# so we can check if they have changed.
1959
for parent_info, file_infos in\
1960
self.walkdirs(directory):
2032
for parent_info, file_infos in self.walkdirs(directory):
1961
2033
for relpath, basename, kind, lstat, fileid, kind in file_infos:
1962
2034
# Is it versioned or ignored?
1963
if self.path2id(relpath) or self.is_ignored(relpath):
2035
if self.path2id(relpath):
1964
2036
# Add nested content for deletion.
1965
new_files.add(relpath)
2037
all_files.add(relpath)
1967
# Files which are not versioned and not ignored
2039
# Files which are not versioned
1968
2040
# should be treated as unknown.
1969
unknown_nested_files.add((relpath, None, kind))
2041
files_to_backup.append(relpath)
1971
2043
for filename in files:
1972
2044
# Get file name into canonical form.
1973
2045
abspath = self.abspath(filename)
1974
2046
filename = self.relpath(abspath)
1975
2047
if len(filename) > 0:
1976
new_files.add(filename)
2048
all_files.add(filename)
1977
2049
recurse_directory_to_add_files(filename)
1979
files = list(new_files)
2051
files = list(all_files)
1981
2053
if len(files) == 0:
1982
2054
return # nothing to do
1987
2059
# Bail out if we are going to delete files we shouldn't
1988
2060
if not keep_files and not force:
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
2061
for (file_id, path, content_change, versioned, parent_id, name,
2062
kind, executable) in self.iter_changes(self.basis_tree(),
2063
include_unchanged=True, require_versioned=False,
2064
want_unversioned=True, specific_files=files):
2065
if versioned[0] == False:
2066
# The record is unknown or newly added
2067
files_to_backup.append(path[1])
2068
elif (content_change and (kind[1] is not None) and
2069
osutils.is_inside_any(files, path[1])):
2070
# Versioned and changed, but not deleted, and still
2071
# in one of the dirs to be deleted.
2072
files_to_backup.append(path[1])
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)
2074
def backup(file_to_backup):
2075
backup_name = self.bzrdir._available_backup_name(file_to_backup)
2076
osutils.rename(abs_path, self.abspath(backup_name))
2077
return "removed %s (but kept a copy: %s)" % (file_to_backup,
2016
2080
# Build inv_delta and delete files where applicable,
2017
2081
# do this before any modifications to inventory.
2347
2417
def add_conflicts(self, arg):
2348
2418
raise errors.UnsupportedOperation(self.add_conflicts, self)
2351
2420
def conflicts(self):
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)))
2421
raise NotImplementedError(self.conflicts)
2376
2423
def walkdirs(self, prefix=""):
2377
2424
"""Walk the directories of this tree.
2646
def check_state(self):
2647
"""Check that the working state is/isn't valid."""
2648
check_refs = self._get_check_refs()
2650
for ref in check_refs:
2653
refs[ref] = self.branch.repository.revision_tree(value)
2656
@needs_tree_write_lock
2657
def reset_state(self, revision_ids=None):
2658
"""Reset the state of the working tree.
2660
This does a hard-reset to a last-known-good state. This is a way to
2661
fix if something got corrupted (like the .bzr/checkout/dirstate file)
2663
if revision_ids is None:
2664
revision_ids = self.get_parent_ids()
2665
if not revision_ids:
2666
rt = self.branch.repository.revision_tree(
2667
_mod_revision.NULL_REVISION)
2669
rt = self.branch.repository.revision_tree(revision_ids[0])
2670
self._write_inventory(rt.inventory)
2671
self.set_parent_ids(revision_ids)
2598
2673
def _get_rules_searcher(self, default_searcher):
2599
2674
"""See Tree._get_rules_searcher."""
2600
2675
if self._rules_searcher is None:
2608
2683
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()
2665
2686
class WorkingTree3(WorkingTree):
2666
2687
"""This is the Format 3 working tree.
2740
2761
self.branch.unlock()
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):
2764
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2765
"""Registry for working tree formats."""
2767
def __init__(self, other_registry=None):
2768
super(WorkingTreeFormatRegistry, self).__init__(other_registry)
2769
self._default_format = None
2771
def get_default(self):
2772
"""Return the current default format."""
2773
return self._default_format
2775
def set_default(self, format):
2776
self._default_format = format
2779
format_registry = WorkingTreeFormatRegistry()
2782
class WorkingTreeFormat(controldir.ControlComponentFormat):
2750
2783
"""An encapsulation of the initialization and open routines for a format.
2752
2785
Formats provide three things:
2764
2797
object will be created every time regardless.
2767
_default_format = None
2768
"""The default format used for new trees."""
2771
"""The known formats."""
2773
2800
requires_rich_root = False
2775
2802
upgrade_recommended = False
2804
requires_normalized_unicode_filenames = False
2806
case_sensitive_filename = "FoRMaT"
2808
missing_parent_conflicts = False
2809
"""If this format supports missing parent conflicts."""
2778
2812
def find_format(klass, a_bzrdir):
2779
2813
"""Return the format for the working tree object in a_bzrdir."""
2781
2815
transport = a_bzrdir.get_workingtree_transport(None)
2782
2816
format_string = transport.get_bytes("format")
2783
return klass._formats[format_string]
2817
return format_registry.get(format_string)
2784
2818
except errors.NoSuchFile:
2785
2819
raise errors.NoWorkingTree(base=transport.base)
2786
2820
except KeyError:
2787
2821
raise errors.UnknownFormatError(format=format_string,
2788
2822
kind="working tree")
2824
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2825
accelerator_tree=None, hardlink=False):
2826
"""Initialize a new working tree in a_bzrdir.
2828
:param a_bzrdir: BzrDir to initialize the working tree in.
2829
:param revision_id: allows creating a working tree at a different
2830
revision than the branch is at.
2831
:param from_branch: Branch to checkout
2832
:param accelerator_tree: A tree which can be used for retrieving file
2833
contents more quickly than the revision tree, i.e. a workingtree.
2834
The revision tree will be used for cases where accelerator_tree's
2835
content is different.
2836
:param hardlink: If true, hard-link files from accelerator_tree,
2839
raise NotImplementedError(self.initialize)
2790
2841
def __eq__(self, other):
2791
2842
return self.__class__ is other.__class__
2880
@symbol_versioning.deprecated_method(
2881
symbol_versioning.deprecated_in((2, 4, 0)))
2827
2882
def register_format(klass, format):
2828
klass._formats[format.get_format_string()] = format
2883
format_registry.register(format)
2886
@symbol_versioning.deprecated_method(
2887
symbol_versioning.deprecated_in((2, 4, 0)))
2888
def register_extra_format(klass, format):
2889
format_registry.register_extra(format)
2892
@symbol_versioning.deprecated_method(
2893
symbol_versioning.deprecated_in((2, 4, 0)))
2894
def unregister_extra_format(klass, format):
2895
format_registry.unregister_extra(format)
2898
@symbol_versioning.deprecated_method(
2899
symbol_versioning.deprecated_in((2, 4, 0)))
2900
def get_formats(klass):
2901
return format_registry._get_all()
2904
@symbol_versioning.deprecated_method(
2905
symbol_versioning.deprecated_in((2, 4, 0)))
2831
2906
def set_default_format(klass, format):
2832
klass._default_format = format
2907
format_registry.set_default(format)
2910
@symbol_versioning.deprecated_method(
2911
symbol_versioning.deprecated_in((2, 4, 0)))
2835
2912
def unregister_format(klass, 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('.'),
2913
format_registry.remove(format)
2921
2916
class WorkingTreeFormat3(WorkingTreeFormat):
2922
2917
"""The second working tree format updated to record a format marker.
3052
3049
__default_format = WorkingTreeFormat6()
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(),
3050
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3051
"bzrlib.workingtree_4", "WorkingTreeFormat4")
3052
format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",
3053
"bzrlib.workingtree_4", "WorkingTreeFormat5")
3054
format_registry.register_lazy("Bazaar Working Tree Format 6 (bzr 1.14)\n",
3055
"bzrlib.workingtree_4", "WorkingTreeFormat6")
3056
format_registry.register(WorkingTreeFormat3())
3057
format_registry.set_default(__default_format)
3058
# Register extra formats which have no format string are not discoverable
3059
# and not independently creatable. They are implicitly created as part of
3060
# e.g. older Bazaar formats or foreign formats.
3061
format_registry.register_extra_lazy("bzrlib.workingtree_2",
3062
"WorkingTreeFormat2")