{"thread":{"id":"36732","subject":"[PATCH v2] Add an explicit GIT_DIR to the list of excludes","startedAt":"2014-05-22T20:11:17Z","lastAt":"2014-05-23T04:39:35Z","messageCount":2,"participants":["Pasha Bolokhov","Eric Sunshine"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"242524","messageId":"1400789477-27906-1-git-send-email-pasha.bolokhov@gmail.com","threadId":"36732","inReplyTo":null,"subject":"[PATCH v2] Add an explicit GIT_DIR to the list of excludes","fromName":"Pasha Bolokhov","fromEmail":"pasha.bolokhov@gmail.com","sentAt":"2014-05-22T20:11:17Z","receivedAt":"2014-05-22T20:11:17Z","isPatch":true,"sender":{"key":"pasha.bolokhov@gmail.com","avatar":null},"body":"When an explicit '--git-dir' option points to a directory inside\nthe work tree, git treats it as if it were any other directory.\nIn particular, 'git status' lists it as untracked, while 'git add -A'\nstages the metadata directory entirely\n\nAdd GIT_DIR to the list of excludes in setup_standard_excludes(),\nwhile checking that GIT_DIR is not just '.git', in which case it\nwould be ignored by default, and that GIT_DIR is inside GIT_WORK_TREE\n\nAlthough an analogous comparison of any given path against '.git'\nis done in treat_path(), this does not seem to be the right place\nto compare against GIT_DIR. Instead, the excludes provide an\neffective mechanism of ignoring a file/directory, and adding GIT_DIR\nas an exclude is equivalent of putting it into '.gitignore'. Function\nsetup_standard_excludes() was chosen because that is the place where\nthe excludes are initialized by the commands that are concerned about\nexcludes\n\nSigned-off-by: Pasha Bolokhov <pasha.bolokhov@gmail.com>\n---\nAdd a test and change the documentation which now reflects the\nfact that 'setup_standard_excludes()' has to be called for\nthe setup purposes\n\n Documentation/technical/api-directory-listing.txt |  4 +-\n dir.c                                             | 20 ++++++++\n t/t2205-add-gitdir.sh                             | 61 +++++++++++++++++++++++\n 3 files changed, 83 insertions(+), 2 deletions(-)\n create mode 100755 t/t2205-add-gitdir.sh\n\ndiff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt\nindex 7f8e78d..fd4a178 100644\n--- a/Documentation/technical/api-directory-listing.txt\n+++ b/Documentation/technical/api-directory-listing.txt\n@@ -90,8 +90,8 @@ marked. If you to exclude files, make sure you have loaded index first.\n   `add_exclude()`.\n \n * To add patterns from a file (e.g. `.git/info/exclude`), call\n-  `add_excludes_from_file()` , and/or set `dir.exclude_per_dir`.  A\n-  short-hand function `setup_standard_excludes()` can be used to set\n+  `add_excludes_from_file()` , and/or set `dir.exclude_per_dir`.  The\n+  short-hand function `setup_standard_excludes()` must be used to set\n   up the standard set of exclude settings.\n \n * Set options described in the Data Structure section above.\ndiff --git a/dir.c b/dir.c\nindex 98bb50f..07e36f3 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1588,6 +1588,26 @@ void setup_standard_excludes(struct dir_struct *dir)\n {\n \tconst char *path;\n \tchar *xdg_path;\n+\tconst char *gitdir = get_git_dir();\n+\n+\t/* Add git directory to the ignores first */\n+\tif (strcmp(gitdir, \".git\") != 0) { /* \"--git-dir\" has been given */\n+\t\tchar ngit[PATH_MAX + 1];\n+\n+\t\t/*\n+\t\t * See if GIT_DIR is inside the work tree; need to normalize\n+\t\t * 'gitdir' but 'get_git_work_tree()' always appears absolute\n+\t\t * and normalized\n+\t\t */\n+\t\tnormalize_path_copy(ngit, real_path(absolute_path(gitdir)));\n+\n+\t\tif (dir_inside_of(ngit, get_git_work_tree()) >= 0) {\n+\t\t\tstruct exclude_list *el = add_exclude_list(dir, EXC_CMDL,\n+\t\t\t\t\t\t\t\"--git-dir option\");\n+\n+\t\t\tadd_exclude(gitdir, \"\", 0, el, 0);\n+\t\t}\n+\t}\n \n \tdir->exclude_per_dir = \".gitignore\";\n \tpath = git_path(\"info/exclude\");\ndiff --git a/t/t2205-add-gitdir.sh b/t/t2205-add-gitdir.sh\nnew file mode 100755\nindex 0000000..3c6b853\n--- /dev/null\n+++ b/t/t2205-add-gitdir.sh\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Pasha Bolokhov\n+#\n+\n+test_description='alternative repository path specified by --git-dir is ignored by add and status'\n+\n+. ./test-lib.sh\n+\n+test_expect_success \"setup\" '\n+\tgit --git-dir=meta init &&\n+\tfor f in a b c d\n+\tdo\n+\t\techo \"DATA\" > \"$f\" || exit 1\n+\tdone &&\n+\tmkdir subdir1 &&\n+\tfor f in e f g h\n+\tdo\n+\t\techo \"MORE DATA\" > \"subdir1/$f\" || exit 1\n+\tdone &&\n+\tmkdir subdir1/meta &&\n+\techo \"EVEN more Data\" > subdir1/meta/aa &&\n+\tmkdir subdir1/ssubdir subdir1/ssubdir/meta &&\n+\techo \"So much more data\" > subdir1/ssubdir/meta/aaa\n+'\n+\n+test_expect_success \"'git status' ignores the repository directory\" '\n+\tgit --git-dir=meta --work-tree=. status > status.out &&\n+\ttest_might_fail grep meta status.out > out &&\n+\t! test -s out\n+'\n+\n+test_expect_success \"'git add -A' ignores the repository directory\" '\n+\tgit --git-dir=meta --work-tree=. add -A &&\n+\tgit --git-dir=meta --work-tree=. status --porcelain > status1.out &&\n+\ttest_might_fail grep meta status1.out > out1 &&\n+\t! test -s out1\n+'\n+\n+test_expect_success \"'git status' acknowledges files 'meta' if repository is not within work tree\" '\n+\ttest_might_fail rm -rf meta/ &&\n+\t(\n+\t\tcd subdir1 &&\n+\t\tgit --git-dir=../meta init\n+\t\tgit --git-dir=../meta --work-tree=. status --porcelain > status2.out &&\n+\t\ttest_might_fail grep meta status2.out > out2 &&\n+\t\ttest -s out2\n+\t)\n+'\n+\n+test_expect_success \"'git add -A' adds 'meta' if the repository is outside the work tree\" '\n+\t(\n+\t\tcd subdir1 &&\n+\t\tgit --git-dir=../meta --work-tree=. add -A &&\n+\t\tgit --git-dir=../meta --work-tree=. status --porcelain > status3.out &&\n+\t\ttest_might_fail grep meta status3.out > out3 &&\n+\t\ttest -s out3\n+\t)\n+'\n+\n+test_done\n-- \n1.9.1\n"},{"id":"242551","messageId":"CAPig+cTZuxd7vFdoLDb=_CUuoaKbHLKRftvBJd6XQDD_5R5+tA@mail.gmail.com","threadId":"36732","inReplyTo":"1400789477-27906-1-git-send-email-pasha.bolokhov@gmail.com","subject":"Re: [PATCH v2] Add an explicit GIT_DIR to the list of excludes","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-05-23T04:39:35Z","receivedAt":"2014-05-23T04:39:35Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, May 22, 2014 at 4:11 PM, Pasha Bolokhov\n<pasha.bolokhov@gmail.com> wrote:\n> diff --git a/t/t2205-add-gitdir.sh b/t/t2205-add-gitdir.sh\n> new file mode 100755\n> index 0000000..3c6b853\n> --- /dev/null\n> +++ b/t/t2205-add-gitdir.sh\n> @@ -0,0 +1,61 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2014 Pasha Bolokhov\n> +#\n> +\n> +test_description='alternative repository path specified by --git-dir is ignored by add and status'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success \"setup\" '\n> +       git --git-dir=meta init &&\n> +       for f in a b c d\n> +       do\n> +               echo \"DATA\" > \"$f\" || exit 1\n\nOn this project, it's customary to say 'foo >bar' (no whitespace after\n'>'). Ditto for the rest of the file.\n\n> +       done &&\n> +       mkdir subdir1 &&\n> +       for f in e f g h\n> +       do\n> +               echo \"MORE DATA\" > \"subdir1/$f\" || exit 1\n> +       done &&\n> +       mkdir subdir1/meta &&\n> +       echo \"EVEN more Data\" > subdir1/meta/aa &&\n> +       mkdir subdir1/ssubdir subdir1/ssubdir/meta &&\n> +       echo \"So much more data\" > subdir1/ssubdir/meta/aaa\n> +'\n> +\n> +test_expect_success \"'git status' acknowledges files 'meta' if repository is not within work tree\" '\n> +       test_might_fail rm -rf meta/ &&\n> +       (\n> +               cd subdir1 &&\n> +               git --git-dir=../meta init\n\nBroken &&-chain.\n\n> +               git --git-dir=../meta --work-tree=. status --porcelain > status2.out &&\n> +               test_might_fail grep meta status2.out > out2 &&\n> +               test -s out2\n> +       )\n> +'\n> +\n> +test_done\n> --\n> 1.9.1\n"}]}