From cde151815eb409d8dd457e7aaa3ded2e53796343 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:11 +0200 Subject: doc: Add a link from gitattributes(5) to git-check-attr(1) Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/gitattributes.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 412c55b54..3d8643437 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -952,6 +952,9 @@ frotz unspecified ---------------------------------------------------------------- +SEE ALSO +-------- +linkgit:git-check-attr[1]. GIT --- -- cgit v1.2.1 From 650cfc512e189c1af347c9eeaebc0377e0dcb88d Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:12 +0200 Subject: doc: Correct git_attr() calls in example code Commit 7fb0eaa2 (2010-01-17) changed git_attr() to take a string instead of a string and a length. Update the documentation accordingly. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/technical/api-gitattributes.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt index 9d97eaa9d..916720f7a 100644 --- a/Documentation/technical/api-gitattributes.txt +++ b/Documentation/technical/api-gitattributes.txt @@ -11,9 +11,9 @@ Data Structure `struct git_attr`:: An attribute is an opaque object that is identified by its name. - Pass the name and its length to `git_attr()` function to obtain - the object of this type. The internal representation of this - structure is of no interest to the calling programs. + Pass the name to `git_attr()` function to obtain the object of + this type. The internal representation of this structure is + of no interest to the calling programs. `struct git_attr_check`:: @@ -72,8 +72,8 @@ static void setup_check(void) { if (check[0].attr) return; /* already done */ - check[0].attr = git_attr("crlf", 4); - check[1].attr = git_attr("ident", 5); + check[0].attr = git_attr("crlf"); + check[1].attr = git_attr("ident"); } ------------ -- cgit v1.2.1 From d42453ab1a482df0fdb428c20de1189a21a2bee1 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:13 +0200 Subject: Remove anachronism from comment Setting attributes to arbitrary values ("attribute=value") is now supported, so it is no longer necessary for this comment to justify prohibiting '=' in an attribute name. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/attr.c b/attr.c index f6b3f7e85..4a1244f9a 100644 --- a/attr.c +++ b/attr.c @@ -50,10 +50,8 @@ static unsigned hash_name(const char *name, int namelen) static int invalid_attr_name(const char *name, int namelen) { /* - * Attribute name cannot begin with '-' and from - * [-A-Za-z0-9_.]. We'd specifically exclude '=' for now, - * as we might later want to allow non-binary value for - * attributes, e.g. "*.svg merge=special-merge-program-for-svg" + * Attribute name cannot begin with '-' and must consist of + * characters from [-A-Za-z0-9_.]. */ if (*name == '-') return -1; -- cgit v1.2.1 From c0b13b21b8daa4bfb222e9c4d335c8b340c511a0 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:14 +0200 Subject: Disallow the empty string as an attribute name Previously, it was possible to have a line like "file.txt =foo" in a .gitattribute file, after which an invocation like "git check-attr '' -- file.txt" would succeed. This patch disallows both constructs. Please note that any existing .gitattributes file that tries to set an empty attribute will now trigger the error message "error: : not a valid attribute name" whereas previously the nonsense was allowed through. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 2 +- t/t0003-attributes.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/attr.c b/attr.c index 4a1244f9a..b1d1d6d79 100644 --- a/attr.c +++ b/attr.c @@ -53,7 +53,7 @@ static int invalid_attr_name(const char *name, int namelen) * Attribute name cannot begin with '-' and must consist of * characters from [-A-Za-z0-9_.]. */ - if (*name == '-') + if (namelen <= 0 || *name == '-') return -1; while (namelen--) { char ch = *name++; diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index ebbc7554a..8c76b79bb 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -42,6 +42,12 @@ test_expect_success 'setup' ' ' +test_expect_success 'command line checks' ' + + test_must_fail git check-attr "" -- f + +' + test_expect_success 'attribute test' ' attr_check f f && -- cgit v1.2.1 From dcc04366a4658763500724888d9e74cae317c861 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:15 +0200 Subject: git-check-attr: Add missing "&&" Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 8c76b79bb..dae76b39b 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -35,7 +35,7 @@ test_expect_success 'setup' ' echo "h test=a/b/h" && echo "d/* test=a/b/d/*" echo "d/yes notest" - ) >a/b/.gitattributes + ) >a/b/.gitattributes && ( echo "global test=global" ) >"$HOME"/global-gitattributes -- cgit v1.2.1 From 09d7dd7ad62fef60fc223fa74eb04c8dc783c2f6 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:16 +0200 Subject: git-check-attr: Add tests of command-line parsing Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index dae76b39b..f1debeb7a 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -44,6 +44,13 @@ test_expect_success 'setup' ' test_expect_success 'command line checks' ' + test_must_fail git check-attr && + test_must_fail git check-attr -- && + test_must_fail git check-attr -- f && + echo "f" | test_must_fail git check-attr --stdin && + echo "f" | test_must_fail git check-attr --stdin -- f && + echo "f" | test_must_fail git check-attr --stdin test -- f && + echo "f" | test_must_fail git check-attr --stdin test f && test_must_fail git check-attr "" -- f ' -- cgit v1.2.1 From 352404ac4ccab144cd866b1f24c90b8f29ca33c2 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:17 +0200 Subject: Provide access to the name attribute of git_attr It will be present in any likely future reimplementation, and its availability simplifies other code. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/technical/api-gitattributes.txt | 3 ++- attr.c | 5 +++++ attr.h | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt index 916720f7a..ab3a84d2f 100644 --- a/Documentation/technical/api-gitattributes.txt +++ b/Documentation/technical/api-gitattributes.txt @@ -13,7 +13,8 @@ Data Structure An attribute is an opaque object that is identified by its name. Pass the name to `git_attr()` function to obtain the object of this type. The internal representation of this structure is - of no interest to the calling programs. + of no interest to the calling programs. The name of the + attribute can be retrieved by calling `git_attr_name()`. `struct git_attr_check`:: diff --git a/attr.c b/attr.c index b1d1d6d79..bfa1f4379 100644 --- a/attr.c +++ b/attr.c @@ -36,6 +36,11 @@ static int attr_nr; static struct git_attr_check *check_all_attr; static struct git_attr *(git_attr_hash[HASHSIZE]); +char *git_attr_name(struct git_attr *attr) +{ + return attr->name; +} + static unsigned hash_name(const char *name, int namelen) { unsigned val = 0, c; diff --git a/attr.h b/attr.h index 8b3f19be6..d4f875a3d 100644 --- a/attr.h +++ b/attr.h @@ -29,6 +29,13 @@ struct git_attr_check { const char *value; }; +/* + * Return the name of the attribute represented by the argument. The + * return value is a pointer to a null-delimited string that is part + * of the internal data structure; it should not be modified or freed. + */ +char *git_attr_name(struct git_attr *); + int git_checkattr(const char *path, int, struct git_attr_check *); enum git_attr_direction { -- cgit v1.2.1 From 66a1fb30335191b5ebdbcc331832e8903eb3cd0e Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:18 +0200 Subject: git-check-attr: Use git_attr_name() Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 3016d29ca..5f04126d4 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -21,7 +21,7 @@ static const struct option check_attr_options[] = { }; static void check_attr(int cnt, struct git_attr_check *check, - const char** name, const char *file) + const char *file) { int j; if (git_checkattr(file, cnt, check)) @@ -37,12 +37,11 @@ static void check_attr(int cnt, struct git_attr_check *check, value = "unspecified"; quote_c_style(file, NULL, stdout, 0); - printf(": %s: %s\n", name[j], value); + printf(": %s: %s\n", git_attr_name(check[j].attr), value); } } -static void check_attr_stdin_paths(int cnt, struct git_attr_check *check, - const char** name) +static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) { struct strbuf buf, nbuf; int line_termination = null_term_line ? 0 : '\n'; @@ -56,7 +55,7 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check, die("line is badly quoted"); strbuf_swap(&buf, &nbuf); } - check_attr(cnt, check, name, buf.buf); + check_attr(cnt, check, buf.buf); maybe_flush_or_die(stdout, "attribute to stdout"); } strbuf_release(&buf); @@ -113,10 +112,10 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } if (stdin_paths) - check_attr_stdin_paths(cnt, check, argv); + check_attr_stdin_paths(cnt, check); else { for (i = doubledash; i < argc; i++) - check_attr(cnt, check, argv, argv[i]); + check_attr(cnt, check, argv[i]); maybe_flush_or_die(stdout, "attribute to stdout"); } return 0; -- cgit v1.2.1 From a872701755347efe22be998d1e39f454fc422ff2 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:19 +0200 Subject: Teach prepare_attr_stack() to figure out dirlen itself Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/attr.c b/attr.c index bfa1f4379..7f0f390d5 100644 --- a/attr.c +++ b/attr.c @@ -535,11 +535,18 @@ static void bootstrap_attr_stack(void) } } -static void prepare_attr_stack(const char *path, int dirlen) +static void prepare_attr_stack(const char *path) { struct attr_stack *elem, *info; - int len; + int dirlen, len; struct strbuf pathbuf; + const char *cp; + + cp = strrchr(path, '/'); + if (!cp) + dirlen = 0; + else + dirlen = cp - path; strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE)); @@ -709,20 +716,14 @@ static int macroexpand_one(int attr_nr, int rem) int git_checkattr(const char *path, int num, struct git_attr_check *check) { struct attr_stack *stk; - const char *cp; - int dirlen, pathlen, i, rem; + int pathlen, i, rem; bootstrap_attr_stack(); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; pathlen = strlen(path); - cp = strrchr(path, '/'); - if (!cp) - dirlen = 0; - else - dirlen = cp - path; - prepare_attr_stack(path, dirlen); + prepare_attr_stack(path); rem = attr_nr; for (stk = attr_stack; 0 < rem && stk; stk = stk->prev) rem = fill(path, pathlen, stk, rem); -- cgit v1.2.1 From 2d72174492b926dffd15d5fd8f4239060fb12247 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:20 +0200 Subject: Extract a function collect_all_attrs() Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/attr.c b/attr.c index 7f0f390d5..bc589f0b7 100644 --- a/attr.c +++ b/attr.c @@ -713,20 +713,31 @@ static int macroexpand_one(int attr_nr, int rem) return rem; } -int git_checkattr(const char *path, int num, struct git_attr_check *check) +/* + * Collect all attributes for path into the array pointed to by + * check_all_attr. + */ +static void collect_all_attrs(const char *path) { struct attr_stack *stk; - int pathlen, i, rem; + int i, pathlen, rem; bootstrap_attr_stack(); + prepare_attr_stack(path); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; pathlen = strlen(path); - prepare_attr_stack(path); rem = attr_nr; for (stk = attr_stack; 0 < rem && stk; stk = stk->prev) rem = fill(path, pathlen, stk, rem); +} + +int git_checkattr(const char *path, int num, struct git_attr_check *check) +{ + int i; + + collect_all_attrs(path); for (i = 0; i < num; i++) { const char *value = check_all_attr[check[i].attr->attr_nr].value; -- cgit v1.2.1 From cd93bffb91630d8c695e1ac59239aa75cc2ebf92 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:21 +0200 Subject: Remove redundant call to bootstrap_attr_stack() prepare_attr_stack() does the same thing. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/attr.c b/attr.c index bc589f0b7..b8ce1586c 100644 --- a/attr.c +++ b/attr.c @@ -722,7 +722,6 @@ static void collect_all_attrs(const char *path) struct attr_stack *stk; int i, pathlen, rem; - bootstrap_attr_stack(); prepare_attr_stack(path); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; -- cgit v1.2.1 From 7373eab48e284a808cde766831172d3447f9e320 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:22 +0200 Subject: Remove redundant check bootstrap_attr_stack() also checks whether attr_stack is already set. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- attr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/attr.c b/attr.c index b8ce1586c..ab30c81b4 100644 --- a/attr.c +++ b/attr.c @@ -565,8 +565,7 @@ static void prepare_attr_stack(const char *path) * .gitattributes in deeper directories to shallower ones, * and finally use the built-in set as the default. */ - if (!attr_stack) - bootstrap_attr_stack(); + bootstrap_attr_stack(); /* * Pop the "info" one that is always at the top of the stack. -- cgit v1.2.1 From ee548df3005d976d4e6a78b3b4454fed812ea28c Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:23 +0200 Subject: Allow querying all attributes on a file Add a function, git_all_attrs(), that reports on all attributes that are set on a path. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/technical/api-gitattributes.txt | 44 ++++++++++++++++++--------- attr.c | 28 +++++++++++++++++ attr.h | 9 ++++++ 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt index ab3a84d2f..16ccb1cdc 100644 --- a/Documentation/technical/api-gitattributes.txt +++ b/Documentation/technical/api-gitattributes.txt @@ -22,19 +22,6 @@ Data Structure to `git_checkattr()` function, and receives the results. -Calling Sequence ----------------- - -* Prepare an array of `struct git_attr_check` to define the list of - attributes you would want to check. To populate this array, you would - need to define necessary attributes by calling `git_attr()` function. - -* Call git_checkattr() to check the attributes for the path. - -* Inspect `git_attr_check` structure to see how each of the attribute in - the array is defined for the path. - - Attribute Values ---------------- @@ -58,6 +45,19 @@ If none of the above returns true, `.value` member points at a string value of the attribute for the path. +Querying Specific Attributes +---------------------------- + +* Prepare an array of `struct git_attr_check` to define the list of + attributes you would want to check. To populate this array, you would + need to define necessary attributes by calling `git_attr()` function. + +* Call `git_checkattr()` to check the attributes for the path. + +* Inspect `git_attr_check` structure to see how each of the attribute in + the array is defined for the path. + + Example ------- @@ -109,4 +109,20 @@ static void setup_check(void) } ------------ -(JC) + +Querying All Attributes +----------------------- + +To get the values of all attributes associated with a file: + +* Call `git_all_attrs()`, which returns an array of `git_attr_check` + structures. + +* Iterate over the `git_attr_check` array to examine the attribute + names and values. The name of the attribute described by a + `git_attr_check` object can be retrieved via + `git_attr_name(check[i].attr)`. (Please note that no items will be + returned for unset attributes, so `ATTR_UNSET()` will return false + for all returned `git_array_check` objects.) + +* Free the `git_array_check` array. diff --git a/attr.c b/attr.c index ab30c81b4..658112eeb 100644 --- a/attr.c +++ b/attr.c @@ -747,6 +747,34 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check) return 0; } +int git_all_attrs(const char *path, int *num, struct git_attr_check **check) +{ + int i, count, j; + + collect_all_attrs(path); + + /* Count the number of attributes that are set. */ + count = 0; + for (i = 0; i < attr_nr; i++) { + const char *value = check_all_attr[i].value; + if (value != ATTR__UNSET && value != ATTR__UNKNOWN) + ++count; + } + *num = count; + *check = xmalloc(sizeof(**check) * count); + j = 0; + for (i = 0; i < attr_nr; i++) { + const char *value = check_all_attr[i].value; + if (value != ATTR__UNSET && value != ATTR__UNKNOWN) { + (*check)[j].attr = check_all_attr[i].attr; + (*check)[j].value = value; + ++j; + } + } + + return 0; +} + void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate) { enum git_attr_direction old = direction; diff --git a/attr.h b/attr.h index d4f875a3d..9e228933a 100644 --- a/attr.h +++ b/attr.h @@ -38,6 +38,15 @@ char *git_attr_name(struct git_attr *); int git_checkattr(const char *path, int, struct git_attr_check *); +/* + * Retrieve all attributes that apply to the specified path. *num + * will be set the the number of attributes on the path; **check will + * be set to point at a newly-allocated array of git_attr_check + * objects describing the attributes and their values. *check must be + * free()ed by the caller. + */ +int git_all_attrs(const char *path, int *num, struct git_attr_check **check); + enum git_attr_direction { GIT_ATTR_CHECKIN, GIT_ATTR_CHECKOUT, -- cgit v1.2.1 From 46f96a6d8ed70ecac7c1532d7f9775320409917b Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:24 +0200 Subject: git-check-attr: Extract a function output_attr() Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 5f04126d4..384c5a617 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -20,12 +20,10 @@ static const struct option check_attr_options[] = { OPT_END() }; -static void check_attr(int cnt, struct git_attr_check *check, +static void output_attr(int cnt, struct git_attr_check *check, const char *file) { int j; - if (git_checkattr(file, cnt, check)) - die("git_checkattr died"); for (j = 0; j < cnt; j++) { const char *value = check[j].value; @@ -41,6 +39,14 @@ static void check_attr(int cnt, struct git_attr_check *check, } } +static void check_attr(int cnt, struct git_attr_check *check, + const char *file) +{ + if (git_checkattr(file, cnt, check)) + die("git_checkattr died"); + output_attr(cnt, check, file); +} + static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) { struct strbuf buf, nbuf; -- cgit v1.2.1 From d6541bb1ac753a3cc0b92021cf82b07cf459cb28 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:25 +0200 Subject: git-check-attr: Introduce a new variable Avoid reusing variable "doubledash" to mean something other than the expected "position of a double-dash, if any". Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 384c5a617..c5270786d 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -71,7 +71,7 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) int cmd_check_attr(int argc, const char **argv, const char *prefix) { struct git_attr_check *check; - int cnt, i, doubledash; + int cnt, i, doubledash, filei; const char *errstr = NULL; argc = parse_options(argc, argv, prefix, check_attr_options, @@ -92,14 +92,15 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) /* If there is no double dash, we handle only one attribute */ if (doubledash < 0) { cnt = 1; - doubledash = 0; - } else + filei = 1; + } else { cnt = doubledash; - doubledash++; + filei = doubledash + 1; + } if (cnt <= 0) errstr = "No attribute specified"; - else if (stdin_paths && doubledash < argc) + else if (stdin_paths && filei < argc) errstr = "Can't specify files with --stdin"; if (errstr) { error("%s", errstr); @@ -120,7 +121,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) if (stdin_paths) check_attr_stdin_paths(cnt, check); else { - for (i = doubledash; i < argc; i++) + for (i = filei; i < argc; i++) check_attr(cnt, check, argv[i]); maybe_flush_or_die(stdout, "attribute to stdout"); } -- cgit v1.2.1 From 9e37a7e126c98513789ce60c4bec67d7940dbf4b Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:26 +0200 Subject: git-check-attr: Extract a function error_with_usage() Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index c5270786d..d0042227c 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -68,6 +68,12 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) strbuf_release(&nbuf); } +static NORETURN void error_with_usage(const char *msg) +{ + error("%s", msg); + usage_with_options(check_attr_usage, check_attr_options); +} + int cmd_check_attr(int argc, const char **argv, const char *prefix) { struct git_attr_check *check; @@ -103,8 +109,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) else if (stdin_paths && filei < argc) errstr = "Can't specify files with --stdin"; if (errstr) { - error("%s", errstr); - usage_with_options(check_attr_usage, check_attr_options); + error_with_usage(errstr); } check = xcalloc(cnt, sizeof(*check)); -- cgit v1.2.1 From 27937447efdf2b50e6294e94bde22f07c526b2de Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:27 +0200 Subject: git-check-attr: Handle each error separately This will make the code easier to refactor. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index d0042227c..de3fef734 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -78,7 +78,6 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) { struct git_attr_check *check; int cnt, i, doubledash, filei; - const char *errstr = NULL; argc = parse_options(argc, argv, prefix, check_attr_options, check_attr_usage, PARSE_OPT_KEEP_DASHDASH); @@ -105,12 +104,10 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } if (cnt <= 0) - errstr = "No attribute specified"; - else if (stdin_paths && filei < argc) - errstr = "Can't specify files with --stdin"; - if (errstr) { - error_with_usage(errstr); - } + error_with_usage("No attribute specified"); + + if (stdin_paths && filei < argc) + error_with_usage("Can't specify files with --stdin"); check = xcalloc(cnt, sizeof(*check)); for (i = 0; i < cnt; i++) { -- cgit v1.2.1 From 72541040c3ed00084344de5bf75cbc5a514504bb Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:28 +0200 Subject: git-check-attr: Process command-line args more systematically Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index de3fef734..e9b827ffb 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -81,8 +81,6 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, check_attr_options, check_attr_usage, PARSE_OPT_KEEP_DASHDASH); - if (!argc) - usage_with_options(check_attr_usage, check_attr_options); if (read_cache() < 0) { die("invalid cache"); @@ -94,8 +92,17 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) doubledash = i; } - /* If there is no double dash, we handle only one attribute */ - if (doubledash < 0) { + /* Check attribute argument(s): */ + if (doubledash == 0) { + error_with_usage("No attribute specified"); + } else if (doubledash < 0) { + /* + * There is no double dash; treat the first + * argument as an attribute. + */ + if (!argc) + error_with_usage("No attribute specified"); + cnt = 1; filei = 1; } else { @@ -103,9 +110,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) filei = doubledash + 1; } - if (cnt <= 0) - error_with_usage("No attribute specified"); - + /* Check file argument(s): */ if (stdin_paths && filei < argc) error_with_usage("Can't specify files with --stdin"); -- cgit v1.2.1 From fdf6be8259fc59fc251b325f66e86df0fe905e79 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:29 +0200 Subject: git-check-attr: Error out if no pathnames are specified If no pathnames are passed as command-line arguments and the --stdin option is not specified, fail with the error message "No file specified". Add tests of this behavior. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 9 +++++++-- t/t0003-attributes.sh | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index e9b827ffb..6cf642139 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -111,8 +111,13 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } /* Check file argument(s): */ - if (stdin_paths && filei < argc) - error_with_usage("Can't specify files with --stdin"); + if (stdin_paths) { + if (filei < argc) + error_with_usage("Can't specify files with --stdin"); + } else { + if (filei >= argc) + error_with_usage("No file specified"); + } check = xcalloc(cnt, sizeof(*check)); for (i = 0; i < cnt; i++) { diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index f1debeb7a..22540051d 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -46,6 +46,8 @@ test_expect_success 'command line checks' ' test_must_fail git check-attr && test_must_fail git check-attr -- && + test_must_fail git check-attr test && + test_must_fail git check-attr test -- && test_must_fail git check-attr -- f && echo "f" | test_must_fail git check-attr --stdin && echo "f" | test_must_fail git check-attr --stdin -- f && -- cgit v1.2.1 From 4ca0f188f6ece3098b60b6ba732e1e8551466f60 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:30 +0200 Subject: git-check-attr: Add an --all option to show all attributes Add new usage patterns git check-attr [-a | --all] [--] pathname... git check-attr --stdin [-a | --all] < which display all attributes associated with the specified file(s). Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/git-check-attr.txt | 16 +++++++++++-- builtin/check-attr.c | 52 +++++++++++++++++++++++++++------------- t/t0003-attributes.sh | 24 +++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index 30eca6cee..798e5d5b4 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -9,8 +9,8 @@ git-check-attr - Display gitattributes information SYNOPSIS -------- [verse] -'git check-attr' attr... [--] pathname... -'git check-attr' --stdin [-z] attr... < +'git check-attr' [-a | --all | attr...] [--] pathname... +'git check-attr' --stdin [-z] [-a | --all | attr...] < DESCRIPTION ----------- @@ -19,6 +19,11 @@ For every pathname, this command will list if each attribute is 'unspecified', OPTIONS ------- +-a, --all:: + List all attributes that are associated with the specified + paths. If this option is used, then 'unspecified' attributes + will not be included in the output. + --stdin:: Read file names from stdin instead of from the command-line. @@ -69,6 +74,13 @@ org/example/MyClass.java: diff: java org/example/MyClass.java: myAttr: set --------------- +* Listing all attributes for a file: +--------------- +$ git check-attr --all -- org/example/MyClass.java +org/example/MyClass.java: diff: java +org/example/MyClass.java: myAttr: set +--------------- + * Listing an attribute for multiple files: --------------- $ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 6cf642139..b0d2ebc3d 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -4,16 +4,18 @@ #include "quote.h" #include "parse-options.h" +static int all_attrs; static int stdin_paths; static const char * const check_attr_usage[] = { -"git check-attr attr... [--] pathname...", -"git check-attr --stdin attr... < ", +"git check-attr [-a | --all | attr...] [--] pathname...", +"git check-attr --stdin [-a | --all | attr...] < ", NULL }; static int null_term_line; static const struct option check_attr_options[] = { + OPT_BOOLEAN('a', "all", &all_attrs, "report all attributes set on file"), OPT_BOOLEAN(0 , "stdin", &stdin_paths, "read file names from stdin"), OPT_BOOLEAN('z', NULL, &null_term_line, "input paths are terminated by a null character"), @@ -42,9 +44,16 @@ static void output_attr(int cnt, struct git_attr_check *check, static void check_attr(int cnt, struct git_attr_check *check, const char *file) { - if (git_checkattr(file, cnt, check)) - die("git_checkattr died"); - output_attr(cnt, check, file); + if (check != NULL) { + if (git_checkattr(file, cnt, check)) + die("git_checkattr died"); + output_attr(cnt, check, file); + } else { + if (git_all_attrs(file, &cnt, &check)) + die("git_all_attrs died"); + output_attr(cnt, check, file); + free(check); + } } static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) @@ -92,8 +101,14 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) doubledash = i; } - /* Check attribute argument(s): */ - if (doubledash == 0) { + /* Process --all and/or attribute arguments: */ + if (all_attrs) { + if (doubledash >= 1) + error_with_usage("Attributes and --all both specified"); + + cnt = 0; + filei = doubledash + 1; + } else if (doubledash == 0) { error_with_usage("No attribute specified"); } else if (doubledash < 0) { /* @@ -119,15 +134,20 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) error_with_usage("No file specified"); } - check = xcalloc(cnt, sizeof(*check)); - for (i = 0; i < cnt; i++) { - const char *name; - struct git_attr *a; - name = argv[i]; - a = git_attr(name); - if (!a) - return error("%s: not a valid attribute name", name); - check[i].attr = a; + if (all_attrs) { + check = NULL; + } else { + check = xcalloc(cnt, sizeof(*check)); + for (i = 0; i < cnt; i++) { + const char *name; + struct git_attr *a; + name = argv[i]; + a = git_attr(name); + if (!a) + return error("%s: not a valid attribute name", + name); + check[i].attr = a; + } } if (stdin_paths) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 22540051d..8892ba3bb 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -107,6 +107,30 @@ EOF test_cmp expect actual ' +test_expect_success 'attribute test: --all option' ' + + cat < all && +f: test: f +a/f: test: f +a/c/f: test: f +a/g: test: a/g +a/b/g: test: a/b/g +b/g: test: unspecified +a/b/h: test: a/b/h +a/b/d/g: test: a/b/d/* +onoff: test: unset +offon: test: set +no: notest: set +a/b/d/no: test: a/b/d/* +a/b/d/no: notest: set +a/b/d/yes: notest: set +EOF + + grep -v unspecified < all | sort > expect && + sed -e "s/:.*//" < all | uniq | git check-attr --stdin --all | sort > actual && + test_cmp expect actual +' + test_expect_success 'root subdir attribute test' ' attr_check a/i a/i && -- cgit v1.2.1 From c9d8f0ac3b9029d825c7d1c049953aacbc489e1c Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:31 +0200 Subject: git-check-attr: Drive two tests using the same raw data Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 59 ++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 8892ba3bb..a49f8a981 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -38,7 +38,25 @@ test_expect_success 'setup' ' ) >a/b/.gitattributes && ( echo "global test=global" - ) >"$HOME"/global-gitattributes + ) >"$HOME"/global-gitattributes && + cat <expect-all +f: test: f +a/f: test: f +a/c/f: test: f +a/g: test: a/g +a/b/g: test: a/b/g +b/g: test: unspecified +a/b/h: test: a/b/h +a/b/d/g: test: a/b/d/* +onoff: test: unset +offon: test: set +no: notest: set +no: test: unspecified +a/b/d/no: notest: set +a/b/d/no: test: a/b/d/* +a/b/d/yes: notest: set +a/b/d/yes: test: unspecified +EOF ' @@ -87,47 +105,16 @@ test_expect_success 'core.attributesfile' ' test_expect_success 'attribute test: read paths from stdin' ' - cat < expect && -f: test: f -a/f: test: f -a/c/f: test: f -a/g: test: a/g -a/b/g: test: a/b/g -b/g: test: unspecified -a/b/h: test: a/b/h -a/b/d/g: test: a/b/d/* -onoff: test: unset -offon: test: set -no: test: unspecified -a/b/d/no: test: a/b/d/* -a/b/d/yes: test: unspecified -EOF - + grep -v notest < expect-all > expect && sed -e "s/:.*//" < expect | git check-attr --stdin test > actual && test_cmp expect actual ' test_expect_success 'attribute test: --all option' ' - cat < all && -f: test: f -a/f: test: f -a/c/f: test: f -a/g: test: a/g -a/b/g: test: a/b/g -b/g: test: unspecified -a/b/h: test: a/b/h -a/b/d/g: test: a/b/d/* -onoff: test: unset -offon: test: set -no: notest: set -a/b/d/no: test: a/b/d/* -a/b/d/no: notest: set -a/b/d/yes: notest: set -EOF - - grep -v unspecified < all | sort > expect && - sed -e "s/:.*//" < all | uniq | git check-attr --stdin --all | sort > actual && + grep -v unspecified < expect-all | sort > expect && + sed -e "s/:.*//" < expect-all | uniq | + git check-attr --stdin --all | sort > actual && test_cmp expect actual ' -- cgit v1.2.1 From ca64d061e0ddf7fa1496a15c75eb5e730c4360e0 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:32 +0200 Subject: git-check-attr: Fix command-line handling to match docs According to the git-check-attr synopsis, if the '--stdin' option is used then no pathnames are expected on the command line. Change the behavior to match this description; namely, if '--stdin' is used but not '--', then treat all command-line arguments as attribute names. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/git-check-attr.txt | 7 +++++-- builtin/check-attr.c | 15 +++++++++------ t/t0003-attributes.sh | 1 - 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index 798e5d5b4..1f7312a18 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -33,8 +33,11 @@ OPTIONS \--:: Interpret all preceding arguments as attributes and all following - arguments as path names. If not supplied, only the first argument will - be treated as an attribute. + arguments as path names. + +If none of `--stdin`, `--all`, or `--` is used, the first argument +will be treated as an attribute and the rest of the arguments as +pathnames. OUTPUT ------ diff --git a/builtin/check-attr.c b/builtin/check-attr.c index b0d2ebc3d..f20772ad6 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -111,15 +111,18 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } else if (doubledash == 0) { error_with_usage("No attribute specified"); } else if (doubledash < 0) { - /* - * There is no double dash; treat the first - * argument as an attribute. - */ if (!argc) error_with_usage("No attribute specified"); - cnt = 1; - filei = 1; + if (stdin_paths) { + /* Treat all arguments as attribute names. */ + cnt = argc; + filei = argc; + } else { + /* Treat exactly one argument as an attribute name. */ + cnt = 1; + filei = 1; + } } else { cnt = doubledash; filei = doubledash + 1; diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index a49f8a981..5acb2d5bb 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -70,7 +70,6 @@ test_expect_success 'command line checks' ' echo "f" | test_must_fail git check-attr --stdin && echo "f" | test_must_fail git check-attr --stdin -- f && echo "f" | test_must_fail git check-attr --stdin test -- f && - echo "f" | test_must_fail git check-attr --stdin test f && test_must_fail git check-attr "" -- f ' -- cgit v1.2.1 From d932f4eb9fc88e93040635d291f6c195ea2e4ee3 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:36:33 +0200 Subject: Rename git_checkattr() to git_check_attr() Suggested by: Junio Hamano Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/technical/api-gitattributes.txt | 8 ++++---- archive.c | 2 +- attr.c | 2 +- attr.h | 4 ++-- builtin/check-attr.c | 4 ++-- builtin/pack-objects.c | 2 +- convert.c | 2 +- ll-merge.c | 4 ++-- userdiff.c | 2 +- ws.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt index 16ccb1cdc..ce363b630 100644 --- a/Documentation/technical/api-gitattributes.txt +++ b/Documentation/technical/api-gitattributes.txt @@ -19,7 +19,7 @@ Data Structure `struct git_attr_check`:: This structure represents a set of attributes to check in a call - to `git_checkattr()` function, and receives the results. + to `git_check_attr()` function, and receives the results. Attribute Values @@ -52,7 +52,7 @@ Querying Specific Attributes attributes you would want to check. To populate this array, you would need to define necessary attributes by calling `git_attr()` function. -* Call `git_checkattr()` to check the attributes for the path. +* Call `git_check_attr()` to check the attributes for the path. * Inspect `git_attr_check` structure to see how each of the attribute in the array is defined for the path. @@ -78,13 +78,13 @@ static void setup_check(void) } ------------ -. Call `git_checkattr()` with the prepared array of `struct git_attr_check`: +. Call `git_check_attr()` with the prepared array of `struct git_attr_check`: ------------ const char *path; setup_check(); - git_checkattr(path, ARRAY_SIZE(check), check); + git_check_attr(path, ARRAY_SIZE(check), check); ------------ . Act on `.value` member of the result, left in `check[]`: diff --git a/archive.c b/archive.c index 2a7a28e3e..3fd7f475f 100644 --- a/archive.c +++ b/archive.c @@ -123,7 +123,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, path_without_prefix = path.buf + args->baselen; setup_archive_check(check); - if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) { + if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) { if (ATTR_TRUE(check[0].value)) return 0; convert = ATTR_TRUE(check[1].value); diff --git a/attr.c b/attr.c index 658112eeb..da29c8eb4 100644 --- a/attr.c +++ b/attr.c @@ -731,7 +731,7 @@ static void collect_all_attrs(const char *path) rem = fill(path, pathlen, stk, rem); } -int git_checkattr(const char *path, int num, struct git_attr_check *check) +int git_check_attr(const char *path, int num, struct git_attr_check *check) { int i; diff --git a/attr.h b/attr.h index 9e228933a..eb8ca0d7c 100644 --- a/attr.h +++ b/attr.h @@ -20,7 +20,7 @@ extern const char git_attr__false[]; #define ATTR_UNSET(v) ((v) == NULL) /* - * Send one or more git_attr_check to git_checkattr(), and + * Send one or more git_attr_check to git_check_attr(), and * each 'value' member tells what its value is. * Unset one is returned as NULL. */ @@ -36,7 +36,7 @@ struct git_attr_check { */ char *git_attr_name(struct git_attr *); -int git_checkattr(const char *path, int, struct git_attr_check *); +int git_check_attr(const char *path, int, struct git_attr_check *); /* * Retrieve all attributes that apply to the specified path. *num diff --git a/builtin/check-attr.c b/builtin/check-attr.c index f20772ad6..6b163687b 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -45,8 +45,8 @@ static void check_attr(int cnt, struct git_attr_check *check, const char *file) { if (check != NULL) { - if (git_checkattr(file, cnt, check)) - die("git_checkattr died"); + if (git_check_attr(file, cnt, check)) + die("git_check_attr died"); output_attr(cnt, check, file); } else { if (git_all_attrs(file, &cnt, &check)) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 84e6dafb1..ac8bed8aa 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -634,7 +634,7 @@ static int no_try_delta(const char *path) struct git_attr_check check[1]; setup_delta_attr_check(check); - if (git_checkattr(path, ARRAY_SIZE(check), check)) + if (git_check_attr(path, ARRAY_SIZE(check), check)) return 0; if (ATTR_FALSE(check->value)) return 1; diff --git a/convert.c b/convert.c index 85939c29b..416bf83c7 100644 --- a/convert.c +++ b/convert.c @@ -727,7 +727,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path) git_config(read_convert_config, NULL); } - if (!git_checkattr(path, NUM_CONV_ATTRS, ccheck)) { + if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) { ca->crlf_action = git_path_check_crlf(path, ccheck + 4); if (ca->crlf_action == CRLF_GUESS) ca->crlf_action = git_path_check_crlf(path, ccheck + 0); diff --git a/ll-merge.c b/ll-merge.c index 6ce512efc..da59738c9 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -330,7 +330,7 @@ static int git_path_check_merge(const char *path, struct git_attr_check check[2] check[0].attr = git_attr("merge"); check[1].attr = git_attr("conflict-marker-size"); } - return git_checkattr(path, 2, check); + return git_check_attr(path, 2, check); } static void normalize_file(mmfile_t *mm, const char *path) @@ -387,7 +387,7 @@ int ll_merge_marker_size(const char *path) if (!check.attr) check.attr = git_attr("conflict-marker-size"); - if (!git_checkattr(path, 1, &check) && check.value) { + if (!git_check_attr(path, 1, &check) && check.value) { marker_size = atoi(check.value); if (marker_size <= 0) marker_size = DEFAULT_CONFLICT_MARKER_SIZE; diff --git a/userdiff.c b/userdiff.c index 01d3a8b81..bf553ad91 100644 --- a/userdiff.c +++ b/userdiff.c @@ -270,7 +270,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path) if (!path) return NULL; - if (git_checkattr(path, 1, &check)) + if (git_check_attr(path, 1, &check)) return NULL; if (ATTR_TRUE(check.value)) diff --git a/ws.c b/ws.c index 9fb9b1476..b498d7599 100644 --- a/ws.c +++ b/ws.c @@ -88,7 +88,7 @@ unsigned whitespace_rule(const char *pathname) struct git_attr_check attr_whitespace_rule; setup_whitespace_attr_check(&attr_whitespace_rule); - if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) { + if (!git_check_attr(pathname, 1, &attr_whitespace_rule)) { const char *value; value = attr_whitespace_rule.value; -- cgit v1.2.1 From fa92f3233c65251c3311f0834526ce96a1963554 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:43 +0200 Subject: git-check-attr: test that no output is written to stderr Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 5acb2d5bb..4f2fbc078 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -9,9 +9,10 @@ attr_check () { path="$1" expect="$2" - git check-attr test -- "$path" >actual && + git check-attr test -- "$path" >actual 2>err && echo "$path: test: $2" >expect && - test_cmp expect actual + test_cmp expect actual && + test_line_count = 0 err } -- cgit v1.2.1 From d4d4f8df14c3c19d445a8a79dca56bd33812ee04 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:44 +0200 Subject: git-check-attr: Demonstrate problems with unnormalized paths Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 4f2fbc078..43957eae6 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -93,6 +93,15 @@ test_expect_success 'attribute test' ' ' +test_expect_failure 'unnormalized paths' ' + + attr_check ./f f && + attr_check ./a/g a/g && + attr_check a/./g a/g && + attr_check a/c/../b/g a/b/g + +' + test_expect_success 'core.attributesfile' ' attr_check global unspecified && git config core.attributesfile "$HOME/global-gitattributes" && -- cgit v1.2.1 From 0216af8356ef562147251c40fef72be25b8b9b07 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:45 +0200 Subject: git-check-attr: Demonstrate problems with relative paths Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- t/t0003-attributes.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 43957eae6..f6cf77d12 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -19,7 +19,7 @@ attr_check () { test_expect_success 'setup' ' - mkdir -p a/b/d a/c && + mkdir -p a/b/d a/c b && ( echo "[attr]notest !test" echo "f test=f" @@ -102,6 +102,19 @@ test_expect_failure 'unnormalized paths' ' ' +test_expect_failure 'relative paths' ' + + (cd a && attr_check ../f f) && + (cd a && attr_check f f) && + (cd a && attr_check i a/i) && + (cd a && attr_check g a/g) && + (cd a && attr_check b/g a/b/g) && + (cd b && attr_check ../a/f f) && + (cd b && attr_check ../a/g a/g) && + (cd b && attr_check ../a/b/g a/b/g) + +' + test_expect_success 'core.attributesfile' ' attr_check global unspecified && git config core.attributesfile "$HOME/global-gitattributes" && -- cgit v1.2.1 From f5114a40c0d0276ce6ff215a3dc51eb19da5b420 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:46 +0200 Subject: git-check-attr: Normalize paths Normalize the path arguments (relative to the working tree root, if applicable) before looking up their attributes. This requires passing the prefix down the call chain. This fixes two test cases for different reasons: * "unnormalized paths" is fixed because the .gitattribute-file-seeking code is not confused into reading the top-level file twice. * "relative paths" is fixed because the canonical pathnames are passed to get_check_attr() or get_all_attrs(), allowing them to match the pathname patterns as expected. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- builtin/check-attr.c | 20 ++++++++++++-------- t/t0003-attributes.sh | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 6b163687b..708988a0e 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -41,22 +41,26 @@ static void output_attr(int cnt, struct git_attr_check *check, } } -static void check_attr(int cnt, struct git_attr_check *check, - const char *file) +static void check_attr(const char *prefix, int cnt, + struct git_attr_check *check, const char *file) { + char *full_path = + prefix_path(prefix, prefix ? strlen(prefix) : 0, file); if (check != NULL) { - if (git_check_attr(file, cnt, check)) + if (git_check_attr(full_path, cnt, check)) die("git_check_attr died"); output_attr(cnt, check, file); } else { - if (git_all_attrs(file, &cnt, &check)) + if (git_all_attrs(full_path, &cnt, &check)) die("git_all_attrs died"); output_attr(cnt, check, file); free(check); } + free(full_path); } -static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) +static void check_attr_stdin_paths(const char *prefix, int cnt, + struct git_attr_check *check) { struct strbuf buf, nbuf; int line_termination = null_term_line ? 0 : '\n'; @@ -70,7 +74,7 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check) die("line is badly quoted"); strbuf_swap(&buf, &nbuf); } - check_attr(cnt, check, buf.buf); + check_attr(prefix, cnt, check, buf.buf); maybe_flush_or_die(stdout, "attribute to stdout"); } strbuf_release(&buf); @@ -154,10 +158,10 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } if (stdin_paths) - check_attr_stdin_paths(cnt, check); + check_attr_stdin_paths(prefix, cnt, check); else { for (i = filei; i < argc; i++) - check_attr(cnt, check, argv[i]); + check_attr(prefix, cnt, check, argv[i]); maybe_flush_or_die(stdout, "attribute to stdout"); } return 0; diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index f6cf77d12..ae2f1da28 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -93,7 +93,7 @@ test_expect_success 'attribute test' ' ' -test_expect_failure 'unnormalized paths' ' +test_expect_success 'unnormalized paths' ' attr_check ./f f && attr_check ./a/g a/g && @@ -102,7 +102,7 @@ test_expect_failure 'unnormalized paths' ' ' -test_expect_failure 'relative paths' ' +test_expect_success 'relative paths' ' (cd a && attr_check ../f f) && (cd a && attr_check f f) && -- cgit v1.2.1 From 87a246e1b562544c25af66f4712cd81bc64f2d44 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:47 +0200 Subject: test-path-utils: Add subcommand "absolute_path" Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- test-path-utils.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test-path-utils.c b/test-path-utils.c index e7671593d..a410e3026 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -20,6 +20,15 @@ int main(int argc, char **argv) return 0; } + if (argc >= 2 && !strcmp(argv[1], "absolute_path")) { + while (argc > 2) { + puts(absolute_path(argv[2])); + argc--; + argv++; + } + return 0; + } + if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { int len = longest_ancestor_length(argv[2], argv[3]); printf("%d\n", len); -- cgit v1.2.1 From 9e8137238d1b7f558dd61c8737883e73c8368e4b Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Thu, 4 Aug 2011 06:47:48 +0200 Subject: test-path-utils: Add subcommand "prefix_path" Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- test-path-utils.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test-path-utils.c b/test-path-utils.c index a410e3026..3bc20e91d 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -35,6 +35,19 @@ int main(int argc, char **argv) return 0; } + if (argc >= 4 && !strcmp(argv[1], "prefix_path")) { + char *prefix = argv[2]; + int prefix_len = strlen(prefix); + int nongit_ok; + setup_git_directory_gently(&nongit_ok); + while (argc > 3) { + puts(prefix_path(prefix, prefix_len, argv[3])); + argc--; + argv++; + } + return 0; + } + if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) { char *prefix = strip_path_suffix(argv[2], argv[3]); printf("%s\n", prefix ? prefix : "(null)"); -- cgit v1.2.1