Merge branch 'sl/clean-d-ignored-fix'
"git clean -d" used to clean directories that has ignored files, even though the command should not lose ignored ones without "-x". "git status --ignored" did not list ignored and untracked files without "-uall". These have been corrected. * sl/clean-d-ignored-fix: clean: teach clean -d to preserve ignored paths dir: expose cmp_name() and check_contains() dir: hide untracked contents of untracked dirs dir: recurse into untracked dirs for ignored files t7061: status --ignored should search untracked dirs t7300: clean -d should skip dirs with ignored files
This commit is contained in:
@ -857,6 +857,38 @@ static void interactive_main_loop(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void correct_untracked_entries(struct dir_struct *dir)
|
||||
{
|
||||
int src, dst, ign;
|
||||
|
||||
for (src = dst = ign = 0; src < dir->nr; src++) {
|
||||
/* skip paths in ignored[] that cannot be inside entries[src] */
|
||||
while (ign < dir->ignored_nr &&
|
||||
0 <= cmp_dir_entry(&dir->entries[src], &dir->ignored[ign]))
|
||||
ign++;
|
||||
|
||||
if (ign < dir->ignored_nr &&
|
||||
check_dir_entry_contains(dir->entries[src], dir->ignored[ign])) {
|
||||
/* entries[src] contains an ignored path, so we drop it */
|
||||
free(dir->entries[src]);
|
||||
} else {
|
||||
struct dir_entry *ent = dir->entries[src++];
|
||||
|
||||
/* entries[src] does not contain an ignored path, so we keep it */
|
||||
dir->entries[dst++] = ent;
|
||||
|
||||
/* then discard paths in entries[] contained inside entries[src] */
|
||||
while (src < dir->nr &&
|
||||
check_dir_entry_contains(ent, dir->entries[src]))
|
||||
free(dir->entries[src++]);
|
||||
|
||||
/* compensate for the outer loop's loop control */
|
||||
src--;
|
||||
}
|
||||
}
|
||||
dir->nr = dst;
|
||||
}
|
||||
|
||||
int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, res;
|
||||
@ -916,6 +948,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
|
||||
dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
|
||||
|
||||
if (remove_directories)
|
||||
dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;
|
||||
|
||||
if (read_cache() < 0)
|
||||
die(_("index file corrupt"));
|
||||
|
||||
@ -931,6 +966,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
prefix, argv);
|
||||
|
||||
fill_directory(&dir, &the_index, &pathspec);
|
||||
correct_untracked_entries(&dir);
|
||||
|
||||
for (i = 0; i < dir.nr; i++) {
|
||||
struct dir_entry *ent = dir.entries[i];
|
||||
@ -958,6 +994,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
string_list_append(&del_list, rel);
|
||||
}
|
||||
|
||||
for (i = 0; i < dir.nr; i++)
|
||||
free(dir.entries[i]);
|
||||
|
||||
for (i = 0; i < dir.ignored_nr; i++)
|
||||
free(dir.ignored[i]);
|
||||
|
||||
if (interactive && del_list.nr > 0)
|
||||
interactive_main_loop();
|
||||
|
||||
|
Reference in New Issue
Block a user