{"thread":{"id":"28018","subject":"[PATCH v2 0/6] git-check-attr should work for relative paths","startedAt":"2011-08-04T04:47:42Z","lastAt":"2011-08-04T04:47:48Z","messageCount":7,"participants":["Michael Haggerty"],"isPatch":true,"patchVersion":2,"patchTotal":6},"messages":[{"id":"172878","messageId":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":null,"subject":"[PATCH v2 0/6] git-check-attr should work for relative paths","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:42Z","receivedAt":"2011-08-04T04:47:42Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This is a reroll of the earlier RFC.  It must be applied on top of\n\"Add --all option to git-check-attr\" v3.\n\nThis re-roll differs in the following ways from the RFC:\n\n* Adjusted for changes between the \"--all\" patch series v2 -> v3.\n\n* Fixed some C problems found by Junio.\n\n\nCurrently, git-check-attr gets confused if it is passed certain types\nof unnormalized paths or is invoked from a non-top-level directory.\nFor example, using the test repo created by t0003-attributes.sh,\ninquiring about a path that starts with \"./\" causes git-check-attr to\nemit a spurious warning:\n\n    $ git check-attr test ./f\n    [attr]notest !test\n     not allowed: ./.gitattributes:1\n    ./f: test: f\n    $ git check-attr test ./a/i\n    [attr]notest !test\n     not allowed: ./.gitattributes:1\n    ./a/i: test: a/i\n\nIn these cases it seems to find the right values, even including the\napplication of macros from the top-level .gitattributes file.  (My\nguess is that it is loading the top-level .gitattributes file\ntwice--once as a top-level file, and once believing that it is in a\nsubdirectory.)\n\nInvoking git-check-attr from a subdirectory using a relative path\ngives incorrect answers; for example:\n\n    $ (cd a; git check-attr test i )\n    i: test: unspecified\n\n(On the other hand, if invoked using the full path of a file, it\n\"works\":\n\n    $ (cd a; git check-attr test a/i )\n    a/i: test: a/i\n\n.)  I think that this behavior is confusing and inconsistent with\nother git commands.  It is also inconsistent with the behavior of\n.gitignore, which works from subdirectories.\n\nThe patches in this series add tests demonstrating the problem,\npropose a possible solution, and add a couple of subcommands to\ntest-path-utils.\n\nThe changes to test-path-utils helped me figure out how the\ncorresponding functions work (comments? we don't need no stinkin'\ncomments) but they are not used anywhere.  Take 'em or leave 'em.\n\n\nMichael Haggerty (6):\n  git-check-attr: test that no output is written to stderr\n  git-check-attr: Demonstrate problems with unnormalized paths\n  git-check-attr: Demonstrate problems with relative paths\n  git-check-attr: Normalize paths\n  test-path-utils: Add subcommand \"absolute_path\"\n  test-path-utils: Add subcommand \"prefix_path\"\n\n builtin/check-attr.c  |   20 ++++++++++++--------\n t/t0003-attributes.sh |   29 ++++++++++++++++++++++++++---\n test-path-utils.c     |   22 ++++++++++++++++++++++\n 3 files changed, 60 insertions(+), 11 deletions(-)\n\n-- \n1.7.6.8.gd2879\n"},{"id":"172883","messageId":"1312433268-11385-2-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 1/6] git-check-attr: test that no output is written to stderr","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:43Z","receivedAt":"2011-08-04T04:47:43Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n t/t0003-attributes.sh |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 5acb2d5..4f2fbc0 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -9,9 +9,10 @@ attr_check () {\n \tpath=\"$1\"\n \texpect=\"$2\"\n \n-\tgit check-attr test -- \"$path\" >actual &&\n+\tgit check-attr test -- \"$path\" >actual 2>err &&\n \techo \"$path: test: $2\" >expect &&\n-\ttest_cmp expect actual\n+\ttest_cmp expect actual &&\n+\ttest_line_count = 0 err\n \n }\n \n-- \n1.7.6.8.gd2879\n"},{"id":"172879","messageId":"1312433268-11385-3-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 2/6] git-check-attr: Demonstrate problems with unnormalized paths","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:44Z","receivedAt":"2011-08-04T04:47:44Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n t/t0003-attributes.sh |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 4f2fbc0..43957ea 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -93,6 +93,15 @@ test_expect_success 'attribute test' '\n \n '\n \n+test_expect_failure 'unnormalized paths' '\n+\n+\tattr_check ./f f &&\n+\tattr_check ./a/g a/g &&\n+\tattr_check a/./g a/g &&\n+\tattr_check a/c/../b/g a/b/g\n+\n+'\n+\n test_expect_success 'core.attributesfile' '\n \tattr_check global unspecified &&\n \tgit config core.attributesfile \"$HOME/global-gitattributes\" &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172881","messageId":"1312433268-11385-4-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 3/6] git-check-attr: Demonstrate problems with relative paths","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:45Z","receivedAt":"2011-08-04T04:47:45Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n t/t0003-attributes.sh |   15 ++++++++++++++-\n 1 files changed, 14 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 43957ea..f6cf77d 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -19,7 +19,7 @@ attr_check () {\n \n test_expect_success 'setup' '\n \n-\tmkdir -p a/b/d a/c &&\n+\tmkdir -p a/b/d a/c b &&\n \t(\n \t\techo \"[attr]notest !test\"\n \t\techo \"f\ttest=f\"\n@@ -102,6 +102,19 @@ test_expect_failure 'unnormalized paths' '\n \n '\n \n+test_expect_failure 'relative paths' '\n+\n+\t(cd a && attr_check ../f f) &&\n+\t(cd a && attr_check f f) &&\n+\t(cd a && attr_check i a/i) &&\n+\t(cd a && attr_check g a/g) &&\n+\t(cd a && attr_check b/g a/b/g) &&\n+\t(cd b && attr_check ../a/f f) &&\n+\t(cd b && attr_check ../a/g a/g) &&\n+\t(cd b && attr_check ../a/b/g a/b/g)\n+\n+'\n+\n test_expect_success 'core.attributesfile' '\n \tattr_check global unspecified &&\n \tgit config core.attributesfile \"$HOME/global-gitattributes\" &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172882","messageId":"1312433268-11385-5-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 4/6] git-check-attr: Normalize paths","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:46Z","receivedAt":"2011-08-04T04:47:46Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Normalize the path arguments (relative to the working tree root, if\napplicable) before looking up their attributes.  This requires passing\nthe prefix down the call chain.\n\nThis fixes two test cases for different reasons:\n\n* \"unnormalized paths\" is fixed because the .gitattribute-file-seeking\n  code is not confused into reading the top-level file twice.\n\n* \"relative paths\" is fixed because the canonical pathnames are passed\n  to get_check_attr() or get_all_attrs(), allowing them to match the\n  pathname patterns as expected.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n builtin/check-attr.c  |   20 ++++++++++++--------\n t/t0003-attributes.sh |    4 ++--\n 2 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 6b16368..708988a 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -41,22 +41,26 @@ static void output_attr(int cnt, struct git_attr_check *check,\n \t}\n }\n \n-static void check_attr(int cnt, struct git_attr_check *check,\n-\tconst char *file)\n+static void check_attr(const char *prefix, int cnt,\n+\tstruct git_attr_check *check, const char *file)\n {\n+\tchar *full_path =\n+\t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n \tif (check != NULL) {\n-\t\tif (git_check_attr(file, cnt, check))\n+\t\tif (git_check_attr(full_path, cnt, check))\n \t\t\tdie(\"git_check_attr died\");\n \t\toutput_attr(cnt, check, file);\n \t} else {\n-\t\tif (git_all_attrs(file, &cnt, &check))\n+\t\tif (git_all_attrs(full_path, &cnt, &check))\n \t\t\tdie(\"git_all_attrs died\");\n \t\toutput_attr(cnt, check, file);\n \t\tfree(check);\n \t}\n+\tfree(full_path);\n }\n \n-static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n+static void check_attr_stdin_paths(const char *prefix, int cnt,\n+\tstruct git_attr_check *check)\n {\n \tstruct strbuf buf, nbuf;\n \tint line_termination = null_term_line ? 0 : '\\n';\n@@ -70,7 +74,7 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n \t\t\t\tdie(\"line is badly quoted\");\n \t\t\tstrbuf_swap(&buf, &nbuf);\n \t\t}\n-\t\tcheck_attr(cnt, check, buf.buf);\n+\t\tcheck_attr(prefix, cnt, check, buf.buf);\n \t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \t}\n \tstrbuf_release(&buf);\n@@ -154,10 +158,10 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (stdin_paths)\n-\t\tcheck_attr_stdin_paths(cnt, check);\n+\t\tcheck_attr_stdin_paths(prefix, cnt, check);\n \telse {\n \t\tfor (i = filei; i < argc; i++)\n-\t\t\tcheck_attr(cnt, check, argv[i]);\n+\t\t\tcheck_attr(prefix, cnt, check, argv[i]);\n \t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \t}\n \treturn 0;\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex f6cf77d..ae2f1da 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -93,7 +93,7 @@ test_expect_success 'attribute test' '\n \n '\n \n-test_expect_failure 'unnormalized paths' '\n+test_expect_success 'unnormalized paths' '\n \n \tattr_check ./f f &&\n \tattr_check ./a/g a/g &&\n@@ -102,7 +102,7 @@ test_expect_failure 'unnormalized paths' '\n \n '\n \n-test_expect_failure 'relative paths' '\n+test_expect_success 'relative paths' '\n \n \t(cd a && attr_check ../f f) &&\n \t(cd a && attr_check f f) &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172884","messageId":"1312433268-11385-6-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 5/6] test-path-utils: Add subcommand \"absolute_path\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:47Z","receivedAt":"2011-08-04T04:47:47Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n test-path-utils.c |    9 +++++++++\n 1 files changed, 9 insertions(+), 0 deletions(-)\n\ndiff --git a/test-path-utils.c b/test-path-utils.c\nindex e767159..a410e30 100644\n--- a/test-path-utils.c\n+++ b/test-path-utils.c\n@@ -20,6 +20,15 @@ int main(int argc, char **argv)\n \t\treturn 0;\n \t}\n \n+\tif (argc >= 2 && !strcmp(argv[1], \"absolute_path\")) {\n+\t\twhile (argc > 2) {\n+\t\t\tputs(absolute_path(argv[2]));\n+\t\t\targc--;\n+\t\t\targv++;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n \tif (argc == 4 && !strcmp(argv[1], \"longest_ancestor_length\")) {\n \t\tint len = longest_ancestor_length(argv[2], argv[3]);\n \t\tprintf(\"%d\\n\", len);\n-- \n1.7.6.8.gd2879\n"},{"id":"172880","messageId":"1312433268-11385-7-git-send-email-mhagger@alum.mit.edu","threadId":"28018","inReplyTo":"1312433268-11385-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 6/6] test-path-utils: Add subcommand \"prefix_path\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T04:47:48Z","receivedAt":"2011-08-04T04:47:48Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n test-path-utils.c |   13 +++++++++++++\n 1 files changed, 13 insertions(+), 0 deletions(-)\n\ndiff --git a/test-path-utils.c b/test-path-utils.c\nindex a410e30..3bc20e9 100644\n--- a/test-path-utils.c\n+++ b/test-path-utils.c\n@@ -35,6 +35,19 @@ int main(int argc, char **argv)\n \t\treturn 0;\n \t}\n \n+\tif (argc >= 4 && !strcmp(argv[1], \"prefix_path\")) {\n+\t\tchar *prefix = argv[2];\n+\t\tint prefix_len = strlen(prefix);\n+\t\tint nongit_ok;\n+\t\tsetup_git_directory_gently(&nongit_ok);\n+\t\twhile (argc > 3) {\n+\t\t\tputs(prefix_path(prefix, prefix_len, argv[3]));\n+\t\t\targc--;\n+\t\t\targv++;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n \tif (argc == 4 && !strcmp(argv[1], \"strip_path_suffix\")) {\n \t\tchar *prefix = strip_path_suffix(argv[2], argv[3]);\n \t\tprintf(\"%s\\n\", prefix ? prefix : \"(null)\");\n-- \n1.7.6.8.gd2879\n"}]}