threads / patch / 27928

patch, 19 partsProvide access to the name attribute of git_attr

Subject: [PATCH 07/19] Provide access to the name attribute of git_attr

## tl;dr

24 messages between Jul 26, 2011 and Jul 28, 2011. Diffs are folded; open one to read it.

replies: 23people: 2as markdown or json

Michael Haggerty· Jul 26, 2011, 14:12 UTC · lore

[PATCH 00/19] Add --all option to git-check-attr

Currently it is possible to inquire the values of particular attributes on particular files, using either the API function git_checkattr() or the command "git check-attr". But it is not possible to ask for *all* attributes that are associated with a particular file. This patch series adds that functionality:

* A new API call git_allattr()
* A new option "git check-attr --all -- pathnames"

Along the way, several small cleanups are made in the general neighborhood, including:

* Disallow the empty string as an attribute name
* Provide access to the name attribute of git_attr
* Fail with an error message if no pathnames are provided on the
  command line (and --stdin is not used)
* If --stdin is used, interpret all command-line arguments as
  attribute names
* Rename struct git_attr_check to git_attr_value

Most of the patches are hopefully self-explanatory; see the individual patch emails for discussion of changes that might potentially be controversial.

Michael Haggerty (19):
  doc: Add a link from gitattributes(5) to git-check-attr(1)
  doc: Correct git_attr() calls in example code
  Remove anachronism from comment
  Disallow the empty string as an attribute name
  git-check-attr: Add missing "&&"
  git-check-attr: Add tests of command-line parsing
  Provide access to the name attribute of git_attr
  git-check-attr: Use git_attr_name()
  Allow querying all attributes on a file
  git-check-attr: Extract a function output_attr()
  git-check-attr: Introduce a new variable
  git-check-attr: Extract a function error_with_usage()
  git-check-attr: Handle each error separately
  git-check-attr: Process command-line args more systematically
  git-check-attr: Error out if no pathnames are specified
  git-check-attr: Add an --all option to show all attributes
  git-check-attr: Drive two tests using the same raw data
  git-check-attr: Fix command-line handling to match docs
  Rename struct git_attr_check to git_attr_value
 Documentation/git-check-attr.txt              |   23 ++++-
 Documentation/gitattributes.txt               |    3 +
 Documentation/technical/api-gitattributes.txt |   66 +++++++++-----
 archive.c                                     |    4 +-
 attr.c                                        |   61 +++++++++++--
 attr.h                                        |   24 ++++-
 builtin/check-attr.c                          |  123 ++++++++++++++++--------
 builtin/pack-objects.c                        |    4 +-
 convert.c                                     |   10 +-
 ll-merge.c                                    |    6 +-
 t/t0003-attributes.sh                         |   61 +++++++++----
 userdiff.c                                    |    2 +-
 ws.c                                          |    4 +-
 13 files changed, 278 insertions(+), 113 deletions(-)
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 01/19] doc: Add a link from gitattributes(5) to git-check-attr(1)

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 Documentation/gitattributes.txt |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
Show changes to Documentation/gitattributes.txt +3 −0
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 412c55b..3d86434 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -952,6 +952,9 @@ frotz	unspecified
 ----------------------------------------------------------------
 
 
+SEE ALSO
+--------
+linkgit:git-check-attr[1].
 
 GIT
 ---
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 02/19] 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 <mhagger@alum.mit.edu>
---
 Documentation/technical/api-gitattributes.txt |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
Show changes to Documentation/technical/api-gitattributes.txt +5 −5
diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt
index 9d97eaa..916720f 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");
 }
 ------------
 
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 03/19] 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 <mhagger@alum.mit.edu>
---
 attr.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)
Show changes to attr.c +2 −4
diff --git a/attr.c b/attr.c
index f6b3f7e..4a1244f 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;
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 04/19] 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 <mhagger@alum.mit.edu>
---

Currently it is possible to use the empty string as an attribute name. For example, a .gitattributes file can have a line

    file.txt =foo
and git-check-attr can be invoked as
    git check-attr '' -- file.txt

Indeed, the above command invocation would report that attribute '' has value 'foo' (though the output looks weird).

I believe this behavior to be a bug, so this patch prohibits the empty string as an attribute name. Any attempt to use the empty string as an attribute name will now trigger the error message "error: : not a valid attribute name"

