Thread (5 messages) flat view 5 messages, 3 authors, 2016-06-15

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help