Re: [BUG] git clean -X skips a directory containing only ignored files
From: Paul Berry <hidden>
Date: 2016-06-15 22:52:54
On 31 January 2012 06:47, Michael Schubert [off-list ref] wrote:
On 01/31/2012 12:36 AM, Paul Berry wrote:quoted
I am trying to use "git clean -X" to remove object files (which are gitignored) from my source tree, but it appears to miss object files that are in a subdirectory without any git-tracked files: $ git init test Initialized empty Git repository in /home/pberry/tmp/test/.git/ $ cd test $ mkdir foo $ touch foo/bar.o $ echo '*.o' > .gitignore $ git add .gitignore $ git commit -mgitignore [master (root-commit) 6b5ffcb] gitignore 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 .gitignore $ git status # On branch master nothing to commit (working directory clean) $ git clean -d -X -f $ ls foo bar.o It seems to me that bar.o should have been removed, because according to the git-clean docs, -X means "Remove only files ignored by git", and bar.o is definitely being ignored by git. It looks like a very similar bug was reported back in 2010, but not fixed: http://git.661346.n2.nabble.com/BUG-git-clean-X-behaviour-when-gitignore-has-sub-directory-entries-td5575307.html. I've confirmed that the workaround mentioned by Jonathan Nieder in that thread fixes my problem too (removing "dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;" from builtin/clean.c). However I'm guessing from Jonathan's comments that it would be better to fix this bug elsewhere (somewhere in dir.c perhaps).Removing DIR_SHOW_OTHER_DIRECTORIES just happens to not trigger this particular "bug" but breaks pretty much everything else.
Yeah, I had a feeling that might be the case.
quoted hunk ↗ jump to hunk
As a workaround, you could explicitly add the directory to your gitignore file. Here's a test: -- >8 -- Subject: [PATCH] t7300-clean: show known breakage with "git clean -d -X" "git clean -d -X" fails for directories containing only untracked files. Example: $ ls -R . .: foo ./foo: bar.o $ cat .gitignore *.o $ git clean -d -X -f $ ! test -d foo || echo fail Reported-by: Paul Berry <redacted> Signed-off-by: Michael Schubert <redacted> --- t/t7300-clean.sh | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 800b536..0b6d545 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh@@ -332,6 +332,13 @@ test_expect_success 'git clean -d -X' '' +test_expect_failure 'git clean -d -X' ' + mkdir -p a/b && + touch a/b/c.o && + git clean -d -X && + ! test -d a
Thanks for the test case. BTW, you might consider changing this last line to "! test -f a/b/c.o". Reasoning: it is clear from the docs that c.o should be removed by "git clean -X" (since c.o is an ignored file). It is less clear whether the directories a and a/b should be removed by "git clean -X", since those directories are not in themselves ignored, only their contents.
+' + test_expect_success 'clean.requireForce defaults to true' ' git config --unset clean.requireForce && -- 1.7.9.174.g356eff6