1437
1458
# check the inventory for source and destination
1438
1459
if from_id is None:
1439
1460
raise errors.BzrMoveFailedError(from_rel,to_rel,
1440
errors.NotVersionedError(path=str(from_rel)))
1461
errors.NotVersionedError(path=from_rel))
1441
1462
if to_id is not None:
1442
1463
raise errors.BzrMoveFailedError(from_rel,to_rel,
1443
errors.AlreadyVersionedError(path=str(to_rel)))
1464
errors.AlreadyVersionedError(path=to_rel))
1445
1466
# try to determine the mode for rename (only change inv or change
1446
1467
# inv and file system)
1448
1469
if not self.has_filename(to_rel):
1449
1470
raise errors.BzrMoveFailedError(from_id,to_rel,
1450
errors.NoSuchFile(path=str(to_rel),
1471
errors.NoSuchFile(path=to_rel,
1451
1472
extra="New file has not been created yet"))
1452
1473
only_change_inv = True
1453
1474
elif not self.has_filename(from_rel) and self.has_filename(to_rel):
2034
all_files = set() # specified and nested files
2023
2035
unknown_nested_files=set()
2024
2036
if to_file is None:
2025
2037
to_file = sys.stdout
2039
files_to_backup = []
2027
2041
def recurse_directory_to_add_files(directory):
2028
2042
# Recurse directory and add all files
2029
2043
# so we can check if they have changed.
2030
2044
for parent_info, file_infos in self.walkdirs(directory):
2031
2045
for relpath, basename, kind, lstat, fileid, kind in file_infos:
2032
2046
# Is it versioned or ignored?
2033
if self.path2id(relpath) or self.is_ignored(relpath):
2047
if self.path2id(relpath):
2034
2048
# Add nested content for deletion.
2035
new_files.add(relpath)
2049
all_files.add(relpath)
2037
# Files which are not versioned and not ignored
2051
# Files which are not versioned
2038
2052
# should be treated as unknown.
2039
unknown_nested_files.add((relpath, None, kind))
2053
files_to_backup.append(relpath)
2041
2055
for filename in files:
2042
2056
# Get file name into canonical form.
2043
2057
abspath = self.abspath(filename)
2044
2058
filename = self.relpath(abspath)
2045
2059
if len(filename) > 0:
2046
new_files.add(filename)
2060
all_files.add(filename)
2047
2061
recurse_directory_to_add_files(filename)
2049
files = list(new_files)
2063
files = list(all_files)
2051
2065
if len(files) == 0:
2052
2066
return # nothing to do
2057
2071
# Bail out if we are going to delete files we shouldn't
2058
2072
if not keep_files and not force:
2059
has_changed_files = len(unknown_nested_files) > 0
2060
if not has_changed_files:
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 == (False, False):
2066
# The record is unknown ...
2067
if not self.is_ignored(path[1]):
2068
# ... but not ignored
2069
has_changed_files = True
2071
elif (content_change and (kind[1] is not None) and
2072
osutils.is_inside_any(files, path[1])):
2073
# Versioned and changed, but not deleted, and still
2074
# in one of the dirs to be deleted.
2075
has_changed_files = True
2073
for (file_id, path, content_change, versioned, parent_id, name,
2074
kind, executable) in self.iter_changes(self.basis_tree(),
2075
include_unchanged=True, require_versioned=False,
2076
want_unversioned=True, specific_files=files):
2077
if versioned[0] == False:
2078
# The record is unknown or newly added
2079
files_to_backup.append(path[1])
2080
elif (content_change and (kind[1] is not None) and
2081
osutils.is_inside_any(files, path[1])):
2082
# Versioned and changed, but not deleted, and still
2083
# in one of the dirs to be deleted.
2084
files_to_backup.append(path[1])
2078
if has_changed_files:
2079
# Make delta show ALL applicable changes in error message.
2080
tree_delta = self.changes_from(self.basis_tree(),
2081
require_versioned=False, want_unversioned=True,
2082
specific_files=files)
2083
for unknown_file in unknown_nested_files:
2084
if unknown_file not in tree_delta.unversioned:
2085
tree_delta.unversioned.extend((unknown_file,))
2086
raise errors.BzrRemoveChangedFilesError(tree_delta)
2086
def backup(file_to_backup):
2087
backup_name = self.bzrdir._available_backup_name(file_to_backup)
2088
osutils.rename(abs_path, self.abspath(backup_name))
2089
return "removed %s (but kept a copy: %s)" % (file_to_backup,
2088
2092
# Build inv_delta and delete files where applicable,
2089
2093
# do this before any modifications to inventory.
2419
2429
def add_conflicts(self, arg):
2420
2430
raise errors.UnsupportedOperation(self.add_conflicts, self)
2423
2432
def conflicts(self):
2424
conflicts = _mod_conflicts.ConflictList()
2425
for conflicted in self._iter_conflicts():
2428
if file_kind(self.abspath(conflicted)) != "file":
2430
except errors.NoSuchFile:
2433
for suffix in ('.THIS', '.OTHER'):
2435
kind = file_kind(self.abspath(conflicted+suffix))
2438
except errors.NoSuchFile:
2442
ctype = {True: 'text conflict', False: 'contents conflict'}[text]
2443
conflicts.append(_mod_conflicts.Conflict.factory(ctype,
2445
file_id=self.path2id(conflicted)))
2433
raise NotImplementedError(self.conflicts)
2448
2435
def walkdirs(self, prefix=""):
2449
2436
"""Walk the directories of this tree.
2658
def check_state(self):
2659
"""Check that the working state is/isn't valid."""
2660
check_refs = self._get_check_refs()
2662
for ref in check_refs:
2665
refs[ref] = self.branch.repository.revision_tree(value)
2668
@needs_tree_write_lock
2669
def reset_state(self, revision_ids=None):
2670
"""Reset the state of the working tree.
2672
This does a hard-reset to a last-known-good state. This is a way to
2673
fix if something got corrupted (like the .bzr/checkout/dirstate file)
2675
if revision_ids is None:
2676
revision_ids = self.get_parent_ids()
2677
if not revision_ids:
2678
rt = self.branch.repository.revision_tree(
2679
_mod_revision.NULL_REVISION)
2681
rt = self.branch.repository.revision_tree(revision_ids[0])
2682
self._write_inventory(rt.inventory)
2683
self.set_parent_ids(revision_ids)
2670
2685
def _get_rules_searcher(self, default_searcher):
2671
2686
"""See Tree._get_rules_searcher."""
2672
2687
if self._rules_searcher is None:
2680
2695
return ShelfManager(self, self._transport)
2683
class WorkingTree2(WorkingTree):
2684
"""This is the Format 2 working tree.
2686
This was the first weave based working tree.
2687
- uses os locks for locking.
2688
- uses the branch last-revision.
2691
def __init__(self, *args, **kwargs):
2692
super(WorkingTree2, self).__init__(*args, **kwargs)
2693
# WorkingTree2 has more of a constraint that self._inventory must
2694
# exist. Because this is an older format, we don't mind the overhead
2695
# caused by the extra computation here.
2697
# Newer WorkingTree's should only have self._inventory set when they
2699
if self._inventory is None:
2700
self.read_working_inventory()
2702
def _get_check_refs(self):
2703
"""Return the references needed to perform a check of this tree."""
2704
return [('trees', self.last_revision())]
2706
def lock_tree_write(self):
2707
"""See WorkingTree.lock_tree_write().
2709
In Format2 WorkingTrees we have a single lock for the branch and tree
2710
so lock_tree_write() degrades to lock_write().
2712
:return: An object with an unlock method which will release the lock
2715
self.branch.lock_write()
2717
self._control_files.lock_write()
2720
self.branch.unlock()
2724
# do non-implementation specific cleanup
2727
# we share control files:
2728
if self._control_files._lock_count == 3:
2729
# _inventory_is_modified is always False during a read lock.
2730
if self._inventory_is_modified:
2732
self._write_hashcache_if_dirty()
2734
# reverse order of locking.
2736
return self._control_files.unlock()
2738
self.branch.unlock()
2741
2698
class WorkingTree3(WorkingTree):
2742
2699
"""This is the Format 3 working tree.
2816
2773
self.branch.unlock()
2819
def get_conflicted_stem(path):
2820
for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
2821
if path.endswith(suffix):
2822
return path[:-len(suffix)]
2825
class WorkingTreeFormat(object):
2776
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2777
"""Registry for working tree formats."""
2779
def __init__(self, other_registry=None):
2780
super(WorkingTreeFormatRegistry, self).__init__(other_registry)
2781
self._default_format = None
2783
def get_default(self):
2784
"""Return the current default format."""
2785
return self._default_format
2787
def set_default(self, format):
2788
self._default_format = format
2791
format_registry = WorkingTreeFormatRegistry()
2794
class WorkingTreeFormat(controldir.ControlComponentFormat):
2826
2795
"""An encapsulation of the initialization and open routines for a format.
2828
2797
Formats provide three things:
2840
2809
object will be created every time regardless.
2843
_default_format = None
2844
"""The default format used for new trees."""
2847
"""The known formats."""
2849
2812
requires_rich_root = False
2851
2814
upgrade_recommended = False
2816
requires_normalized_unicode_filenames = False
2818
case_sensitive_filename = "FoRMaT"
2820
missing_parent_conflicts = False
2821
"""If this format supports missing parent conflicts."""
2854
2824
def find_format(klass, a_bzrdir):
2855
2825
"""Return the format for the working tree object in a_bzrdir."""
2857
2827
transport = a_bzrdir.get_workingtree_transport(None)
2858
2828
format_string = transport.get_bytes("format")
2859
return klass._formats[format_string]
2829
return format_registry.get(format_string)
2860
2830
except errors.NoSuchFile:
2861
2831
raise errors.NoWorkingTree(base=transport.base)
2862
2832
except KeyError:
2863
2833
raise errors.UnknownFormatError(format=format_string,
2864
2834
kind="working tree")
2836
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2837
accelerator_tree=None, hardlink=False):
2838
"""Initialize a new working tree in a_bzrdir.
2840
:param a_bzrdir: BzrDir to initialize the working tree in.
2841
:param revision_id: allows creating a working tree at a different
2842
revision than the branch is at.
2843
:param from_branch: Branch to checkout
2844
:param accelerator_tree: A tree which can be used for retrieving file
2845
contents more quickly than the revision tree, i.e. a workingtree.
2846
The revision tree will be used for cases where accelerator_tree's
2847
content is different.
2848
:param hardlink: If true, hard-link files from accelerator_tree,
2851
raise NotImplementedError(self.initialize)
2866
2853
def __eq__(self, other):
2867
2854
return self.__class__ is other.__class__
2892
@symbol_versioning.deprecated_method(
2893
symbol_versioning.deprecated_in((2, 4, 0)))
2903
2894
def register_format(klass, format):
2904
klass._formats[format.get_format_string()] = format
2895
format_registry.register(format)
2898
@symbol_versioning.deprecated_method(
2899
symbol_versioning.deprecated_in((2, 4, 0)))
2900
def register_extra_format(klass, format):
2901
format_registry.register_extra(format)
2904
@symbol_versioning.deprecated_method(
2905
symbol_versioning.deprecated_in((2, 4, 0)))
2906
def unregister_extra_format(klass, format):
2907
format_registry.unregister_extra(format)
2910
@symbol_versioning.deprecated_method(
2911
symbol_versioning.deprecated_in((2, 4, 0)))
2912
def get_formats(klass):
2913
return format_registry._get_all()
2916
@symbol_versioning.deprecated_method(
2917
symbol_versioning.deprecated_in((2, 4, 0)))
2907
2918
def set_default_format(klass, format):
2908
klass._default_format = format
2919
format_registry.set_default(format)
2922
@symbol_versioning.deprecated_method(
2923
symbol_versioning.deprecated_in((2, 4, 0)))
2911
2924
def unregister_format(klass, format):
2912
del klass._formats[format.get_format_string()]
2915
class WorkingTreeFormat2(WorkingTreeFormat):
2916
"""The second working tree format.
2918
This format modified the hash cache from the format 1 hash cache.
2921
upgrade_recommended = True
2923
def get_format_description(self):
2924
"""See WorkingTreeFormat.get_format_description()."""
2925
return "Working tree format 2"
2927
def _stub_initialize_on_transport(self, transport, file_mode):
2928
"""Workaround: create control files for a remote working tree.
2930
This ensures that it can later be updated and dealt with locally,
2931
since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
2932
no working tree. (See bug #43064).
2935
inv = inventory.Inventory()
2936
xml5.serializer_v5.write_inventory(inv, sio, working=True)
2938
transport.put_file('inventory', sio, file_mode)
2939
transport.put_bytes('pending-merges', '', file_mode)
2941
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2942
accelerator_tree=None, hardlink=False):
2943
"""See WorkingTreeFormat.initialize()."""
2944
if not isinstance(a_bzrdir.transport, LocalTransport):
2945
raise errors.NotLocalUrl(a_bzrdir.transport.base)
2946
if from_branch is not None:
2947
branch = from_branch
2949
branch = a_bzrdir.open_branch()
2950
if revision_id is None:
2951
revision_id = _mod_revision.ensure_null(branch.last_revision())
2954
branch.generate_revision_history(revision_id)
2957
inv = inventory.Inventory()
2958
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2964
basis_tree = branch.repository.revision_tree(revision_id)
2965
if basis_tree.inventory.root is not None:
2966
wt.set_root_id(basis_tree.get_root_id())
2967
# set the parent list and cache the basis tree.
2968
if _mod_revision.is_null(revision_id):
2971
parent_trees = [(revision_id, basis_tree)]
2972
wt.set_parent_trees(parent_trees)
2973
transform.build_tree(basis_tree, wt)
2977
super(WorkingTreeFormat2, self).__init__()
2978
self._matchingbzrdir = bzrdir.BzrDirFormat6()
2980
def open(self, a_bzrdir, _found=False):
2981
"""Return the WorkingTree object for a_bzrdir
2983
_found is a private parameter, do not use it. It is used to indicate
2984
if format probing has already been done.
2987
# we are being called directly and must probe.
2988
raise NotImplementedError
2989
if not isinstance(a_bzrdir.transport, LocalTransport):
2990
raise errors.NotLocalUrl(a_bzrdir.transport.base)
2991
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2925
format_registry.remove(format)
2997
2928
class WorkingTreeFormat3(WorkingTreeFormat):
2998
2929
"""The second working tree format updated to record a format marker.
3128
3061
__default_format = WorkingTreeFormat6()
3129
WorkingTreeFormat.register_format(__default_format)
3130
WorkingTreeFormat.register_format(WorkingTreeFormat5())
3131
WorkingTreeFormat.register_format(WorkingTreeFormat4())
3132
WorkingTreeFormat.register_format(WorkingTreeFormat3())
3133
WorkingTreeFormat.set_default_format(__default_format)
3134
# formats which have no format string are not discoverable
3135
# and not independently creatable, so are not registered.
3136
_legacy_formats = [WorkingTreeFormat2(),
3062
format_registry.register_lazy("Bazaar Working Tree Format 4 (bzr 0.15)\n",
3063
"bzrlib.workingtree_4", "WorkingTreeFormat4")
3064
format_registry.register_lazy("Bazaar Working Tree Format 5 (bzr 1.11)\n",
3065
"bzrlib.workingtree_4", "WorkingTreeFormat5")
3066
format_registry.register_lazy("Bazaar Working Tree Format 6 (bzr 1.14)\n",
3067
"bzrlib.workingtree_4", "WorkingTreeFormat6")
3068
format_registry.register(WorkingTreeFormat3())
3069
format_registry.set_default(__default_format)