{"thread":{"id":"25259","subject":"[BUG] git clean -X behaviour when .gitignore has sub-directory entries","startedAt":"2010-09-27T14:35:06Z","lastAt":"2010-10-03T19:12:09Z","messageCount":4,"participants":["Jean-Philippe Gariépy","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"151825","messageId":"4CA0AB9A.4050002@nuecho.com","threadId":"25259","inReplyTo":null,"subject":"[BUG] git clean -X behaviour when .gitignore has sub-directory entries","fromName":"Jean-Philippe Gariépy","fromEmail":"jean-philippe.gariepy@nuecho.com","sentAt":"2010-09-27T14:35:06Z","receivedAt":"2010-09-27T14:35:06Z","isPatch":false,"sender":{"key":"jean-philippe.gariepy@nuecho.com","avatar":"https://gravatar.com/avatar/a2b619b19cbd998aee61f61aabcccbfe7775e0862e0bd61e3cef4e2eb8c65563?d=mp&s=160"},"body":"(this is a repost w/ a bit more context)\n\nHi,\n\nContext:\n\"git clean -X\" is really helpful in my projects to mimick a \"make clean\" \n(or more precisely a \"make distclean\") but I believe there is a small \nproblem with the -X option of git clean. I've validated this with other \npeople and they agree it's a bug.\n\nProblem:\nWhen using sub-directory entries in .gitignore, while the entry is \nignored as expected, \"git clean -X\" doesn't clean the ignored sub-directory.\n\n$ git init test\nInitialized empty Git repository in /home/jpgariep/git/test/.git/\n$ cd test/\n$ mkdir -p a/b/c\n$ touch a/b/c/test\n$ echo '/a/b/' > .gitignore\n$ git add .gitignore\n$ git commit -m \"Added .gitignore.\"\n[master (root-commit) 94e2825] Added .gitignore.\n  1 files changed, 1 insertions(+), 0 deletions(-)\n  create mode 100644 .gitignore\n$ git status\n# On branch master\nnothing to commit (working directory clean)\n$ git clean -X -d -f\n$ ls a\nb\n\nWhy is b still there?\n\n\nGit version:\ngit version 1.7.2.3  (but this has been around since 1.6.something)\nTested also with 1.7.3.2.g9027fa (today's HEAD of master branch)\n\nThanks.\n\n-- \nJean-Philippe\n"},{"id":"151855","messageId":"20100927203652.GB11957@burratino","threadId":"25259","inReplyTo":"4CA0AB9A.4050002@nuecho.com","subject":"Re: [BUG] git clean -X behaviour when .gitignore has sub-directory entries","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-09-27T20:36:52Z","receivedAt":"2010-09-27T20:36:52Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nJean-Philippe Gariépy wrote:\n\n> When using sub-directory entries in .gitignore, while the entry is\n> ignored as expected, \"git clean -X\" doesn't clean the ignored\n> sub-directory.\n\nThanks for reporting.\n\n $ cat test.sh\n rm -fr test &&\n git init test &&\n (\n\tcd test &&\n\tmkdir -p a/b/c &&\n\t>a/b/c/f &&\n\techo '/a/b/' >.gitignore &&\n\tgit status -s &&\n\tgit clean -X -d -n &&\n\tgit ls-files -o -i --exclude-standard &&\n\tgit ls-files -o --directory -i --exclude-standard &&\n\tgit clean -X -d -f &&\n\techo ... drumroll ... &&\n\t! test -e a/b/c/f\n )\n $ sh test.sh || echo fail\n Initialized empty Git repository in /tmp/test/.git/\n ?? .gitignore\n ... drumroll ...\n fail\n\nVariations:\n\n 1) echo '/a/' >.gitignore\n 2) echo '/a/b/c/f' >.gitignore\n 3) >a/b/f\n\n(1) does not fail; (2) and (3) still do.\n\nOkay, so why does this happen?  Tracing:\n\n-- 8< --\ndiff --git a/dir.c b/dir.c\nindex 133f472..5707ad0 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -693,6 +693,9 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \t\t\t\t\t  int dtype, struct dirent *de)\n {\n \tint exclude = excluded(dir, path, &dtype);\n+\n+\ttrace_printf(\"treat_one_path: path=%s exclude=%d\\n\", path, exclude);\n+\n \tif (exclude && (dir->flags & DIR_COLLECT_IGNORED)\n \t    && exclude_matches_pathspec(path, *len, simplify))\n \t\tdir_add_ignored(dir, path, *len);\n-- >8 --\n\n $ GIT_TRACE=true PATH=/home/jrn/src/git/bin-wrappers:$PATH sh test.sh \n trace: built-in: git 'init' 'test'\n Initialized empty Git repository in /tmp/test/.git/\n trace: built-in: git 'status' '-s'\n treat_one_path: path=.gitignore exclude=0\n treat_one_path: path=a exclude=0\n treat_one_path: path=a/b exclude=1\n ?? .gitignore\n trace: built-in: git 'clean' '-X' '-d' '-n'\n treat_one_path: path=.gitignore exclude=0\n treat_one_path: path=a exclude=0\n trace: built-in: git 'ls-files' '-o' '-i' '--exclude-standard'\n treat_one_path: path=.gitignore exclude=0\n treat_one_path: path=a exclude=0\n treat_one_path: path=a/b exclude=1\n treat_one_path: path=a/b/c exclude=0\n treat_one_path: path=a/b/c/f exclude=0\n trace: built-in: git 'ls-files' '-o' '--directory' '-i' '--exclude-standard'\n treat_one_path: path=.gitignore exclude=0\n treat_one_path: path=a exclude=0\n trace: built-in: git 'clean' '-X' '-d' '-f'\n treat_one_path: path=.gitignore exclude=0\n treat_one_path: path=a exclude=0\n ... drumroll ...\n $\n\n 1) a/b/f is not actually considered excluded; only its containing\n    directory is.\n\n 2) git clean does not even examine a/b to consider whether to remove\n    it: since a/ does not contain any tracked files, it stopped there.\n\nThe following would cause \"git clean -ndx\" to print more than it\nshould, but hopefully it illustrates the idea.\n\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex b508d2c..91624c2 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -84,8 +84,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \tif (force > 1)\n \t\trm_flags = 0;\n \n-\tdir.flags |= DIR_SHOW_OTHER_DIRECTORIES;\n-\n \tif (read_cache() < 0)\n \t\tdie(\"index file corrupt\");\n \n-- \n"},{"id":"152374","messageId":"4CA8D1B4.1020801@nuecho.com","threadId":"25259","inReplyTo":"20100927203652.GB11957@burratino","subject":"Re: [BUG] git clean -X behaviour when .gitignore has sub-directory entries","fromName":"Jean-Philippe Gariépy","fromEmail":"jean-philippe.gariepy@nuecho.com","sentAt":"2010-10-03T18:55:48Z","receivedAt":"2010-10-03T18:55:48Z","isPatch":false,"sender":{"key":"jean-philippe.gariepy@nuecho.com","avatar":"https://gravatar.com/avatar/a2b619b19cbd998aee61f61aabcccbfe7775e0862e0bd61e3cef4e2eb8c65563?d=mp&s=160"},"body":"  On 09/27/2010 04:36 PM, Jonathan Nieder wrote:\n> ...\n>   1) a/b/f is not actually considered excluded; only its containing\n>      directory is.\n>\n>   2) git clean does not even examine a/b to consider whether to remove\n>      it: since a/ does not contain any tracked files, it stopped there.\n\nOk, thanks for your analysis.  Do you consider it a bug?\n\n\n\n-- \nJean-Philippe\n"},{"id":"152375","messageId":"20101003191209.GA22743@burratino","threadId":"25259","inReplyTo":"4CA8D1B4.1020801@nuecho.com","subject":"Re: [BUG] git clean -X behaviour when .gitignore has sub-directory entries","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-10-03T19:12:09Z","receivedAt":"2010-10-03T19:12:09Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jean-Philippe Gariépy wrote:\n>  On 09/27/2010 04:36 PM, Jonathan Nieder wrote:\n\n>>...\n>>  1) a/b/f is not actually considered excluded; only its containing\n>>     directory is.\n>>\n>>  2) git clean does not even examine a/b to consider whether to remove\n>>     it: since a/ does not contain any tracked files, it stopped there.\n>\n> Ok, thanks for your analysis.  Do you consider it a bug?\n\nYes.\n"}]}