Please note that it is conceivable that there are existing repositories with .gitattributes files that set empty attributes. If so, any attempt to read *any* attributes from a file in an affected directory will fail with the above error message.

 attr.c                |    2 +-
 t/t0003-attributes.sh |    6 ++++++
 2 files changed, 7 insertions(+), 1 deletions(-)
Show changes to 2 files +7 −1

attr.c, t/t0003-attributes.sh

diff --git a/attr.c b/attr.c
index 4a1244f..b1d1d6d 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 ebbc755..8c76b79 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 &&
-- 
1.7.6.8.gd2879
Junio C Hamano· Jul 27, 2011, 20:20 UTC · re: Michael Haggerty · lore

Re: [PATCH 04/19] Disallow the empty string as an attribute name

Michael Haggerty <mhagger@alum.mit.edu> writes:
> 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.
Good. Very much appreciated.
> Currently it is possible to use the empty string as an attribute name.
Yeah, even I wouldn't call it a regression to disallow this ;-).
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 05/19] git-check-attr: Add missing "&&"

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t0003-attributes.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Show changes to t/t0003-attributes.sh +1 −1
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 8c76b79..dae76b3 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
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 06/19] git-check-attr: Add tests of command-line parsing

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t0003-attributes.sh |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
Show changes to t/t0003-attributes.sh +7 −0
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index dae76b3..f1debeb 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
 
 '
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

It will be present in any likely future reimplementation, and its availability simplifies other code.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---

struct git_attr is an opaque structure containing, among other things, the name of the attribute that it represents. This patch adds a function git_attr_name(struct git_attr *) that allows the name to be read from the structure. This functionality will be convenient for later patches.

This seems harmless to me. It is hardly conceivable that the implementation will change so dramatically that it becomes impossible to derive the attribute name from the git_attr.

Please check that the name that I chose for this function conforms to git conventions.

 Documentation/technical/api-gitattributes.txt |    3 ++-
 attr.c                                        |    4 ++++
 attr.h                                        |    7 +++++++
 3 files changed, 13 insertions(+), 1 deletions(-)
Show changes to 3 files +13 −1

Documentation/technical/api-gitattributes.txt, attr.c, attr.h

diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt
index 916720f..ab3a84d 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 b1d1d6d..a261550 100644
--- a/attr.c
+++ b/attr.c
@@ -36,6 +36,10 @@ 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 8b3f19b..d4f875a 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 {
-- 
1.7.6.8.gd2879
Junio C Hamano· Jul 27, 2011, 20:02 UTC · re: Michael Haggerty · lore

Re: [PATCH 07/19] Provide access to the name attribute of git_attr

Michael Haggerty <mhagger@alum.mit.edu> writes:
> It will be present in any likely future reimplementation, and its
> availability simplifies other code.
Looks good to me except for minor nits.
Show 9 quoted lines
> struct git_attr is an opaque structure containing, among other things,
> the name of the attribute that it represents.  This patch adds a
> function git_attr_name(struct git_attr *) that allows the name to be
> read from the structure.  This functionality will be convenient for
> later patches.
>
> This seems harmless to me.  It is hardly conceivable that the
> implementation will change so dramatically that it becomes impossible
> to derive the attribute name from the git_attr.

The original design of attribute API wanted to make sure that the callers do not have to care what _other_ attributes are on the path, and defined only "if you have a specific name, you can ask if that is set". Of course once you start wanting to enumerate the attributes without knowing what attributes may exist in the world, you would need an API to grab all the attributes and then find out the name of each of them. So I think this is not just harmless but is necessary.

Show 5 quoted lines
> diff --git a/attr.c b/attr.c
> ...
> +char *git_attr_name(struct git_attr *attr) {
> +	return attr->name;
> +}
(Style)
	char *git_attr_name(struct git_attr *attr)
	{
		return attr->name;
	}
Show 7 quoted lines
> diff --git a/attr.h b/attr.h
> ...
> +/*
> + * 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.
> + */
should not be modified NOR freed?
Michael Haggerty· Jul 28, 2011, 04:27 UTC · re: Junio C Hamano · lore

Re: [PATCH 07/19] Provide access to the name attribute of git_attr

On 07/27/2011 10:02 PM, Junio C Hamano wrote:
Show 13 quoted lines
> Michael Haggerty <mhagger@alum.mit.edu> writes:
>> diff --git a/attr.c b/attr.c
>> ...
>> +char *git_attr_name(struct git_attr *attr) {
>> +	return attr->name;
>> +}
> 
> (Style)
> 
> 	char *git_attr_name(struct git_attr *attr)
> 	{
> 		return attr->name;
> 	}
Thanks.  I will include this in the next version of the patch series.
Show 9 quoted lines
>> diff --git a/attr.h b/attr.h
>> ...
>> +/*
>> + * 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.
>> + */
> 
> should not be modified NOR freed?

No, usually "nor" is only used with "neither". I'm confident that the wording that I used is correct [1]. Alternatively, one could write "should be neither modified nor freed".

Michael

[1] See, e.g., http://grammar.quickanddirtytips.com/when-to-use-nor.aspx section "When to Use “Or” Instead of “Nor”".

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 08/19] git-check-attr: Use git_attr_name()

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)
Show changes to builtin/check-attr.c +6 −7
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 3016d29..5f04126 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;
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 09/19] Allow querying all attributes on a file

