{"thread":{"id":"27940","subject":"[PATCH v2 00/19] Add --all option to git-check-attr","startedAt":"2011-07-28T04:46:39Z","lastAt":"2011-08-04T03:20:29Z","messageCount":24,"participants":["Michael Haggerty","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":19},"messages":[{"id":"172208","messageId":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":null,"subject":"[PATCH v2 00/19] Add --all option to git-check-attr","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:39Z","receivedAt":"2011-07-28T04:46:39Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This version of the patch series fixes a formatting problem found by\nJunio and mentions in the documentation that \"-a\" means the same as\n\"--all\".\n\nCurrently it is possible to inquire the values of particular\nattributes on particular files, using either the API function\ngit_checkattr() or the command \"git check-attr\".  But it is not\npossible to ask for *all* attributes that are associated with a\nparticular file.  This patch series adds that functionality:\n\n* A new API call git_allattr()\n\n* A new option \"git check-attr --all -- pathnames\"\n\nAlong the way, several small cleanups are made in the general\nneighborhood, including:\n\n* Disallow the empty string as an attribute name\n\n* Provide access to the name attribute of git_attr\n\n* Fail with an error message if no pathnames are provided on the\n  command line (and --stdin is not used)\n\n* If --stdin is used, interpret all command-line arguments as\n  attribute names\n\n* Rename struct git_attr_check to git_attr_value\n\nMost of the patches are hopefully self-explanatory; see the individual\npatch emails for discussion of changes that might potentially be\ncontroversial.\n\nMichael Haggerty (19):\n  doc: Add a link from gitattributes(5) to git-check-attr(1)\n  doc: Correct git_attr() calls in example code\n  Remove anachronism from comment\n  Disallow the empty string as an attribute name\n  git-check-attr: Add missing \"&&\"\n  git-check-attr: Add tests of command-line parsing\n  Provide access to the name attribute of git_attr\n  git-check-attr: Use git_attr_name()\n  Allow querying all attributes on a file\n  git-check-attr: Extract a function output_attr()\n  git-check-attr: Introduce a new variable\n  git-check-attr: Extract a function error_with_usage()\n  git-check-attr: Handle each error separately\n  git-check-attr: Process command-line args more systematically\n  git-check-attr: Error out if no pathnames are specified\n  git-check-attr: Add an --all option to show all attributes\n  git-check-attr: Drive two tests using the same raw data\n  git-check-attr: Fix command-line handling to match docs\n  Rename struct git_attr_check to git_attr_value\n\n Documentation/git-check-attr.txt              |   23 ++++-\n Documentation/gitattributes.txt               |    3 +\n Documentation/technical/api-gitattributes.txt |   66 +++++++++-----\n archive.c                                     |    4 +-\n attr.c                                        |   62 +++++++++++--\n attr.h                                        |   24 ++++-\n builtin/check-attr.c                          |  123 ++++++++++++++++--------\n builtin/pack-objects.c                        |    4 +-\n convert.c                                     |   10 +-\n ll-merge.c                                    |    6 +-\n t/t0003-attributes.sh                         |   61 +++++++++----\n userdiff.c                                    |    2 +-\n ws.c                                          |    4 +-\n 13 files changed, 279 insertions(+), 113 deletions(-)\n\n-- \n1.7.6.8.gd2879\n"},{"id":"172209","messageId":"1311828418-2676-2-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 01/19] doc: Add a link from gitattributes(5) to git-check-attr(1)","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:40Z","receivedAt":"2011-07-28T04:46:40Z","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 Documentation/gitattributes.txt |    3 +++\n 1 files changed, 3 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex 412c55b..3d86434 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -952,6 +952,9 @@ frotz\tunspecified\n ----------------------------------------------------------------\n \n \n+SEE ALSO\n+--------\n+linkgit:git-check-attr[1].\n \n GIT\n ---\n-- \n1.7.6.8.gd2879\n"},{"id":"172210","messageId":"1311828418-2676-3-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 02/19] doc: Correct git_attr() calls in example code","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:41Z","receivedAt":"2011-07-28T04:46:41Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Commit 7fb0eaa2 (2010-01-17) changed git_attr() to take a string\ninstead of a string and a length.  Update the documentation\naccordingly.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/technical/api-gitattributes.txt |   10 +++++-----\n 1 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\nindex 9d97eaa..916720f 100644\n--- a/Documentation/technical/api-gitattributes.txt\n+++ b/Documentation/technical/api-gitattributes.txt\n@@ -11,9 +11,9 @@ Data Structure\n `struct git_attr`::\n \n \tAn attribute is an opaque object that is identified by its name.\n-\tPass the name and its length to `git_attr()` function to obtain\n-\tthe object of this type.  The internal representation of this\n-\tstructure is of no interest to the calling programs.\n+\tPass the name to `git_attr()` function to obtain the object of\n+\tthis type.  The internal representation of this structure is\n+\tof no interest to the calling programs.\n \n `struct git_attr_check`::\n \n@@ -72,8 +72,8 @@ static void setup_check(void)\n {\n \tif (check[0].attr)\n \t\treturn; /* already done */\n-\tcheck[0].attr = git_attr(\"crlf\", 4);\n-\tcheck[1].attr = git_attr(\"ident\", 5);\n+\tcheck[0].attr = git_attr(\"crlf\");\n+\tcheck[1].attr = git_attr(\"ident\");\n }\n ------------\n \n-- \n1.7.6.8.gd2879\n"},{"id":"172211","messageId":"1311828418-2676-4-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 03/19] Remove anachronism from comment","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:42Z","receivedAt":"2011-07-28T04:46:42Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Setting attributes to arbitrary values (\"attribute=value\") is now\nsupported, so it is no longer necessary for this comment to justify\nprohibiting '=' in an attribute name.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n attr.c |    6 ++----\n 1 files changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/attr.c b/attr.c\nindex f6b3f7e..4a1244f 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -50,10 +50,8 @@ static unsigned hash_name(const char *name, int namelen)\n static int invalid_attr_name(const char *name, int namelen)\n {\n \t/*\n-\t * Attribute name cannot begin with '-' and from\n-\t * [-A-Za-z0-9_.].  We'd specifically exclude '=' for now,\n-\t * as we might later want to allow non-binary value for\n-\t * attributes, e.g. \"*.svg\tmerge=special-merge-program-for-svg\"\n+\t * Attribute name cannot begin with '-' and must consist of\n+\t * characters from [-A-Za-z0-9_.].\n \t */\n \tif (*name == '-')\n \t\treturn -1;\n-- \n1.7.6.8.gd2879\n"},{"id":"172212","messageId":"1311828418-2676-5-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 04/19] Disallow the empty string as an attribute name","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:43Z","receivedAt":"2011-07-28T04:46:43Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Previously, it was possible to have a line like \"file.txt =foo\" in a\n.gitattribute file, after which an invocation like \"git check-attr ''\n-- file.txt\" would succeed.  This patch disallows both constructs.\n\nPlease note that any existing .gitattributes file that tries to set an\nempty attribute will now trigger the error message \"error: : not a\nvalid attribute name\" whereas previously the nonsense was allowed\nthrough.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n attr.c                |    2 +-\n t/t0003-attributes.sh |    6 ++++++\n 2 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/attr.c b/attr.c\nindex 4a1244f..b1d1d6d 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -53,7 +53,7 @@ static int invalid_attr_name(const char *name, int namelen)\n \t * Attribute name cannot begin with '-' and must consist of\n \t * characters from [-A-Za-z0-9_.].\n \t */\n-\tif (*name == '-')\n+\tif (namelen <= 0 || *name == '-')\n \t\treturn -1;\n \twhile (namelen--) {\n \t\tchar ch = *name++;\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex ebbc755..8c76b79 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -42,6 +42,12 @@ test_expect_success 'setup' '\n \n '\n \n+test_expect_success 'command line checks' '\n+\n+\ttest_must_fail git check-attr \"\" -- f\n+\n+'\n+\n test_expect_success 'attribute test' '\n \n \tattr_check f f &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172213","messageId":"1311828418-2676-6-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 05/19] git-check-attr: Add missing \"&&\"","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:44Z","receivedAt":"2011-07-28T04:46: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 |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 8c76b79..dae76b3 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -35,7 +35,7 @@ test_expect_success 'setup' '\n \t\techo \"h test=a/b/h\" &&\n \t\techo \"d/* test=a/b/d/*\"\n \t\techo \"d/yes notest\"\n-\t) >a/b/.gitattributes\n+\t) >a/b/.gitattributes &&\n \t(\n \t\techo \"global test=global\"\n \t) >\"$HOME\"/global-gitattributes\n-- \n1.7.6.8.gd2879\n"},{"id":"172214","messageId":"1311828418-2676-7-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 06/19] git-check-attr: Add tests of command-line parsing","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:45Z","receivedAt":"2011-07-28T04:46: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 |    7 +++++++\n 1 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex dae76b3..f1debeb 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -44,6 +44,13 @@ test_expect_success 'setup' '\n \n test_expect_success 'command line checks' '\n \n+\ttest_must_fail git check-attr &&\n+\ttest_must_fail git check-attr -- &&\n+\ttest_must_fail git check-attr -- f &&\n+\techo \"f\" | test_must_fail git check-attr --stdin &&\n+\techo \"f\" | test_must_fail git check-attr --stdin -- f &&\n+\techo \"f\" | test_must_fail git check-attr --stdin test -- f &&\n+\techo \"f\" | test_must_fail git check-attr --stdin test f &&\n \ttest_must_fail git check-attr \"\" -- f\n \n '\n-- \n1.7.6.8.gd2879\n"},{"id":"172215","messageId":"1311828418-2676-8-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 07/19] Provide access to the name attribute of git_attr","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:46Z","receivedAt":"2011-07-28T04:46:46Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"It will be present in any likely future reimplementation, and its\navailability simplifies other code.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/technical/api-gitattributes.txt |    3 ++-\n attr.c                                        |    5 +++++\n attr.h                                        |    7 +++++++\n 3 files changed, 14 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\nindex 916720f..ab3a84d 100644\n--- a/Documentation/technical/api-gitattributes.txt\n+++ b/Documentation/technical/api-gitattributes.txt\n@@ -13,7 +13,8 @@ Data Structure\n \tAn attribute is an opaque object that is identified by its name.\n \tPass the name to `git_attr()` function to obtain the object of\n \tthis type.  The internal representation of this structure is\n-\tof no interest to the calling programs.\n+\tof no interest to the calling programs.  The name of the\n+\tattribute can be retrieved by calling `git_attr_name()`.\n \n `struct git_attr_check`::\n \ndiff --git a/attr.c b/attr.c\nindex b1d1d6d..bfa1f43 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -36,6 +36,11 @@ static int attr_nr;\n static struct git_attr_check *check_all_attr;\n static struct git_attr *(git_attr_hash[HASHSIZE]);\n \n+char *git_attr_name(struct git_attr *attr)\n+{\n+\treturn attr->name;\n+}\n+\n static unsigned hash_name(const char *name, int namelen)\n {\n \tunsigned val = 0, c;\ndiff --git a/attr.h b/attr.h\nindex 8b3f19b..d4f875a 100644\n--- a/attr.h\n+++ b/attr.h\n@@ -29,6 +29,13 @@ struct git_attr_check {\n \tconst char *value;\n };\n \n+/*\n+ * Return the name of the attribute represented by the argument.  The\n+ * return value is a pointer to a null-delimited string that is part\n+ * of the internal data structure; it should not be modified or freed.\n+ */\n+char *git_attr_name(struct git_attr *);\n+\n int git_checkattr(const char *path, int, struct git_attr_check *);\n \n enum git_attr_direction {\n-- \n1.7.6.8.gd2879\n"},{"id":"172217","messageId":"1311828418-2676-9-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 08/19] git-check-attr: Use git_attr_name()","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:47Z","receivedAt":"2011-07-28T04:46: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 builtin/check-attr.c |   13 ++++++-------\n 1 files changed, 6 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 3016d29..5f04126 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -21,7 +21,7 @@ static const struct option check_attr_options[] = {\n };\n \n static void check_attr(int cnt, struct git_attr_check *check,\n-\tconst char** name, const char *file)\n+\tconst char *file)\n {\n \tint j;\n \tif (git_checkattr(file, cnt, check))\n@@ -37,12 +37,11 @@ static void check_attr(int cnt, struct git_attr_check *check,\n \t\t\tvalue = \"unspecified\";\n \n \t\tquote_c_style(file, NULL, stdout, 0);\n-\t\tprintf(\": %s: %s\\n\", name[j], value);\n+\t\tprintf(\": %s: %s\\n\", git_attr_name(check[j].attr), value);\n \t}\n }\n \n-static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,\n-\tconst char** name)\n+static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n {\n \tstruct strbuf buf, nbuf;\n \tint line_termination = null_term_line ? 0 : '\\n';\n@@ -56,7 +55,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, name, buf.buf);\n+\t\tcheck_attr(cnt, check, buf.buf);\n \t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \t}\n \tstrbuf_release(&buf);\n@@ -113,10 +112,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, argv);\n+\t\tcheck_attr_stdin_paths(cnt, check);\n \telse {\n \t\tfor (i = doubledash; i < argc; i++)\n-\t\t\tcheck_attr(cnt, check, argv, argv[i]);\n+\t\t\tcheck_attr(cnt, check, argv[i]);\n \t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \t}\n \treturn 0;\n-- \n1.7.6.8.gd2879\n"},{"id":"172216","messageId":"1311828418-2676-10-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 09/19] Allow querying all attributes on a file","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:48Z","receivedAt":"2011-07-28T04:46:48Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Add a function, git_allattrs(), that reports on all attributes that\nare set on a path.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/technical/api-gitattributes.txt |   45 +++++++++++++++++-------\n attr.c                                        |   43 +++++++++++++++++++++++\n attr.h                                        |    9 +++++\n 3 files changed, 84 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\nindex ab3a84d..640240e 100644\n--- a/Documentation/technical/api-gitattributes.txt\n+++ b/Documentation/technical/api-gitattributes.txt\n@@ -22,19 +22,6 @@ Data Structure\n \tto `git_checkattr()` function, and receives the results.\n \n \n-Calling Sequence\n-----------------\n-\n-* Prepare an array of `struct git_attr_check` to define the list of\n-  attributes you would want to check.  To populate this array, you would\n-  need to define necessary attributes by calling `git_attr()` function.\n-\n-* Call git_checkattr() to check the attributes for the path.\n-\n-* Inspect `git_attr_check` structure to see how each of the attribute in\n-  the array is defined for the path.\n-\n-\n Attribute Values\n ----------------\n \n@@ -58,6 +45,19 @@ If none of the above returns true, `.value` member points at a string\n value of the attribute for the path.\n \n \n+Querying Specific Attributes\n+----------------------------\n+\n+* Prepare an array of `struct git_attr_check` to define the list of\n+  attributes you would want to check.  To populate this array, you would\n+  need to define necessary attributes by calling `git_attr()` function.\n+\n+* Call `git_checkattr()` to check the attributes for the path.\n+\n+* Inspect `git_attr_check` structure to see how each of the attribute in\n+  the array is defined for the path.\n+\n+\n Example\n -------\n \n@@ -109,4 +109,23 @@ static void setup_check(void)\n \t}\n ------------\n \n+\n+Querying All Attributes\n+-----------------------\n+\n+To get the values of all attributes associated with a file:\n+\n+* Call `git_allattrs()`, which returns an array of `git_attr_check`\n+  structures.\n+\n+* Iterate over the `git_attr_check` array to examine the attribute\n+  names and values.  The name of the attribute described by a\n+  `git_attr_check` object can be retrieved via\n+  `git_attr_name(check[i].attr)`.  (Please note that no items will be\n+  returned for unset attributes, so `ATTR_UNSET()` will return false\n+  for all returned `git_array_check` objects.)\n+\n+* Free the `git_array_check` array.\n+\n+\n (JC)\ndiff --git a/attr.c b/attr.c\nindex bfa1f43..9c2fca8 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -737,6 +737,49 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)\n \treturn 0;\n }\n \n+int git_allattrs(const char *path, int *num, struct git_attr_check **check)\n+{\n+\tstruct attr_stack *stk;\n+\tconst char *cp;\n+\tint dirlen, pathlen, i, rem, count, j;\n+\n+\tbootstrap_attr_stack();\n+\tfor (i = 0; i < attr_nr; i++)\n+\t\tcheck_all_attr[i].value = ATTR__UNKNOWN;\n+\n+\tpathlen = strlen(path);\n+\tcp = strrchr(path, '/');\n+\tif (!cp)\n+\t\tdirlen = 0;\n+\telse\n+\t\tdirlen = cp - path;\n+\tprepare_attr_stack(path, dirlen);\n+\trem = attr_nr;\n+\tfor (stk = attr_stack; 0 < rem && stk; stk = stk->prev)\n+\t\trem = fill(path, pathlen, stk, rem);\n+\n+\t/* Count the number of attributes that are set. */\n+\tcount = 0;\n+\tfor (i = 0; i < attr_nr; i++) {\n+\t\tconst char *value = check_all_attr[i].value;\n+\t\tif (value != ATTR__UNSET && value != ATTR__UNKNOWN)\n+\t\t\t++count;\n+\t}\n+\t*num = count;\n+\t*check = xmalloc(sizeof(*check_all_attr) * count);\n+\tj = 0;\n+\tfor (i = 0; i < attr_nr; i++) {\n+\t\tconst char *value = check_all_attr[i].value;\n+\t\tif (value != ATTR__UNSET && value != ATTR__UNKNOWN) {\n+\t\t\t(*check)[j].attr = check_all_attr[i].attr;\n+\t\t\t(*check)[j].value = value;\n+\t\t\t++j;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)\n {\n \tenum git_attr_direction old = direction;\ndiff --git a/attr.h b/attr.h\nindex d4f875a..83202f0 100644\n--- a/attr.h\n+++ b/attr.h\n@@ -38,6 +38,15 @@ char *git_attr_name(struct git_attr *);\n \n int git_checkattr(const char *path, int, struct git_attr_check *);\n \n+/*\n+ * Retrieve all attributes that apply to the specified path.  *num\n+ * will be set the the number of attributes on the path; **check will\n+ * be set to point at a newly-allocated array of git_attr_check\n+ * objects describing the attributes and their values.  *check must be\n+ * free()ed by the caller.\n+ */\n+int git_allattrs(const char *path, int *num, struct git_attr_check **check);\n+\n enum git_attr_direction {\n \tGIT_ATTR_CHECKIN,\n \tGIT_ATTR_CHECKOUT,\n-- \n1.7.6.8.gd2879\n"},{"id":"172222","messageId":"1311828418-2676-11-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 10/19] git-check-attr: Extract a function output_attr()","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:49Z","receivedAt":"2011-07-28T04:46:49Z","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 builtin/check-attr.c |   12 +++++++++---\n 1 files changed, 9 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 5f04126..384c5a6 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -20,12 +20,10 @@ static const struct option check_attr_options[] = {\n \tOPT_END()\n };\n \n-static void check_attr(int cnt, struct git_attr_check *check,\n+static void output_attr(int cnt, struct git_attr_check *check,\n \tconst char *file)\n {\n \tint j;\n-\tif (git_checkattr(file, cnt, check))\n-\t\tdie(\"git_checkattr died\");\n \tfor (j = 0; j < cnt; j++) {\n \t\tconst char *value = check[j].value;\n \n@@ -41,6 +39,14 @@ static void check_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+{\n+\tif (git_checkattr(file, cnt, check))\n+\t\tdie(\"git_checkattr died\");\n+\toutput_attr(cnt, check, file);\n+}\n+\n static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n {\n \tstruct strbuf buf, nbuf;\n-- \n1.7.6.8.gd2879\n"},{"id":"172221","messageId":"1311828418-2676-12-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 11/19] git-check-attr: Introduce a new variable","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:50Z","receivedAt":"2011-07-28T04:46:50Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Avoid reusing variable \"doubledash\" to mean something other than the\nexpected \"position of a double-dash, if any\".\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n builtin/check-attr.c |   13 +++++++------\n 1 files changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 384c5a6..c527078 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -71,7 +71,7 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n-\tint cnt, i, doubledash;\n+\tint cnt, i, doubledash, filei;\n \tconst char *errstr = NULL;\n \n \targc = parse_options(argc, argv, prefix, check_attr_options,\n@@ -92,14 +92,15 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t/* If there is no double dash, we handle only one attribute */\n \tif (doubledash < 0) {\n \t\tcnt = 1;\n-\t\tdoubledash = 0;\n-\t} else\n+\t\tfilei = 1;\n+\t} else {\n \t\tcnt = doubledash;\n-\tdoubledash++;\n+\t\tfilei = doubledash + 1;\n+\t}\n \n \tif (cnt <= 0)\n \t\terrstr = \"No attribute specified\";\n-\telse if (stdin_paths && doubledash < argc)\n+\telse if (stdin_paths && filei < argc)\n \t\terrstr = \"Can't specify files with --stdin\";\n \tif (errstr) {\n \t\terror(\"%s\", errstr);\n@@ -120,7 +121,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \tif (stdin_paths)\n \t\tcheck_attr_stdin_paths(cnt, check);\n \telse {\n-\t\tfor (i = doubledash; i < argc; i++)\n+\t\tfor (i = filei; i < argc; i++)\n \t\t\tcheck_attr(cnt, check, argv[i]);\n \t\tmaybe_flush_or_die(stdout, \"attribute to stdout\");\n \t}\n-- \n1.7.6.8.gd2879\n"},{"id":"172220","messageId":"1311828418-2676-13-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 12/19] git-check-attr: Extract a function error_with_usage()","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:51Z","receivedAt":"2011-07-28T04:46:51Z","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 builtin/check-attr.c |    9 +++++++--\n 1 files changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex c527078..d004222 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -68,6 +68,12 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n \tstrbuf_release(&nbuf);\n }\n \n+static NORETURN void error_with_usage(const char *msg)\n+{\n+\terror(\"%s\", msg);\n+\tusage_with_options(check_attr_usage, check_attr_options);\n+}\n+\n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n@@ -103,8 +109,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \telse if (stdin_paths && filei < argc)\n \t\terrstr = \"Can't specify files with --stdin\";\n \tif (errstr) {\n-\t\terror(\"%s\", errstr);\n-\t\tusage_with_options(check_attr_usage, check_attr_options);\n+\t\terror_with_usage(errstr);\n \t}\n \n \tcheck = xcalloc(cnt, sizeof(*check));\n-- \n1.7.6.8.gd2879\n"},{"id":"172223","messageId":"1311828418-2676-14-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 13/19] git-check-attr: Handle each error separately","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:52Z","receivedAt":"2011-07-28T04:46:52Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This will make the code easier to refactor.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n builtin/check-attr.c |   11 ++++-------\n 1 files changed, 4 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex d004222..de3fef7 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -78,7 +78,6 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n \tstruct git_attr_check *check;\n \tint cnt, i, doubledash, filei;\n-\tconst char *errstr = NULL;\n \n \targc = parse_options(argc, argv, prefix, check_attr_options,\n \t\t\t     check_attr_usage, PARSE_OPT_KEEP_DASHDASH);\n@@ -105,12 +104,10 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (cnt <= 0)\n-\t\terrstr = \"No attribute specified\";\n-\telse if (stdin_paths && filei < argc)\n-\t\terrstr = \"Can't specify files with --stdin\";\n-\tif (errstr) {\n-\t\terror_with_usage(errstr);\n-\t}\n+\t\terror_with_usage(\"No attribute specified\");\n+\n+\tif (stdin_paths && filei < argc)\n+\t\terror_with_usage(\"Can't specify files with --stdin\");\n \n \tcheck = xcalloc(cnt, sizeof(*check));\n \tfor (i = 0; i < cnt; i++) {\n-- \n1.7.6.8.gd2879\n"},{"id":"172218","messageId":"1311828418-2676-15-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 14/19] git-check-attr: Process command-line args more systematically","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:53Z","receivedAt":"2011-07-28T04:46:53Z","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 builtin/check-attr.c |   19 ++++++++++++-------\n 1 files changed, 12 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex de3fef7..e9b827f 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -81,8 +81,6 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, check_attr_options,\n \t\t\t     check_attr_usage, PARSE_OPT_KEEP_DASHDASH);\n-\tif (!argc)\n-\t\tusage_with_options(check_attr_usage, check_attr_options);\n \n \tif (read_cache() < 0) {\n \t\tdie(\"invalid cache\");\n@@ -94,8 +92,17 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\t\tdoubledash = i;\n \t}\n \n-\t/* If there is no double dash, we handle only one attribute */\n-\tif (doubledash < 0) {\n+\t/* Check attribute argument(s): */\n+\tif (doubledash == 0) {\n+\t\terror_with_usage(\"No attribute specified\");\n+\t} else if (doubledash < 0) {\n+\t\t/*\n+\t\t * There is no double dash; treat the first\n+\t\t * argument as an attribute.\n+\t\t */\n+\t\tif (!argc)\n+\t\t\terror_with_usage(\"No attribute specified\");\n+\n \t\tcnt = 1;\n \t\tfilei = 1;\n \t} else {\n@@ -103,9 +110,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\tfilei = doubledash + 1;\n \t}\n \n-\tif (cnt <= 0)\n-\t\terror_with_usage(\"No attribute specified\");\n-\n+\t/* Check file argument(s): */\n \tif (stdin_paths && filei < argc)\n \t\terror_with_usage(\"Can't specify files with --stdin\");\n \n-- \n1.7.6.8.gd2879\n"},{"id":"172224","messageId":"1311828418-2676-16-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 15/19] git-check-attr: Error out if no pathnames are specified","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:54Z","receivedAt":"2011-07-28T04:46:54Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"If no pathnames are passed as command-line arguments and the --stdin\noption is not specified, fail with the error message \"No file\nspecified\".  Add tests of this behavior.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n builtin/check-attr.c  |    9 +++++++--\n t/t0003-attributes.sh |    2 ++\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex e9b827f..6cf6421 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -111,8 +111,13 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t}\n \n \t/* Check file argument(s): */\n-\tif (stdin_paths && filei < argc)\n-\t\terror_with_usage(\"Can't specify files with --stdin\");\n+\tif (stdin_paths) {\n+\t\tif (filei < argc)\n+\t\t\terror_with_usage(\"Can't specify files with --stdin\");\n+\t} else {\n+\t\tif (filei >= argc)\n+\t\t\terror_with_usage(\"No file specified\");\n+\t}\n \n \tcheck = xcalloc(cnt, sizeof(*check));\n \tfor (i = 0; i < cnt; i++) {\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex f1debeb..2254005 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -46,6 +46,8 @@ test_expect_success 'command line checks' '\n \n \ttest_must_fail git check-attr &&\n \ttest_must_fail git check-attr -- &&\n+\ttest_must_fail git check-attr test &&\n+\ttest_must_fail git check-attr test -- &&\n \ttest_must_fail git check-attr -- f &&\n \techo \"f\" | test_must_fail git check-attr --stdin &&\n \techo \"f\" | test_must_fail git check-attr --stdin -- f &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172219","messageId":"1311828418-2676-17-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 16/19] git-check-attr: Add an --all option to show all attributes","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:55Z","receivedAt":"2011-07-28T04:46:55Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Add new usage patterns\n\n    git check-attr [-a | --all] [--] pathname...\n    git check-attr --stdin [-a | --all] < <list-of-paths>\n\nwhich display all attributes associated with the specified file(s).\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/git-check-attr.txt |   16 ++++++++++-\n builtin/check-attr.c             |   52 ++++++++++++++++++++++++++-----------\n t/t0003-attributes.sh            |   24 +++++++++++++++++\n 3 files changed, 74 insertions(+), 18 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 30eca6c..798e5d5 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -9,8 +9,8 @@ git-check-attr - Display gitattributes information\n SYNOPSIS\n --------\n [verse]\n-'git check-attr' attr... [--] pathname...\n-'git check-attr' --stdin [-z] attr... < <list-of-paths>\n+'git check-attr' [-a | --all | attr...] [--] pathname...\n+'git check-attr' --stdin [-z] [-a | --all | attr...] < <list-of-paths>\n \n DESCRIPTION\n -----------\n@@ -19,6 +19,11 @@ For every pathname, this command will list if each attribute is 'unspecified',\n \n OPTIONS\n -------\n+-a, --all::\n+\tList all attributes that are associated with the specified\n+\tpaths.  If this option is used, then 'unspecified' attributes\n+\twill not be included in the output.\n+\n --stdin::\n \tRead file names from stdin instead of from the command-line.\n \n@@ -69,6 +74,13 @@ org/example/MyClass.java: diff: java\n org/example/MyClass.java: myAttr: set\n ---------------\n \n+* Listing all attributes for a file:\n+---------------\n+$ git check-attr --all -- org/example/MyClass.java\n+org/example/MyClass.java: diff: java\n+org/example/MyClass.java: myAttr: set\n+---------------\n+\n * Listing an attribute for multiple files:\n ---------------\n $ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 6cf6421..48834b4 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -4,16 +4,18 @@\n #include \"quote.h\"\n #include \"parse-options.h\"\n \n+static int all_attrs;\n static int stdin_paths;\n static const char * const check_attr_usage[] = {\n-\"git check-attr attr... [--] pathname...\",\n-\"git check-attr --stdin attr... < <list-of-paths>\",\n+\"git check-attr [-a | --all | attr...] [--] pathname...\",\n+\"git check-attr --stdin [-a | --all | attr...] < <list-of-paths>\",\n NULL\n };\n \n static int null_term_line;\n \n static const struct option check_attr_options[] = {\n+\tOPT_BOOLEAN('a', \"all\", &all_attrs, \"report all attributes set on file\"),\n \tOPT_BOOLEAN(0 , \"stdin\", &stdin_paths, \"read file names from stdin\"),\n \tOPT_BOOLEAN('z', NULL, &null_term_line,\n \t\t\"input paths are terminated by a null character\"),\n@@ -42,9 +44,16 @@ static void output_attr(int cnt, struct git_attr_check *check,\n static void check_attr(int cnt, struct git_attr_check *check,\n \tconst char *file)\n {\n-\tif (git_checkattr(file, cnt, check))\n-\t\tdie(\"git_checkattr died\");\n-\toutput_attr(cnt, check, file);\n+\tif (check != NULL) {\n+\t\tif (git_checkattr(file, cnt, check))\n+\t\t\tdie(\"git_checkattr died\");\n+\t\toutput_attr(cnt, check, file);\n+\t} else {\n+\t\tif (git_allattrs(file, &cnt, &check))\n+\t\t\tdie(\"git_allattrs died\");\n+\t\toutput_attr(cnt, check, file);\n+\t\tfree(check);\n+\t}\n }\n \n static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n@@ -92,8 +101,14 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\t\tdoubledash = i;\n \t}\n \n-\t/* Check attribute argument(s): */\n-\tif (doubledash == 0) {\n+\t/* Process --all and/or attribute arguments: */\n+\tif (all_attrs) {\n+\t\tif (doubledash >= 1)\n+\t\t\terror_with_usage(\"Attributes and --all both specified\");\n+\n+\t\tcnt = 0;\n+\t\tfilei = doubledash + 1;\n+\t} else if (doubledash == 0) {\n \t\terror_with_usage(\"No attribute specified\");\n \t} else if (doubledash < 0) {\n \t\t/*\n@@ -119,15 +134,20 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t\t\terror_with_usage(\"No file specified\");\n \t}\n \n-\tcheck = xcalloc(cnt, sizeof(*check));\n-\tfor (i = 0; i < cnt; i++) {\n-\t\tconst char *name;\n-\t\tstruct git_attr *a;\n-\t\tname = argv[i];\n-\t\ta = git_attr(name);\n-\t\tif (!a)\n-\t\t\treturn error(\"%s: not a valid attribute name\", name);\n-\t\tcheck[i].attr = a;\n+\tif (all_attrs) {\n+\t\tcheck = NULL;\n+\t} else {\n+\t\tcheck = xcalloc(cnt, sizeof(*check));\n+\t\tfor (i = 0; i < cnt; i++) {\n+\t\t\tconst char *name;\n+\t\t\tstruct git_attr *a;\n+\t\t\tname = argv[i];\n+\t\t\ta = git_attr(name);\n+\t\t\tif (!a)\n+\t\t\t\treturn error(\"%s: not a valid attribute name\",\n+\t\t\t\t\tname);\n+\t\t\tcheck[i].attr = a;\n+\t\t}\n \t}\n \n \tif (stdin_paths)\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 2254005..8892ba3 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -107,6 +107,30 @@ EOF\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'attribute test: --all option' '\n+\n+\tcat <<EOF > all &&\n+f: test: f\n+a/f: test: f\n+a/c/f: test: f\n+a/g: test: a/g\n+a/b/g: test: a/b/g\n+b/g: test: unspecified\n+a/b/h: test: a/b/h\n+a/b/d/g: test: a/b/d/*\n+onoff: test: unset\n+offon: test: set\n+no: notest: set\n+a/b/d/no: test: a/b/d/*\n+a/b/d/no: notest: set\n+a/b/d/yes: notest: set\n+EOF\n+\n+\tgrep -v unspecified < all | sort > expect &&\n+\tsed -e \"s/:.*//\" < all | uniq | git check-attr --stdin --all | sort > actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'root subdir attribute test' '\n \n \tattr_check a/i a/i &&\n-- \n1.7.6.8.gd2879\n"},{"id":"172226","messageId":"1311828418-2676-18-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 17/19] git-check-attr: Drive two tests using the same raw data","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:56Z","receivedAt":"2011-07-28T04:46:56Z","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 |   59 +++++++++++++++++++-----------------------------\n 1 files changed, 23 insertions(+), 36 deletions(-)\n\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 8892ba3..a49f8a9 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -38,7 +38,25 @@ test_expect_success 'setup' '\n \t) >a/b/.gitattributes &&\n \t(\n \t\techo \"global test=global\"\n-\t) >\"$HOME\"/global-gitattributes\n+\t) >\"$HOME\"/global-gitattributes &&\n+\tcat <<EOF >expect-all\n+f: test: f\n+a/f: test: f\n+a/c/f: test: f\n+a/g: test: a/g\n+a/b/g: test: a/b/g\n+b/g: test: unspecified\n+a/b/h: test: a/b/h\n+a/b/d/g: test: a/b/d/*\n+onoff: test: unset\n+offon: test: set\n+no: notest: set\n+no: test: unspecified\n+a/b/d/no: notest: set\n+a/b/d/no: test: a/b/d/*\n+a/b/d/yes: notest: set\n+a/b/d/yes: test: unspecified\n+EOF\n \n '\n \n@@ -87,47 +105,16 @@ test_expect_success 'core.attributesfile' '\n \n test_expect_success 'attribute test: read paths from stdin' '\n \n-\tcat <<EOF > expect &&\n-f: test: f\n-a/f: test: f\n-a/c/f: test: f\n-a/g: test: a/g\n-a/b/g: test: a/b/g\n-b/g: test: unspecified\n-a/b/h: test: a/b/h\n-a/b/d/g: test: a/b/d/*\n-onoff: test: unset\n-offon: test: set\n-no: test: unspecified\n-a/b/d/no: test: a/b/d/*\n-a/b/d/yes: test: unspecified\n-EOF\n-\n+\tgrep -v notest < expect-all > expect &&\n \tsed -e \"s/:.*//\" < expect | git check-attr --stdin test > actual &&\n \ttest_cmp expect actual\n '\n \n test_expect_success 'attribute test: --all option' '\n \n-\tcat <<EOF > all &&\n-f: test: f\n-a/f: test: f\n-a/c/f: test: f\n-a/g: test: a/g\n-a/b/g: test: a/b/g\n-b/g: test: unspecified\n-a/b/h: test: a/b/h\n-a/b/d/g: test: a/b/d/*\n-onoff: test: unset\n-offon: test: set\n-no: notest: set\n-a/b/d/no: test: a/b/d/*\n-a/b/d/no: notest: set\n-a/b/d/yes: notest: set\n-EOF\n-\n-\tgrep -v unspecified < all | sort > expect &&\n-\tsed -e \"s/:.*//\" < all | uniq | git check-attr --stdin --all | sort > actual &&\n+\tgrep -v unspecified < expect-all | sort > expect &&\n+\tsed -e \"s/:.*//\" < expect-all | uniq |\n+\t\tgit check-attr --stdin --all | sort > actual &&\n \ttest_cmp expect actual\n '\n \n-- \n1.7.6.8.gd2879\n"},{"id":"172227","messageId":"1311828418-2676-19-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 18/19] git-check-attr: Fix command-line handling to match docs","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:57Z","receivedAt":"2011-07-28T04:46:57Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"According to the git-check-attr synopsis, if the '--stdin' option is\nused then no pathnames are expected on the command line.  Change the\nbehavior to match this description; namely, if '--stdin' is used but\nnot '--', then treat all command-line arguments as attribute names.\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/git-check-attr.txt |    7 +++++--\n builtin/check-attr.c             |   15 +++++++++------\n t/t0003-attributes.sh            |    1 -\n 3 files changed, 14 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt\nindex 798e5d5..1f7312a 100644\n--- a/Documentation/git-check-attr.txt\n+++ b/Documentation/git-check-attr.txt\n@@ -33,8 +33,11 @@ OPTIONS\n \n \\--::\n \tInterpret all preceding arguments as attributes and all following\n-\targuments as path names. If not supplied, only the first argument will\n-\tbe treated as an attribute.\n+\targuments as path names.\n+\n+If none of `--stdin`, `--all`, or `--` is used, the first argument\n+will be treated as an attribute and the rest of the arguments as\n+pathnames.\n \n OUTPUT\n ------\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 48834b4..9fe0b93 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -111,15 +111,18 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t} else if (doubledash == 0) {\n \t\terror_with_usage(\"No attribute specified\");\n \t} else if (doubledash < 0) {\n-\t\t/*\n-\t\t * There is no double dash; treat the first\n-\t\t * argument as an attribute.\n-\t\t */\n \t\tif (!argc)\n \t\t\terror_with_usage(\"No attribute specified\");\n \n-\t\tcnt = 1;\n-\t\tfilei = 1;\n+\t\tif (stdin_paths) {\n+\t\t\t/* Treat all arguments as attribute names. */\n+\t\t\tcnt = argc;\n+\t\t\tfilei = argc;\n+\t\t} else {\n+\t\t\t/* Treat exactly one argument as an attribute name. */\n+\t\t\tcnt = 1;\n+\t\t\tfilei = 1;\n+\t\t}\n \t} else {\n \t\tcnt = doubledash;\n \t\tfilei = doubledash + 1;\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex a49f8a9..5acb2d5 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -70,7 +70,6 @@ test_expect_success 'command line checks' '\n \techo \"f\" | test_must_fail git check-attr --stdin &&\n \techo \"f\" | test_must_fail git check-attr --stdin -- f &&\n \techo \"f\" | test_must_fail git check-attr --stdin test -- f &&\n-\techo \"f\" | test_must_fail git check-attr --stdin test f &&\n \ttest_must_fail git check-attr \"\" -- f\n \n '\n-- \n1.7.6.8.gd2879\n"},{"id":"172225","messageId":"1311828418-2676-20-git-send-email-mhagger@alum.mit.edu","threadId":"27940","inReplyTo":"1311828418-2676-1-git-send-email-mhagger@alum.mit.edu","subject":"[PATCH v2 19/19] Rename struct git_attr_check to git_attr_value","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-07-28T04:46:58Z","receivedAt":"2011-07-28T04:46:58Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"This described its purpose better, especially when used with\ngit_allattrs().\n\nSigned-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n---\n Documentation/technical/api-gitattributes.txt |   20 ++++++++++----------\n archive.c                                     |    4 ++--\n attr.c                                        |    8 ++++----\n attr.h                                        |   12 ++++++------\n builtin/check-attr.c                          |    8 ++++----\n builtin/pack-objects.c                        |    4 ++--\n convert.c                                     |   10 +++++-----\n ll-merge.c                                    |    6 +++---\n userdiff.c                                    |    2 +-\n ws.c                                          |    4 ++--\n 10 files changed, 39 insertions(+), 39 deletions(-)\n\ndiff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\nindex 640240e..c64969d 100644\n--- a/Documentation/technical/api-gitattributes.txt\n+++ b/Documentation/technical/api-gitattributes.txt\n@@ -16,7 +16,7 @@ Data Structure\n \tof no interest to the calling programs.  The name of the\n \tattribute can be retrieved by calling `git_attr_name()`.\n \n-`struct git_attr_check`::\n+`struct git_attr_value`::\n \n \tThis structure represents a set of attributes to check in a call\n \tto `git_checkattr()` function, and receives the results.\n@@ -27,7 +27,7 @@ Attribute Values\n \n An attribute for a path can be in one of four states: Set, Unset,\n Unspecified or set to a string, and `.value` member of `struct\n-git_attr_check` records it.  There are three macros to check these:\n+git_attr_value` records it.  There are three macros to check these:\n \n `ATTR_TRUE()`::\n \n@@ -48,13 +48,13 @@ value of the attribute for the path.\n Querying Specific Attributes\n ----------------------------\n \n-* Prepare an array of `struct git_attr_check` to define the list of\n+* Prepare an array of `struct git_attr_value` to define the list of\n   attributes you would want to check.  To populate this array, you would\n   need to define necessary attributes by calling `git_attr()` function.\n \n * Call `git_checkattr()` to check the attributes for the path.\n \n-* Inspect `git_attr_check` structure to see how each of the attribute in\n+* Inspect `git_attr_value` structure to see how each of the attribute in\n   the array is defined for the path.\n \n \n@@ -63,12 +63,12 @@ Example\n \n To see how attributes \"crlf\" and \"indent\" are set for different paths.\n \n-. Prepare an array of `struct git_attr_check` with two elements (because\n+. Prepare an array of `struct git_attr_value` with two elements (because\n   we are checking two attributes).  Initialize their `attr` member with\n   pointers to `struct git_attr` obtained by calling `git_attr()`:\n \n ------------\n-static struct git_attr_check check[2];\n+static struct git_attr_value check[2];\n static void setup_check(void)\n {\n \tif (check[0].attr)\n@@ -78,7 +78,7 @@ static void setup_check(void)\n }\n ------------\n \n-. Call `git_checkattr()` with the prepared array of `struct git_attr_check`:\n+. Call `git_checkattr()` with the prepared array of `struct git_attr_value`:\n \n ------------\n \tconst char *path;\n@@ -115,12 +115,12 @@ Querying All Attributes\n \n To get the values of all attributes associated with a file:\n \n-* Call `git_allattrs()`, which returns an array of `git_attr_check`\n+* Call `git_allattrs()`, which returns an array of `git_attr_value`\n   structures.\n \n-* Iterate over the `git_attr_check` array to examine the attribute\n+* Iterate over the `git_attr_value` array to examine the attribute\n   names and values.  The name of the attribute described by a\n-  `git_attr_check` object can be retrieved via\n+  `git_attr_value` object can be retrieved via\n   `git_attr_name(check[i].attr)`.  (Please note that no items will be\n   returned for unset attributes, so `ATTR_UNSET()` will return false\n   for all returned `git_array_check` objects.)\ndiff --git a/archive.c b/archive.c\nindex 2a7a28e..9a180b6 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -81,7 +81,7 @@ static void *sha1_file_to_archive(const char *path, const unsigned char *sha1,\n \treturn buffer;\n }\n \n-static void setup_archive_check(struct git_attr_check *check)\n+static void setup_archive_check(struct git_attr_value *check)\n {\n \tstatic struct git_attr *attr_export_ignore;\n \tstatic struct git_attr *attr_export_subst;\n@@ -107,7 +107,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,\n \tstruct archiver_context *c = context;\n \tstruct archiver_args *args = c->args;\n \twrite_archive_entry_fn_t write_entry = c->write_entry;\n-\tstruct git_attr_check check[2];\n+\tstruct git_attr_value check[2];\n \tconst char *path_without_prefix;\n \tint convert = 0;\n \tint err;\ndiff --git a/attr.c b/attr.c\nindex 9c2fca8..d2a7727 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -33,7 +33,7 @@ struct git_attr {\n };\n static int attr_nr;\n \n-static struct git_attr_check *check_all_attr;\n+static struct git_attr_value *check_all_attr;\n static struct git_attr *(git_attr_hash[HASHSIZE]);\n \n char *git_attr_name(struct git_attr *attr)\n@@ -646,7 +646,7 @@ static int macroexpand_one(int attr_nr, int rem);\n \n static int fill_one(const char *what, struct match_attr *a, int rem)\n {\n-\tstruct git_attr_check *check = check_all_attr;\n+\tstruct git_attr_value *check = check_all_attr;\n \tint i;\n \n \tfor (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {\n@@ -706,7 +706,7 @@ static int macroexpand_one(int attr_nr, int rem)\n \treturn rem;\n }\n \n-int git_checkattr(const char *path, int num, struct git_attr_check *check)\n+int git_checkattr(const char *path, int num, struct git_attr_value *check)\n {\n \tstruct attr_stack *stk;\n \tconst char *cp;\n@@ -737,7 +737,7 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)\n \treturn 0;\n }\n \n-int git_allattrs(const char *path, int *num, struct git_attr_check **check)\n+int git_allattrs(const char *path, int *num, struct git_attr_value **check)\n {\n \tstruct attr_stack *stk;\n \tconst char *cp;\ndiff --git a/attr.h b/attr.h\nindex 83202f0..4dc4db0 100644\n--- a/attr.h\n+++ b/attr.h\n@@ -14,17 +14,17 @@ struct git_attr *git_attr(const char *);\n extern const char git_attr__true[];\n extern const char git_attr__false[];\n \n-/* For public to check git_attr_check results */\n+/* For public to check git_attr_value results */\n #define ATTR_TRUE(v) ((v) == git_attr__true)\n #define ATTR_FALSE(v) ((v) == git_attr__false)\n #define ATTR_UNSET(v) ((v) == NULL)\n \n /*\n- * Send one or more git_attr_check to git_checkattr(), and\n+ * Send one or more git_attr_value to git_checkattr(), and\n  * each 'value' member tells what its value is.\n  * Unset one is returned as NULL.\n  */\n-struct git_attr_check {\n+struct git_attr_value {\n \tstruct git_attr *attr;\n \tconst char *value;\n };\n@@ -36,16 +36,16 @@ struct git_attr_check {\n  */\n char *git_attr_name(struct git_attr *);\n \n-int git_checkattr(const char *path, int, struct git_attr_check *);\n+int git_checkattr(const char *path, int, struct git_attr_value *);\n \n /*\n  * Retrieve all attributes that apply to the specified path.  *num\n  * will be set the the number of attributes on the path; **check will\n- * be set to point at a newly-allocated array of git_attr_check\n+ * be set to point at a newly-allocated array of git_attr_value\n  * objects describing the attributes and their values.  *check must be\n  * free()ed by the caller.\n  */\n-int git_allattrs(const char *path, int *num, struct git_attr_check **check);\n+int git_allattrs(const char *path, int *num, struct git_attr_value **check);\n \n enum git_attr_direction {\n \tGIT_ATTR_CHECKIN,\ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 9fe0b93..781b7df 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -22,7 +22,7 @@ static const struct option check_attr_options[] = {\n \tOPT_END()\n };\n \n-static void output_attr(int cnt, struct git_attr_check *check,\n+static void output_attr(int cnt, struct git_attr_value *check,\n \tconst char *file)\n {\n \tint j;\n@@ -41,7 +41,7 @@ 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+static void check_attr(int cnt, struct git_attr_value *check,\n \tconst char *file)\n {\n \tif (check != NULL) {\n@@ -56,7 +56,7 @@ static void check_attr(int cnt, struct git_attr_check *check,\n \t}\n }\n \n-static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)\n+static void check_attr_stdin_paths(int cnt, struct git_attr_value *check)\n {\n \tstruct strbuf buf, nbuf;\n \tint line_termination = null_term_line ? 0 : '\\n';\n@@ -85,7 +85,7 @@ static NORETURN void error_with_usage(const char *msg)\n \n int cmd_check_attr(int argc, const char **argv, const char *prefix)\n {\n-\tstruct git_attr_check *check;\n+\tstruct git_attr_value *check;\n \tint cnt, i, doubledash, filei;\n \n \targc = parse_options(argc, argv, prefix, check_attr_options,\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 84e6daf..a0becea 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -619,7 +619,7 @@ static unsigned name_hash(const char *name)\n \treturn hash;\n }\n \n-static void setup_delta_attr_check(struct git_attr_check *check)\n+static void setup_delta_attr_check(struct git_attr_value *check)\n {\n \tstatic struct git_attr *attr_delta;\n \n@@ -631,7 +631,7 @@ static void setup_delta_attr_check(struct git_attr_check *check)\n \n static int no_try_delta(const char *path)\n {\n-\tstruct git_attr_check check[1];\n+\tstruct git_attr_value check[1];\n \n \tsetup_delta_attr_check(check);\n \tif (git_checkattr(path, ARRAY_SIZE(check), check))\ndiff --git a/convert.c b/convert.c\nindex 85939c2..ab582f8 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -641,7 +641,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,\n \treturn 1;\n }\n \n-static int git_path_check_crlf(const char *path, struct git_attr_check *check)\n+static int git_path_check_crlf(const char *path, struct git_attr_value *check)\n {\n \tconst char *value = check->value;\n \n@@ -658,7 +658,7 @@ static int git_path_check_crlf(const char *path, struct git_attr_check *check)\n \treturn CRLF_GUESS;\n }\n \n-static int git_path_check_eol(const char *path, struct git_attr_check *check)\n+static int git_path_check_eol(const char *path, struct git_attr_value *check)\n {\n \tconst char *value = check->value;\n \n@@ -672,7 +672,7 @@ static int git_path_check_eol(const char *path, struct git_attr_check *check)\n }\n \n static struct convert_driver *git_path_check_convert(const char *path,\n-\t\t\t\t\t     struct git_attr_check *check)\n+\t\t\t\t\t     struct git_attr_value *check)\n {\n \tconst char *value = check->value;\n \tstruct convert_driver *drv;\n@@ -685,7 +685,7 @@ static struct convert_driver *git_path_check_convert(const char *path,\n \treturn NULL;\n }\n \n-static int git_path_check_ident(const char *path, struct git_attr_check *check)\n+static int git_path_check_ident(const char *path, struct git_attr_value *check)\n {\n \tconst char *value = check->value;\n \n@@ -718,7 +718,7 @@ static const char *conv_attr_name[] = {\n static void convert_attrs(struct conv_attrs *ca, const char *path)\n {\n \tint i;\n-\tstatic struct git_attr_check ccheck[NUM_CONV_ATTRS];\n+\tstatic struct git_attr_value ccheck[NUM_CONV_ATTRS];\n \n \tif (!ccheck[0].attr) {\n \t\tfor (i = 0; i < NUM_CONV_ATTRS; i++)\ndiff --git a/ll-merge.c b/ll-merge.c\nindex 6ce512e..65f326e 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -324,7 +324,7 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr\n \treturn &ll_merge_drv[LL_TEXT_MERGE];\n }\n \n-static int git_path_check_merge(const char *path, struct git_attr_check check[2])\n+static int git_path_check_merge(const char *path, struct git_attr_value check[2])\n {\n \tif (!check[0].attr) {\n \t\tcheck[0].attr = git_attr(\"merge\");\n@@ -350,7 +350,7 @@ int ll_merge(mmbuffer_t *result_buf,\n \t     mmfile_t *theirs, const char *their_label,\n \t     const struct ll_merge_options *opts)\n {\n-\tstatic struct git_attr_check check[2];\n+\tstatic struct git_attr_value check[2];\n \tstatic const struct ll_merge_options default_opts;\n \tconst char *ll_driver_name = NULL;\n \tint marker_size = DEFAULT_CONFLICT_MARKER_SIZE;\n@@ -382,7 +382,7 @@ int ll_merge(mmbuffer_t *result_buf,\n \n int ll_merge_marker_size(const char *path)\n {\n-\tstatic struct git_attr_check check;\n+\tstatic struct git_attr_value check;\n \tint marker_size = DEFAULT_CONFLICT_MARKER_SIZE;\n \n \tif (!check.attr)\ndiff --git a/userdiff.c b/userdiff.c\nindex 01d3a8b..cde9537 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -262,7 +262,7 @@ struct userdiff_driver *userdiff_find_by_name(const char *name) {\n struct userdiff_driver *userdiff_find_by_path(const char *path)\n {\n \tstatic struct git_attr *attr;\n-\tstruct git_attr_check check;\n+\tstruct git_attr_value check;\n \n \tif (!attr)\n \t\tattr = git_attr(\"diff\");\ndiff --git a/ws.c b/ws.c\nindex 9fb9b14..4a76ef8 100644\n--- a/ws.c\n+++ b/ws.c\n@@ -74,7 +74,7 @@ unsigned parse_whitespace_rule(const char *string)\n \treturn rule;\n }\n \n-static void setup_whitespace_attr_check(struct git_attr_check *check)\n+static void setup_whitespace_attr_check(struct git_attr_value *check)\n {\n \tstatic struct git_attr *attr_whitespace;\n \n@@ -85,7 +85,7 @@ static void setup_whitespace_attr_check(struct git_attr_check *check)\n \n unsigned whitespace_rule(const char *pathname)\n {\n-\tstruct git_attr_check attr_whitespace_rule;\n+\tstruct git_attr_value attr_whitespace_rule;\n \n \tsetup_whitespace_attr_check(&attr_whitespace_rule);\n \tif (!git_checkattr(pathname, 1, &attr_whitespace_rule)) {\n-- \n1.7.6.8.gd2879\n"},{"id":"172664","messageId":"7vwrevg73x.fsf@alter.siamese.dyndns.org","threadId":"27940","inReplyTo":"1311828418-2676-10-git-send-email-mhagger@alum.mit.edu","subject":"Re: [PATCH v2 09/19] Allow querying all attributes on a file","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-02T15:34:26Z","receivedAt":"2011-08-02T15:34:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> Add a function, git_allattrs(), that reports on all attributes that\n> are set on a path.\n>\n> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n> ---\n>  Documentation/technical/api-gitattributes.txt |   45 +++++++++++++++++-------\n>  attr.c                                        |   43 +++++++++++++++++++++++\n>  attr.h                                        |    9 +++++\n>  3 files changed, 84 insertions(+), 13 deletions(-)\n>\n> diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\n> index ab3a84d..640240e 100644\n> --- a/Documentation/technical/api-gitattributes.txt\n> +++ b/Documentation/technical/api-gitattributes.txt\n> @@ -22,19 +22,6 @@ Data Structure\n> ...\n>  (JC)\n\nThe last line, I think, can now be dropped. This was a marker saying \"we\nlack documentation for this API; bug this person for necessary information\nand write one\".\n\n> diff --git a/attr.c b/attr.c\n> index bfa1f43..9c2fca8 100644\n> --- a/attr.c\n> +++ b/attr.c\n> @@ -737,6 +737,49 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)\n>  \treturn 0;\n>  }\n>  \n> +int git_allattrs(const char *path, int *num, struct git_attr_check **check)\n> +{\n> +\tstruct attr_stack *stk;\n> +\tconst char *cp;\n> +\tint dirlen, pathlen, i, rem, count, j;\n> +\n> +\tbootstrap_attr_stack();\n> +\tfor (i = 0; i < attr_nr; i++)\n> +\t\tcheck_all_attr[i].value = ATTR__UNKNOWN;\n> +\n> +\tpathlen = strlen(path);\n> +\tcp = strrchr(path, '/');\n> +\tif (!cp)\n> +\t\tdirlen = 0;\n> +\telse\n> +\t\tdirlen = cp - path;\n> +\tprepare_attr_stack(path, dirlen);\n> +\trem = attr_nr;\n> +\tfor (stk = attr_stack; 0 < rem && stk; stk = stk->prev)\n> +\t\trem = fill(path, pathlen, stk, rem);\n\nShouldn't the above part at least should be refactored instead of copied\nand pasted from git_checkattr()?\n"},{"id":"172666","messageId":"7vsjpjg6k7.fsf@alter.siamese.dyndns.org","threadId":"27940","inReplyTo":"1311828418-2676-20-git-send-email-mhagger@alum.mit.edu","subject":"Re: [PATCH v2 19/19] Rename struct git_attr_check to git_attr_value","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-02T15:46:16Z","receivedAt":"2011-08-02T15:46:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> This described its purpose better, especially when used with\n> git_allattrs().\n\nYou probably meant s/described/describes/ but more importantly does it\nreally? It is a structure used to probe into the attributes system for the\nstate of various attributes on a path, and the set of possible states\nincludes \"there is no value\" (aka unset), so it feels actively wrong to\ncall it attr_value and that is why I didn't call it in the first place.\n\nI also think git_all_attrs() (i.e. word-break underscore after \"all\") is\nmore in line with the naming throughout the codebase, after looking at\noutput from\n\n  $ git grep -e _all'[a-z]' --and --not -e alloc -e _all_ -- '*.c'\n\nOther than these, and the earlier comment about the copy&paste done from\ngit_checkattr (which by the way should probably be \"git_check_attr\"), it\nseems that the series mostly consist of good clean-ups and an addition of\na new and (probably) useful feature that is straightforward. Nice.\n\nThanks.\n"},{"id":"172845","messageId":"4E3A0F0D.7050403@alum.mit.edu","threadId":"27940","inReplyTo":"7vwrevg73x.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 09/19] Allow querying all attributes on a file","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T03:16:29Z","receivedAt":"2011-08-04T03:16:29Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 08/02/2011 05:34 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n>> Add a function, git_allattrs(), that reports on all attributes that\n>> are set on a path.\n>>\n>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>\n>> ---\n>>  Documentation/technical/api-gitattributes.txt |   45 +++++++++++++++++-------\n>>  attr.c                                        |   43 +++++++++++++++++++++++\n>>  attr.h                                        |    9 +++++\n>>  3 files changed, 84 insertions(+), 13 deletions(-)\n>>\n>> diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt\n>> index ab3a84d..640240e 100644\n>> --- a/Documentation/technical/api-gitattributes.txt\n>> +++ b/Documentation/technical/api-gitattributes.txt\n>> @@ -22,19 +22,6 @@ Data Structure\n>> ...\n>>  (JC)\n> \n> The last line, I think, can now be dropped. This was a marker saying \"we\n> lack documentation for this API; bug this person for necessary information\n> and write one\".\n\nOK; I will drop the line in the re-roll.\n\n>> diff --git a/attr.c b/attr.c\n>> index bfa1f43..9c2fca8 100644\n>> --- a/attr.c\n>> +++ b/attr.c\n>> @@ -737,6 +737,49 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)\n>>  \treturn 0;\n>>  }\n>>  \n>> +int git_allattrs(const char *path, int *num, struct git_attr_check **check)\n>> +{\n>> +\tstruct attr_stack *stk;\n>> +\tconst char *cp;\n>> +\tint dirlen, pathlen, i, rem, count, j;\n>> +\n>> +\tbootstrap_attr_stack();\n>> +\tfor (i = 0; i < attr_nr; i++)\n>> +\t\tcheck_all_attr[i].value = ATTR__UNKNOWN;\n>> +\n>> +\tpathlen = strlen(path);\n>> +\tcp = strrchr(path, '/');\n>> +\tif (!cp)\n>> +\t\tdirlen = 0;\n>> +\telse\n>> +\t\tdirlen = cp - path;\n>> +\tprepare_attr_stack(path, dirlen);\n>> +\trem = attr_nr;\n>> +\tfor (stk = attr_stack; 0 < rem && stk; stk = stk->prev)\n>> +\t\trem = fill(path, pathlen, stk, rem);\n> \n> Shouldn't the above part at least should be refactored instead of copied\n> and pasted from git_checkattr()?\n\nQuite right.  Will be fixed in re-roll.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"},{"id":"172846","messageId":"4E3A0FFD.7010604@alum.mit.edu","threadId":"27940","inReplyTo":"7vsjpjg6k7.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 19/19] Rename struct git_attr_check to git_attr_value","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2011-08-04T03:20:29Z","receivedAt":"2011-08-04T03:20:29Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"Thanks for the good feedback.\n\nOn 08/02/2011 05:46 PM, Junio C Hamano wrote:\n> Michael Haggerty <mhagger@alum.mit.edu> writes:\n> \n>> This described its purpose better, especially when used with\n>> git_allattrs().\n> \n> You probably meant s/described/describes/ but more importantly does it\n> really? It is a structure used to probe into the attributes system for the\n> state of various attributes on a path, and the set of possible states\n> includes \"there is no value\" (aka unset), so it feels actively wrong to\n> call it attr_value and that is why I didn't call it in the first place.\n\nI don't think it is so unusual for a \"value\" object to be able to\nreflect the fact that the value is unset, but I can understand your\npoint of view too.  I will omit this renaming in the re-roll.\n\n> I also think git_all_attrs() (i.e. word-break underscore after \"all\") is\n> more in line with the naming throughout the codebase, after looking at\n> output from\n> \n>   $ git grep -e _all'[a-z]' --and --not -e alloc -e _all_ -- '*.c'\n> \n> Other than these, and the earlier comment about the copy&paste done from\n> git_checkattr (which by the way should probably be \"git_check_attr\"), it\n> seems that the series mostly consist of good clean-ups and an addition of\n> a new and (probably) useful feature that is straightforward. Nice.\n\nI thought the name was awkward, too, but I chose it to be consistent\nwith git_checkattr().  So in the re-roll I will happily rename both\nfunctions.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\nhttp://softwareswirl.blogspot.com/\n"}]}