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