Add a function, git_allattrs(), that reports on all attributes that are set on a path.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
Please check that the function name conforms to git conventions.
 Documentation/technical/api-gitattributes.txt |   45 +++++++++++++++++-------
 attr.c                                        |   43 +++++++++++++++++++++++
 attr.h                                        |    9 +++++
 3 files changed, 84 insertions(+), 13 deletions(-)
Show changes to 3 files +84 −12

Documentation/technical/api-gitattributes.txt, attr.c, attr.h

diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt
index ab3a84d..640240e 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,23 @@ static void setup_check(void)
 	}
 ------------
 
+
+Querying All Attributes
+-----------------------
+
+To get the values of all attributes associated with a file:
+
+* Call `git_allattrs()`, 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.
+
+
 (JC)
diff --git a/attr.c b/attr.c
index a261550..976c830 100644
--- a/attr.c
+++ b/attr.c
@@ -736,6 +736,49 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
 	return 0;
 }
 
+int git_allattrs(const char *path, int *num, struct git_attr_check **check)
+{
+	struct attr_stack *stk;
+	const char *cp;
+	int dirlen, pathlen, i, rem, count, j;
+
+	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);
+	rem = attr_nr;
+	for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
+		rem = fill(path, pathlen, stk, rem);
+
+	/* 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_all_attr) * 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 d4f875a..83202f0 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_allattrs(const char *path, int *num, struct git_attr_check **check);
+
 enum git_attr_direction {
 	GIT_ATTR_CHECKIN,
 	GIT_ATTR_CHECKOUT,
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 10/19] git-check-attr: Extract a function output_attr()

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
Show changes to builtin/check-attr.c +9 −3
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 5f04126..384c5a6 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;
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 11/19] 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 <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)
Show changes to builtin/check-attr.c +7 −6
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 384c5a6..c527078 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");
 	}
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 12/19] git-check-attr: Extract a function error_with_usage()

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
Show changes to builtin/check-attr.c +7 −2
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index c527078..d004222 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));
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 13/19] git-check-attr: Handle each error separately

This will make the code easier to refactor.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)
Show changes to builtin/check-attr.c +4 −7
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index d004222..de3fef7 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++) {
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 14/19] git-check-attr: Process command-line args more systematically

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/check-attr.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)
Show changes to builtin/check-attr.c +12 −7
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index de3fef7..e9b827f 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");
 
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 15/19] 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 <mhagger@alum.mit.edu>
---

The documentation seems to require at least one pathname, and other git commands seem to insist on pathname lists not being empty. Add a similar test to git-check-attr. If it is considered likely that people depend on the current behavior, I have no problem with skipping this patch.

 builtin/check-attr.c  |    9 +++++++--
 t/t0003-attributes.sh |    2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)
Show changes to 2 files +9 −2

builtin/check-attr.c, t/t0003-attributes.sh

diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index e9b827f..6cf6421 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 f1debeb..2254005 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 &&
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:12 UTC · re: Michael Haggerty · lore

[PATCH 16/19] git-check-attr: Add an --all option to show all attributes

Add new usage patterns
    git check-attr --all [--] pathname...
    git check-attr --stdin --all < <list-of-paths>
which display all attributes associated with the specified file(s).
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---

One non-obvious design choice is that if --all is specified but not '--', then all of the arguments are interpreted as pathnames.

 Documentation/git-check-attr.txt |   16 ++++++++++-
 builtin/check-attr.c             |   52 ++++++++++++++++++++++++++-----------
 t/t0003-attributes.sh            |   24 +++++++++++++++++
 3 files changed, 74 insertions(+), 18 deletions(-)
Show changes to 3 files +74 −18

Documentation/git-check-attr.txt, builtin/check-attr.c, t/t0003-attributes.sh

diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index 30eca6c..3afa9b1 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... < <list-of-paths>
+'git check-attr' [--all | attr...] [--] pathname...
+'git check-attr' --stdin [-z] [--all | attr...] < <list-of-paths>
 
 DESCRIPTION
 -----------
@@ -19,6 +19,11 @@ For every pathname, this command will list if each attribute is 'unspecified',
 
 OPTIONS
 -------
+--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 6cf6421..ecf420f 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... < <list-of-paths>",
+"git check-attr [--all | attr...] [--] pathname...",
+"git check-attr --stdin [--all | attr...] < <list-of-paths>",
 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_allattrs(file, &cnt, &check))
+			die("git_allattrs 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 2254005..8892ba3 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 <<EOF > 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 &&
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 28, 2011, 04:31 UTC · re: Michael Haggerty · lore

Re: [PATCH 16/19] git-check-attr: Add an --all option to show all attributes

On 07/26/2011 04:12 PM, Michael Haggerty wrote:
Show 6 quoted lines
> Add new usage patterns
> 
>     git check-attr --all [--] pathname...
>     git check-attr --stdin --all < <list-of-paths>
> 
> which display all attributes associated with the specified file(s).

I realized that I also added the synonym "-a" but forgot to mention it in the docs or commit message. I will fix this in the next version of the patch series.

Michael
-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Michael Haggerty· Jul 26, 2011, 14:13 UTC · re: Michael Haggerty · lore

[PATCH 17/19] git-check-attr: Drive two tests using the same raw data

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t0003-attributes.sh |   59 +++++++++++++++++++-----------------------------
 1 files changed, 23 insertions(+), 36 deletions(-)
Show changes to t/t0003-attributes.sh +23 −36
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 8892ba3..a49f8a9 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 <<EOF >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 <<EOF > 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 <<EOF > 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
 '
 
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:13 UTC · re: Michael Haggerty · lore

[PATCH 18/19] 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 <mhagger@alum.mit.edu>
---

Previously, such invocations either had exactly one argument (and functioned the same as with this patch), or they failed with the message "Can't specify files with --stdin".

 Documentation/git-check-attr.txt |    7 +++++--
 builtin/check-attr.c             |   15 +++++++++------
 t/t0003-attributes.sh            |    1 -
 3 files changed, 14 insertions(+), 9 deletions(-)
Show changes to 3 files +14 −9

Documentation/git-check-attr.txt, builtin/check-attr.c, t/t0003-attributes.sh

diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index 3afa9b1..902d5ca 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 ecf420f..29613d4 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 a49f8a9..5acb2d5 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
 
 '
-- 
1.7.6.8.gd2879
Michael Haggerty· Jul 26, 2011, 14:13 UTC · re: Michael Haggerty · lore

[PATCH 19/19] Rename struct git_attr_check to git_attr_value

This described its purpose better, especially when used with git_allattrs().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---

This change makes the name of the structure more closely match its uses. However, if git makes backwards-compatibility guarantees for its API, such a renaming might be prohibited. If so, this patch can be left off the series.

 Documentation/technical/api-gitattributes.txt |   20 ++++++++++----------
 archive.c                                     |    4 ++--
 attr.c                                        |    8 ++++----
 attr.h                                        |   12 ++++++------
 builtin/check-attr.c                          |    8 ++++----
 builtin/pack-objects.c                        |    4 ++--
 convert.c                                     |   10 +++++-----
 ll-merge.c                                    |    6 +++---
 userdiff.c                                    |    2 +-
 ws.c                                          |    4 ++--
 10 files changed, 39 insertions(+), 39 deletions(-)
Show changes to 10 files +39 −39

Documentation/technical/api-gitattributes.txt, archive.c, attr.c, attr.h, builtin/check-attr.c, builtin/pack-objects.c, convert.c, ll-merge.c, userdiff.c, ws.c

diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt
index 640240e..c64969d 100644
--- a/Documentation/technical/api-gitattributes.txt
+++ b/Documentation/technical/api-gitattributes.txt
@@ -16,7 +16,7 @@ Data Structure
 	of no interest to the calling programs.  The name of the
 	attribute can be retrieved by calling `git_attr_name()`.
 
-`struct git_attr_check`::
+`struct git_attr_value`::
 
 	This structure represents a set of attributes to check in a call
 	to `git_checkattr()` function, and receives the results.
@@ -27,7 +27,7 @@ Attribute Values
 
 An attribute for a path can be in one of four states: Set, Unset,
 Unspecified or set to a string, and `.value` member of `struct
-git_attr_check` records it.  There are three macros to check these:
+git_attr_value` records it.  There are three macros to check these:
 
 `ATTR_TRUE()`::
 
@@ -48,13 +48,13 @@ value of the attribute for the path.
 Querying Specific Attributes
 ----------------------------
 
-* Prepare an array of `struct git_attr_check` to define the list of
+* Prepare an array of `struct git_attr_value` 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
+* Inspect `git_attr_value` structure to see how each of the attribute in
   the array is defined for the path.
 
 
@@ -63,12 +63,12 @@ Example
 
 To see how attributes "crlf" and "indent" are set for different paths.
 
-. Prepare an array of `struct git_attr_check` with two elements (because
+. Prepare an array of `struct git_attr_value` with two elements (because
   we are checking two attributes).  Initialize their `attr` member with
   pointers to `struct git_attr` obtained by calling `git_attr()`:
 
 ------------
-static struct git_attr_check check[2];
+static struct git_attr_value check[2];
 static void setup_check(void)
 {
 	if (check[0].attr)
@@ -78,7 +78,7 @@ static void setup_check(void)
 }
 ------------
 
-. Call `git_checkattr()` with the prepared array of `struct git_attr_check`:
+. Call `git_checkattr()` with the prepared array of `struct git_attr_value`:
 
 ------------
 	const char *path;
@@ -115,12 +115,12 @@ Querying All Attributes
 
 To get the values of all attributes associated with a file:
 
-* Call `git_allattrs()`, which returns an array of `git_attr_check`
+* Call `git_allattrs()`, which returns an array of `git_attr_value`
   structures.
 
-* Iterate over the `git_attr_check` array to examine the attribute
+* Iterate over the `git_attr_value` 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_value` 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.)
diff --git a/archive.c b/archive.c
index 2a7a28e..9a180b6 100644
--- a/archive.c
+++ b/archive.c
@@ -81,7 +81,7 @@ static void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
 	return buffer;
 }
 
-static void setup_archive_check(struct git_attr_check *check)
+static void setup_archive_check(struct git_attr_value *check)
 {
 	static struct git_attr *attr_export_ignore;
 	static struct git_attr *attr_export_subst;
@@ -107,7 +107,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
 	struct archiver_context *c = context;
 	struct archiver_args *args = c->args;
 	write_archive_entry_fn_t write_entry = c->write_entry;
-	struct git_attr_check check[2];
+	struct git_attr_value check[2];
 	const char *path_without_prefix;
 	int convert = 0;
 	int err;
diff --git a/attr.c b/attr.c
index 976c830..ec50ba5 100644
--- a/attr.c
+++ b/attr.c
@@ -33,7 +33,7 @@ struct git_attr {
 };
 static int attr_nr;
 
-static struct git_attr_check *check_all_attr;
+static struct git_attr_value *check_all_attr;
 static struct git_attr *(git_attr_hash[HASHSIZE]);
 
 char *git_attr_name(struct git_attr *attr) {
@@ -645,7 +645,7 @@ static int macroexpand_one(int attr_nr, int rem);
 
 static int fill_one(const char *what, struct match_attr *a, int rem)
 {
-	struct git_attr_check *check = check_all_attr;
+	struct git_attr_value *check = check_all_attr;
 	int i;
 
 	for (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {
@@ -705,7 +705,7 @@ static int macroexpand_one(int attr_nr, int rem)
 	return rem;
 }
 
-int git_checkattr(const char *path, int num, struct git_attr_check *check)
+int git_checkattr(const char *path, int num, struct git_attr_value *check)
 {
 	struct attr_stack *stk;
 	const char *cp;
@@ -736,7 +736,7 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
 	return 0;
 }
 
-int git_allattrs(const char *path, int *num, struct git_attr_check **check)
+int git_allattrs(const char *path, int *num, struct git_attr_value **check)
 {
 	struct attr_stack *stk;
 	const char *cp;
diff --git a/attr.h b/attr.h
index 83202f0..4dc4db0 100644
--- a/attr.h
+++ b/attr.h
@@ -14,17 +14,17 @@ struct git_attr *git_attr(const char *);
 extern const char git_attr__true[];
 extern const char git_attr__false[];
 
-/* For public to check git_attr_check results */
+/* For public to check git_attr_value results */
 #define ATTR_TRUE(v) ((v) == git_attr__true)
 #define ATTR_FALSE(v) ((v) == 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_value to git_checkattr(), and
  * each 'value' member tells what its value is.
  * Unset one is returned as NULL.
  */
