{"thread":{"id":"39132","subject":"Wrong gitignore precedence?","startedAt":"2015-04-22T06:05:58Z","lastAt":"2015-04-23T12:11:52Z","messageCount":4,"participants":["Yohei Endo","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"259785","messageId":"20150422150558.6326cb6152a306f028fb6ad3@gmail.com","threadId":"39132","inReplyTo":null,"subject":"Wrong gitignore precedence?","fromName":"Yohei Endo","fromEmail":"yoheie@gmail.com","sentAt":"2015-04-22T06:05:58Z","receivedAt":"2015-04-22T06:05:58Z","isPatch":false,"sender":{"key":"yoheie@gmail.com","avatar":null},"body":"Hello All,\n\nI read the document of gitignore (http://git-scm.com/docs/gitignore),\nand learned that $GIT_DIR/info/exclude has higher precedence than\nthe file specified by core.excludesfile.\n\nBut I noticed that patterns in core.excludesfile override patterns in\n$GIT_DIR/info/exclude.\n\nI tested as below:\n\n   1. Make a new git repository for test, and move into the repository.\n      $ git init testrepo\n      $ cd testrepo\n   2. Change core.excludesfile configuration.\n      $ touch ../core_excludesfile\n      $ git config core.excludesfile `realpath ../core_excludesfile`\n   3. Create test~. In each step I check if the file is ignored or not.\n      $ touch test~\n   4. See git status. In this case I expect that test~ should not be ignored.\n      $ git status --ignored\n   5. Change settings in .git/info/exclude.\n      $ echo '*~' > .git/info/exclude\n   6. See git status. In this case I expect that test~ should be ignored.\n      $ git status --ignored\n   7. Change settings in .git/info/exclude and core.excludesfile.\n      $ echo '*~' > ../core_excludesfile\n      $ echo '!*~' > .git/info/exclude\n   8. See git status. In this case I expect that test~ should not be ignored.\n      $ git status --ignored\n   9. Change settings in .git/info/exclude and core.excludesfile\n      $ echo '!*~' > ../core_excludesfile\n      $ echo '*~' > .git/info/exclude\n  10. See git status. In this case I expect that test~ should be ignored.\n      $ git status --ignored\n\nSteps 4. and 6. worked as I expected, but 8. and 10. didn't.\n\nI read the source code of Git, and found out the point that seems to\ncause the problem.\n\nIn dir.c, setup_standard_excludes() adds patterns in .git/info/exclude to\nthe excludes list first, and patterns in core.excludesfile are added next.\n\nIn last_exclude_matching_from_list(), pattern is searched from the end of\nthe list, and the first matching pattern is used. Therefore the patterns\nin core.excludesfile are used in precedence to .git/info/exclude.\n\nTo meet the precedence described in the document of gitignore, I guess\nsetup_standard_excludes() should be fixed so that patterns in\ncore.excludesfile are added to the list before those in\n.git/info/ecdlude are added.\n\nThanks\n\n-- \n  遠藤 陽平 (Yohei Endo)\n    yoheie@gmail.com\n"},{"id":"259817","messageId":"xmqqh9s8dm6f.fsf@gitster.dls.corp.google.com","threadId":"39132","inReplyTo":"20150422150558.6326cb6152a306f028fb6ad3@gmail.com","subject":"Re: Wrong gitignore precedence?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-04-22T18:59:04Z","receivedAt":"2015-04-22T18:59:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Yohei Endo <yoheie@gmail.com> writes:\n\n> I read the document of gitignore (http://git-scm.com/docs/gitignore),\n> and learned that $GIT_DIR/info/exclude has higher precedence than\n> the file specified by core.excludesfile.\n>\n> But I noticed that patterns in core.excludesfile override patterns in\n> $GIT_DIR/info/exclude.\n\nI tend to agree that info/exclude which is per-repository personal\npreference should take precedence over $XDG_HOME/git/ignore which is\na personal preference across repositories that are accessed from\nthat machine.\n\nIt appears that the precedence was screwed-up between these two\nfiles from the very beginning when 896bdfa2 (add: Support specifying\nan excludes file with a configuration variable, 2007-02-27)\nintroduced core.excludesfile variable; seeing that nobody so far\ncomplained with the discrepancy between the documentation and the\nbehaviour, it would indicate either (1) nobody reads the docs, or\n(2) nobody uses both at the same time.\n\nSwapping the order in the code this late in the game after 8 years\nmay affect people who have come to rely on the current behaviour and\nnever read the doc, which is somewhat worrying, though.\n"},{"id":"259851","messageId":"xmqqvbgnderm.fsf@gitster.dls.corp.google.com","threadId":"39132","inReplyTo":"20150422150558.6326cb6152a306f028fb6ad3@gmail.com","subject":"[PATCH] ignore: info/exclude should trump core.excludesfile","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-04-22T21:39:09Z","receivedAt":"2015-04-22T21:39:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"$GIT_DIR/info/exclude and core.excludesfile (which falls back to\n$XDG_HOME/git/ignore) are both ways to override the ignore pattern\nlists given by the project in .gitignore files.  The former, which\nis per-repository personal preference, should take precedence over\nthe latter, which is a personal preference default across different\nrepositories that are accessed from that machine.  The existing\ndocumentation also agrees.\n\nHowever, the precedence order was screwed up between these two from\nthe very beginning when 896bdfa2 (add: Support specifying an\nexcludes file with a configuration variable, 2007-02-27) introduced\ncore.excludesfile variable.\n\nNoticed-by: Yohei Endo <yoheie@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * This is done on an old codebase and may not apply cleanly to more\n   modern codebase easily.\n\n dir.c              | 10 +++++++---\n t/t0008-ignores.sh | 10 ++++++++++\n 2 files changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 23b6de4..e67b6f9 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1530,15 +1530,19 @@ void setup_standard_excludes(struct dir_struct *dir)\n \tchar *xdg_path;\n \n \tdir->exclude_per_dir = \".gitignore\";\n-\tpath = git_path(\"info/exclude\");\n+\n+\t/* core.excludefile defaulting to $XDG_HOME/git/ignore */\n \tif (!excludes_file) {\n \t\thome_config_paths(NULL, &xdg_path, \"ignore\");\n \t\texcludes_file = xdg_path;\n \t}\n-\tif (!access_or_warn(path, R_OK, 0))\n-\t\tadd_excludes_from_file(dir, path);\n \tif (excludes_file && !access_or_warn(excludes_file, R_OK, 0))\n \t\tadd_excludes_from_file(dir, excludes_file);\n+\n+\t/* per repository user preference */\n+\tpath = git_path(\"info/exclude\");\n+\tif (!access_or_warn(path, R_OK, 0))\n+\t\tadd_excludes_from_file(dir, path);\n }\n \n int remove_path(const char *name)\ndiff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh\nindex b4d98e6..38405de 100755\n--- a/t/t0008-ignores.sh\n+++ b/t/t0008-ignores.sh\n@@ -775,4 +775,14 @@ test_expect_success PIPE 'streaming support for --stdin' '\n \techo \"$response\" | grep \"^::\ttwo\"\n '\n \n+test_expect_success 'info/exclude trumps core.excludesfile' '\n+\techo >>global-excludes usually-ignored &&\n+\techo >>.git/info/exclude \"!usually-ignored\" &&\n+\t>usually-ignored &&\n+\techo \"?? usually-ignored\" >expect &&\n+\n+\tgit status --porcelain usually-ignored >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_done\n-- \n2.4.0-rc3-227-gd45ce82\n"},{"id":"259889","messageId":"20150423211152.0fdcbd2cdb48c98d15fe446c@gmail.com","threadId":"39132","inReplyTo":"xmqqh9s8dm6f.fsf@gitster.dls.corp.google.com","subject":"Re: Wrong gitignore precedence?","fromName":"Yohei Endo","fromEmail":"yoheie@gmail.com","sentAt":"2015-04-23T12:11:52Z","receivedAt":"2015-04-23T12:11:52Z","isPatch":false,"sender":{"key":"yoheie@gmail.com","avatar":null},"body":"On Wed, 22 Apr 2015 11:59:04 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> Swapping the order in the code this late in the game after 8 years\n> may affect people who have come to rely on the current behaviour and\n> never read the doc, which is somewhat worrying, though.\n\nI agree. I think the change should be well announced before\nthe fix is applied, like when the implicit value of\npush.default was changed.\n\nThanks.\n-- \n  遠藤 陽平 (Yohei Endo)\n    yoheie@gmail.com\n"}]}