2028
all_files = set() # specified and nested files
2029
2029
unknown_nested_files=set()
2030
2030
if to_file is None:
2031
2031
to_file = sys.stdout
2033
files_to_backup = []
2033
2035
def recurse_directory_to_add_files(directory):
2034
2036
# Recurse directory and add all files
2035
2037
# so we can check if they have changed.
2036
2038
for parent_info, file_infos in self.walkdirs(directory):
2037
2039
for relpath, basename, kind, lstat, fileid, kind in file_infos:
2038
2040
# Is it versioned or ignored?
2039
if self.path2id(relpath) or self.is_ignored(relpath):
2041
if self.path2id(relpath):
2040
2042
# Add nested content for deletion.
2041
new_files.add(relpath)
2043
all_files.add(relpath)
2043
# Files which are not versioned and not ignored
2045
# Files which are not versioned
2044
2046
# should be treated as unknown.
2045
unknown_nested_files.add((relpath, None, kind))
2047
files_to_backup.append(relpath)
2047
2049
for filename in files:
2048
2050
# Get file name into canonical form.
2049
2051
abspath = self.abspath(filename)
2050
2052
filename = self.relpath(abspath)
2051
2053
if len(filename) > 0:
2052
new_files.add(filename)
2054
all_files.add(filename)
2053
2055
recurse_directory_to_add_files(filename)
2055
files = list(new_files)
2057
files = list(all_files)
2057
2059
if len(files) == 0:
2058
2060
return # nothing to do
2063
2065
# Bail out if we are going to delete files we shouldn't
2064
2066
if not keep_files and not force:
2065
has_changed_files = len(unknown_nested_files) > 0
2066
if not has_changed_files:
2067
for (file_id, path, content_change, versioned, parent_id, name,
2068
kind, executable) in self.iter_changes(self.basis_tree(),
2069
include_unchanged=True, require_versioned=False,
2070
want_unversioned=True, specific_files=files):
2071
if versioned == (False, False):
2072
# The record is unknown ...
2073
if not self.is_ignored(path[1]):
2074
# ... but not ignored
2075
has_changed_files = True
2077
elif (content_change and (kind[1] is not None) and
2078
osutils.is_inside_any(files, path[1])):
2079
# Versioned and changed, but not deleted, and still
2080
# in one of the dirs to be deleted.
2081
has_changed_files = True
2067
for (file_id, path, content_change, versioned, parent_id, name,
2068
kind, executable) in self.iter_changes(self.basis_tree(),
2069
include_unchanged=True, require_versioned=False,
2070
want_unversioned=True, specific_files=files):
2071
if versioned[0] == False:
2072
# The record is unknown or newly added
2073
files_to_backup.append(path[1])
2074
elif (content_change and (kind[1] is not None) and
2075
osutils.is_inside_any(files, path[1])):
2076
# Versioned and changed, but not deleted, and still
2077
# in one of the dirs to be deleted.
2078
files_to_backup.append(path[1])
2084
if has_changed_files:
2085
# Make delta show ALL applicable changes in error message.
2086
tree_delta = self.changes_from(self.basis_tree(),
2087
require_versioned=False, want_unversioned=True,
2088
specific_files=files)
2089
for unknown_file in unknown_nested_files:
2090
if unknown_file not in tree_delta.unversioned:
2091
tree_delta.unversioned.extend((unknown_file,))
2092
raise errors.BzrRemoveChangedFilesError(tree_delta)
2080
def backup(file_to_backup):
2081
backup_name = self.bzrdir.generate_backup_name(file_to_backup)
2082
osutils.rename(abs_path, self.abspath(backup_name))
2083
return "removed %s (but kept a copy: %s)" % (file_to_backup, backup_name)
2094
2085
# Build inv_delta and delete files where applicable,
2095
2086
# do this before any modifications to inventory.
2119
2110
len(os.listdir(abs_path)) > 0):
2121
2112
osutils.rmtree(abs_path)
2113
message = "deleted %s" % (f,)
2123
message = "%s is not an empty directory "\
2124
"and won't be deleted." % (f,)
2126
osutils.delete_any(abs_path)
2127
message = "deleted %s" % (f,)
2117
if f in files_to_backup:
2120
osutils.delete_any(abs_path)
2121
message = "deleted %s" % (f,)
2128
2122
elif message is not None:
2129
2123
# Only care if we haven't done anything yet.
2130
2124
message = "%s does not exist." % (f,)