-struct git_attr_check {
+struct git_attr_value {
 	struct git_attr *attr;
 	const char *value;
 };
@@ -36,16 +36,16 @@ struct git_attr_check {
  */
 char *git_attr_name(struct git_attr *);
 
-int git_checkattr(const char *path, int, struct git_attr_check *);
+int git_checkattr(const char *path, int, struct git_attr_value *);
 
 /*
  * 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
+ * be set to point at a newly-allocated array of git_attr_value
  * objects describing the attributes and their values.  *check must be
  * free()ed by the caller.
  */
-int git_allattrs(const char *path, int *num, struct git_attr_check **check);
+int git_allattrs(const char *path, int *num, struct git_attr_value **check);
 
 enum git_attr_direction {
 	GIT_ATTR_CHECKIN,
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 29613d4..cd00496 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -22,7 +22,7 @@ static const struct option check_attr_options[] = {
 	OPT_END()
 };
 
-static void output_attr(int cnt, struct git_attr_check *check,
+static void output_attr(int cnt, struct git_attr_value *check,
 	const char *file)
 {
 	int j;
@@ -41,7 +41,7 @@ static void output_attr(int cnt, struct git_attr_check *check,
 	}
 }
 
-static void check_attr(int cnt, struct git_attr_check *check,
+static void check_attr(int cnt, struct git_attr_value *check,
 	const char *file)
 {
 	if (check != NULL) {
@@ -56,7 +56,7 @@ static void check_attr(int cnt, struct git_attr_check *check,
 	}
 }
 
-static void check_attr_stdin_paths(int cnt, struct git_attr_check *check)
+static void check_attr_stdin_paths(int cnt, struct git_attr_value *check)
 {
 	struct strbuf buf, nbuf;
 	int line_termination = null_term_line ? 0 : '\n';
@@ -85,7 +85,7 @@ static NORETURN void error_with_usage(const char *msg)
 
 int cmd_check_attr(int argc, const char **argv, const char *prefix)
 {
-	struct git_attr_check *check;
+	struct git_attr_value *check;
 	int cnt, i, doubledash, filei;
 
 	argc = parse_options(argc, argv, prefix, check_attr_options,
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 84e6daf..a0becea 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -619,7 +619,7 @@ static unsigned name_hash(const char *name)
 	return hash;
 }
 
-static void setup_delta_attr_check(struct git_attr_check *check)
+static void setup_delta_attr_check(struct git_attr_value *check)
 {
 	static struct git_attr *attr_delta;
 
@@ -631,7 +631,7 @@ static void setup_delta_attr_check(struct git_attr_check *check)
 
 static int no_try_delta(const char *path)
 {
-	struct git_attr_check check[1];
+	struct git_attr_value check[1];
 
 	setup_delta_attr_check(check);
 	if (git_checkattr(path, ARRAY_SIZE(check), check))
diff --git a/convert.c b/convert.c
index 85939c2..ab582f8 100644
--- a/convert.c
+++ b/convert.c
@@ -641,7 +641,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,
 	return 1;
 }
 
-static int git_path_check_crlf(const char *path, struct git_attr_check *check)
+static int git_path_check_crlf(const char *path, struct git_attr_value *check)
 {
 	const char *value = check->value;
 
@@ -658,7 +658,7 @@ static int git_path_check_crlf(const char *path, struct git_attr_check *check)
 	return CRLF_GUESS;
 }
 
-static int git_path_check_eol(const char *path, struct git_attr_check *check)
+static int git_path_check_eol(const char *path, struct git_attr_value *check)
 {
 	const char *value = check->value;
 
@@ -672,7 +672,7 @@ static int git_path_check_eol(const char *path, struct git_attr_check *check)
 }
 
 static struct convert_driver *git_path_check_convert(const char *path,
-					     struct git_attr_check *check)
+					     struct git_attr_value *check)
 {
 	const char *value = check->value;
 	struct convert_driver *drv;
@@ -685,7 +685,7 @@ static struct convert_driver *git_path_check_convert(const char *path,
 	return NULL;
 }
 
-static int git_path_check_ident(const char *path, struct git_attr_check *check)
+static int git_path_check_ident(const char *path, struct git_attr_value *check)
 {
 	const char *value = check->value;
 
@@ -718,7 +718,7 @@ static const char *conv_attr_name[] = {
 static void convert_attrs(struct conv_attrs *ca, const char *path)
 {
 	int i;
-	static struct git_attr_check ccheck[NUM_CONV_ATTRS];
+	static struct git_attr_value ccheck[NUM_CONV_ATTRS];
 
 	if (!ccheck[0].attr) {
 		for (i = 0; i < NUM_CONV_ATTRS; i++)
diff --git a/ll-merge.c b/ll-merge.c
index 6ce512e..65f326e 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -324,7 +324,7 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr
 	return &ll_merge_drv[LL_TEXT_MERGE];
 }
 
-static int git_path_check_merge(const char *path, struct git_attr_check check[2])
+static int git_path_check_merge(const char *path, struct git_attr_value check[2])
 {
 	if (!check[0].attr) {
 		check[0].attr = git_attr("merge");
@@ -350,7 +350,7 @@ int ll_merge(mmbuffer_t *result_buf,
 	     mmfile_t *theirs, const char *their_label,
 	     const struct ll_merge_options *opts)
 {
-	static struct git_attr_check check[2];
+	static struct git_attr_value check[2];
 	static const struct ll_merge_options default_opts;
 	const char *ll_driver_name = NULL;
 	int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
@@ -382,7 +382,7 @@ int ll_merge(mmbuffer_t *result_buf,
 
 int ll_merge_marker_size(const char *path)
 {
-	static struct git_attr_check check;
+	static struct git_attr_value check;
 	int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
 
 	if (!check.attr)
diff --git a/userdiff.c b/userdiff.c
index 01d3a8b..cde9537 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -262,7 +262,7 @@ struct userdiff_driver *userdiff_find_by_name(const char *name) {
 struct userdiff_driver *userdiff_find_by_path(const char *path)
 {
 	static struct git_attr *attr;
-	struct git_attr_check check;
+	struct git_attr_value check;
 
 	if (!attr)
 		attr = git_attr("diff");
diff --git a/ws.c b/ws.c
index 9fb9b14..4a76ef8 100644
--- a/ws.c
+++ b/ws.c
@@ -74,7 +74,7 @@ unsigned parse_whitespace_rule(const char *string)
 	return rule;
 }
 
-static void setup_whitespace_attr_check(struct git_attr_check *check)
+static void setup_whitespace_attr_check(struct git_attr_value *check)
 {
 	static struct git_attr *attr_whitespace;
 
@@ -85,7 +85,7 @@ static void setup_whitespace_attr_check(struct git_attr_check *check)
 
 unsigned whitespace_rule(const char *pathname)
 {
-	struct git_attr_check attr_whitespace_rule;
+	struct git_attr_value attr_whitespace_rule;
 
 	setup_whitespace_attr_check(&attr_whitespace_rule);
 	if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) {
-- 
1.7.6.8.gd2879

← back to recent threads