Skip to content

Commit 7b95849

Browse files
peffgitster
authored andcommitted
attr: do not mark queried macros as unset
Since 60a1272 (attr: remove maybe-real, maybe-macro from git_attr, 2017-01-27), we will always mark an attribute macro (e.g., "binary") that is specifically queried for as "unspecified", even though listing _all_ attributes would display it at set. E.g.: $ echo "* binary" >.gitattributes $ git check-attr -a file file: binary: set file: diff: unset file: merge: unset file: text: unset $ git check-attr binary file file: binary: unspecified The problem stems from an incorrect conversion of the optimization from 06a604e (attr: avoid heavy work when we know the specified attr is not defined, 2014-12-28). There we tried in collect_some_attrs() to avoid even looking at the attr_stack when the user has asked for "foo" and we know that "foo" did not ever appear in any .gitattributes file. It used a flag "maybe_real" in each attribute struct, where "real" meant that the attribute appeared in an actual file (we have to make this distinction because we also create an attribute struct for any names that are being queried). But as explained in that commit message, the meaning of "real" was tangled with some special cases around macros. When 60a1272 later refactored the macro code, it dropped maybe_real entirely. This missed the fact that "maybe_real" could be unset for two reasons: because of a macro, or because it was never found during parsing. This had two results: - the optimization in collect_some_attrs() ceased doing anything meaningful, since it no longer kept track of "was it found during parsing" - worse, it actually kicked in when the caller _did_ ask about a macro by name, causing us to mark it as unspecified It should be possible to salvage this optimization, but let's start with just removing the remnants. It hasn't been doing anything (except creating bugs) since 60a1272, and nobody seems to have noticed the performance regression. It's more important to fix the correctness problem clearly first. I've added two tests here. The second one actually shows off the bug. The test of "check-attr -a" is not strictly necessary, but we currently do not test attribute macros much, and the builtin "binary" not at all. So this increases our general test coverage, as well as making sure we didn't mess up this related case. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 98cdfbb commit 7b95849

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

attr.c

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ static void collect_some_attrs(const struct index_state *istate,
11041104
const char *path,
11051105
struct attr_check *check)
11061106
{
1107-
int i, pathlen, rem, dirlen;
1107+
int pathlen, rem, dirlen;
11081108
const char *cp, *last_slash = NULL;
11091109
int basename_offset;
11101110

@@ -1125,20 +1125,6 @@ static void collect_some_attrs(const struct index_state *istate,
11251125
all_attrs_init(&g_attr_hashmap, check);
11261126
determine_macros(check->all_attrs, check->stack);
11271127

1128-
if (check->nr) {
1129-
rem = 0;
1130-
for (i = 0; i < check->nr; i++) {
1131-
int n = check->items[i].attr->attr_nr;
1132-
struct all_attrs_item *item = &check->all_attrs[n];
1133-
if (item->macro) {
1134-
item->value = ATTR__UNSET;
1135-
rem++;
1136-
}
1137-
}
1138-
if (rem == check->nr)
1139-
return;
1140-
}
1141-
11421128
rem = check->all_attrs_nr;
11431129
fill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);
11441130
}

t/t0003-attributes.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,24 @@ test_expect_success 'bare repository: test info/attributes' '
322322
)
323323
'
324324

325+
test_expect_success 'binary macro expanded by -a' '
326+
echo "file binary" >.gitattributes &&
327+
cat >expect <<-\EOF &&
328+
file: binary: set
329+
file: diff: unset
330+
file: merge: unset
331+
file: text: unset
332+
EOF
333+
git check-attr -a file >actual &&
334+
test_cmp expect actual
335+
'
336+
337+
338+
test_expect_success 'query binary macro directly' '
339+
echo "file binary" >.gitattributes &&
340+
echo file: binary: set >expect &&
341+
git check-attr binary file >actual &&
342+
test_cmp expect actual
343+
'
344+
325345
test_done

0 commit comments

Comments
 (0)