From b3487ccc0bffc28e134333b164d0d84fdd15d9f4 Mon Sep 17 00:00:00 2001 From: Samuel Lijin Date: Thu, 18 May 2017 04:21:49 -0400 Subject: t7300: clean -d should skip dirs with ignored files If git sees a directory which contains only untracked and ignored files, clean -d should not remove that directory. It was recently discovered that this is *not* true of git clean -d, and it's possible that this has never worked correctly; this test and its accompanying patch series aims to fix that. Signed-off-by: Samuel Lijin Signed-off-by: Junio C Hamano --- t/t7300-clean.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 't') diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index b89fd2a6ad..3a2d709c29 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -653,4 +653,20 @@ test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir) test_path_is_dir foobar ' +test_expect_failure 'git clean -d skips untracked dirs containing ignored files' ' + echo /foo/bar >.gitignore && + echo ignoreme >>.gitignore && + rm -rf foo && + mkdir -p foo/a/aa/aaa foo/b/bb/bbb && + touch foo/bar foo/baz foo/a/aa/ignoreme foo/b/ignoreme foo/b/bb/1 foo/b/bb/2 && + git clean -df && + test_path_is_dir foo && + test_path_is_file foo/bar && + test_path_is_missing foo/baz && + test_path_is_file foo/a/aa/ignoreme && + test_path_is_missing foo/a/aa/aaa && + test_path_is_file foo/b/ignoreme && + test_path_is_missing foo/b/bb +' + test_done -- cgit v1.2.3 From 0a81d4a55917514091727696a09ac649d03b57ff Mon Sep 17 00:00:00 2001 From: Samuel Lijin Date: Thu, 18 May 2017 04:21:50 -0400 Subject: t7061: status --ignored should search untracked dirs Per eb8c5b87, `status --ignored` by design does not list ignored files if they are in a directory which contains only ignored and untracked files (which is itself considered to be untracked) without `-uall`. This does not make sense for `--ignored`, which claims to "Show ignored files as well." Thus we revisit eb8c5b87 and decide that for such directories, `status --ignored` will list the directory as untracked *and* list all ignored files within said directory even without `-uall`. Signed-off-by: Samuel Lijin Signed-off-by: Junio C Hamano --- t/t7061-wtstatus-ignore.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index cdc0747bf0..15e7592b6b 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -9,9 +9,10 @@ cat >expected <<\EOF ?? actual ?? expected ?? untracked/ +!! untracked/ignored EOF -test_expect_success 'status untracked directory with --ignored' ' +test_expect_failure 'status untracked directory with --ignored' ' echo "ignored" >.gitignore && mkdir untracked && : >untracked/ignored && @@ -20,7 +21,7 @@ test_expect_success 'status untracked directory with --ignored' ' test_cmp expected actual ' -test_expect_success 'same with gitignore starting with BOM' ' +test_expect_failure 'same with gitignore starting with BOM' ' printf "\357\273\277ignored\n" >.gitignore && mkdir -p untracked && : >untracked/ignored && -- cgit v1.2.3 From fb898888491b83c9a3396fb559032ca78807a0c0 Mon Sep 17 00:00:00 2001 From: Samuel Lijin Date: Thu, 18 May 2017 04:21:52 -0400 Subject: dir: hide untracked contents of untracked dirs When we taught read_directory_recursive() to recurse into untracked directories in search of ignored files given DIR_SHOW_IGNORED_TOO, that had the side effect of teaching it to collect the untracked contents of untracked directories. It doesn't always make sense to return these, though (we do need them for `clean -d`), so we introduce a flag (DIR_KEEP_UNTRACKED_CONTENTS) to control whether or not read_directory() strips dir->entries of the untracked contents of untracked dirs. We also introduce check_contains() to check if one dir_entry corresponds to a path which contains the path corresponding to another dir_entry. This also fixes known breakages in t7061, since status --ignored now searches untracked directories for ignored files. Signed-off-by: Samuel Lijin Signed-off-by: Junio C Hamano --- t/t7061-wtstatus-ignore.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index 15e7592b6b..fc6013ba3c 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -12,7 +12,7 @@ cat >expected <<\EOF !! untracked/ignored EOF -test_expect_failure 'status untracked directory with --ignored' ' +test_expect_success 'status untracked directory with --ignored' ' echo "ignored" >.gitignore && mkdir untracked && : >untracked/ignored && @@ -21,7 +21,7 @@ test_expect_failure 'status untracked directory with --ignored' ' test_cmp expected actual ' -test_expect_failure 'same with gitignore starting with BOM' ' +test_expect_success 'same with gitignore starting with BOM' ' printf "\357\273\277ignored\n" >.gitignore && mkdir -p untracked && : >untracked/ignored && -- cgit v1.2.3 From 6b1db43109ab3d4c92e61874cd149779c66016db Mon Sep 17 00:00:00 2001 From: Samuel Lijin Date: Tue, 23 May 2017 06:09:37 -0400 Subject: clean: teach clean -d to preserve ignored paths There is an implicit assumption that a directory containing only untracked and ignored paths should itself be considered untracked. This makes sense in use cases where we're asking if a directory should be added to the git database, but not when we're asking if a directory can be safely removed from the working tree; as a result, clean -d would assume that an "untracked" directory containing ignored paths could be deleted, even though doing so would also remove the ignored paths. To get around this, we teach clean -d to collect ignored paths and skip an untracked directory if it contained an ignored path, instead just removing the untracked contents thereof. To achieve this, cmd_clean() has to collect all untracked contents of untracked directories, in addition to all ignored paths, to determine which untracked dirs must be skipped (because they contain ignored paths) and which ones should *not* be skipped. For this purpose, correct_untracked_entries() is introduced to prune a given dir_struct of untracked entries containing ignored paths and those untracked entries encompassed by the untracked entries which are not pruned away. A memory leak is also fixed in cmd_clean(). This also fixes the known breakage in t7300, since clean -d now skips untracked directories containing ignored paths. Signed-off-by: Samuel Lijin Signed-off-by: Junio C Hamano --- t/t7300-clean.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 3a2d709c29..7b36954d63 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -653,7 +653,7 @@ test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir) test_path_is_dir foobar ' -test_expect_failure 'git clean -d skips untracked dirs containing ignored files' ' +test_expect_success 'git clean -d skips untracked dirs containing ignored files' ' echo /foo/bar >.gitignore && echo ignoreme >>.gitignore && rm -rf foo && -- cgit v1.2.3