Skip to content

Commit b7d0da8

Browse files
committed
Merge branch 'hg/maint-attr-fix'
* hg/maint-attr-fix: attr: Expand macros immediately when encountered. attr: Allow multiple changes to an attribute on the same line. attr: Fixed debug output for macro expansion.
2 parents 67e5c87 + ec775c4 commit b7d0da8

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

attr.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -594,20 +594,25 @@ static int path_matches(const char *pathname, int pathlen,
594594
return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
595595
}
596596

597+
static int macroexpand_one(int attr_nr, int rem);
598+
597599
static int fill_one(const char *what, struct match_attr *a, int rem)
598600
{
599601
struct git_attr_check *check = check_all_attr;
600602
int i;
601603

602-
for (i = 0; 0 < rem && i < a->num_attr; i++) {
604+
for (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {
603605
struct git_attr *attr = a->state[i].attr;
604606
const char **n = &(check[attr->attr_nr].value);
605607
const char *v = a->state[i].setto;
606608

607609
if (*n == ATTR__UNKNOWN) {
608-
debug_set(what, a->u.pattern, attr, v);
610+
debug_set(what,
611+
a->is_macro ? a->u.attr->name : a->u.pattern,
612+
attr, v);
609613
*n = v;
610614
rem--;
615+
rem = macroexpand_one(attr->attr_nr, rem);
611616
}
612617
}
613618
return rem;
@@ -629,19 +634,27 @@ static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem)
629634
return rem;
630635
}
631636

632-
static int macroexpand(struct attr_stack *stk, int rem)
637+
static int macroexpand_one(int attr_nr, int rem)
633638
{
639+
struct attr_stack *stk;
640+
struct match_attr *a = NULL;
634641
int i;
635-
struct git_attr_check *check = check_all_attr;
636642

637-
for (i = stk->num_matches - 1; 0 < rem && 0 <= i; i--) {
638-
struct match_attr *a = stk->attrs[i];
639-
if (!a->is_macro)
640-
continue;
641-
if (check[a->u.attr->attr_nr].value != ATTR__TRUE)
642-
continue;
643+
if (check_all_attr[attr_nr].value != ATTR__TRUE)
644+
return rem;
645+
646+
for (stk = attr_stack; !a && stk; stk = stk->prev)
647+
for (i = stk->num_matches - 1; !a && 0 <= i; i--) {
648+
struct match_attr *ma = stk->attrs[i];
649+
if (!ma->is_macro)
650+
continue;
651+
if (ma->u.attr->attr_nr == attr_nr)
652+
a = ma;
653+
}
654+
655+
if (a)
643656
rem = fill_one("expand", a, rem);
644-
}
657+
645658
return rem;
646659
}
647660

@@ -666,9 +679,6 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
666679
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
667680
rem = fill(path, pathlen, stk, rem);
668681

669-
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
670-
rem = macroexpand(stk, rem);
671-
672682
for (i = 0; i < num; i++) {
673683
const char *value = check_all_attr[check[i].attr->attr_nr].value;
674684
if (value == ATTR__UNKNOWN)

t/t0003-attributes.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ test_expect_success 'setup' '
2020
2121
mkdir -p a/b/d a/c &&
2222
(
23+
echo "[attr]notest !test"
2324
echo "f test=f"
2425
echo "a/i test=a/i"
26+
echo "onoff test -test"
27+
echo "offon -test test"
28+
echo "no notest"
2529
) >.gitattributes &&
2630
(
2731
echo "g test=a/g" &&
@@ -30,6 +34,7 @@ test_expect_success 'setup' '
3034
(
3135
echo "h test=a/b/h" &&
3236
echo "d/* test=a/b/d/*"
37+
echo "d/yes notest"
3338
) >a/b/.gitattributes
3439
3540
'
@@ -44,6 +49,11 @@ test_expect_success 'attribute test' '
4449
attr_check b/g unspecified &&
4550
attr_check a/b/h a/b/h &&
4651
attr_check a/b/d/g "a/b/d/*"
52+
attr_check onoff unset
53+
attr_check offon set
54+
attr_check no unspecified
55+
attr_check a/b/d/no "a/b/d/*"
56+
attr_check a/b/d/yes unspecified
4757
4858
'
4959

@@ -58,6 +68,11 @@ a/b/g: test: a/b/g
5868
b/g: test: unspecified
5969
a/b/h: test: a/b/h
6070
a/b/d/g: test: a/b/d/*
71+
onoff: test: unset
72+
offon: test: set
73+
no: test: unspecified
74+
a/b/d/no: test: a/b/d/*
75+
a/b/d/yes: test: unspecified
6176
EOF
6277
6378
sed -e "s/:.*//" < expect | git check-attr --stdin test > actual &&

0 commit comments

Comments
 (0)