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.
This commit is contained in:
commit
b7d0da858b
38
attr.c
38
attr.c
@ -594,20 +594,25 @@ static int path_matches(const char *pathname, int pathlen,
|
||||
return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
|
||||
for (i = 0; 0 < rem && i < a->num_attr; i++) {
|
||||
for (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {
|
||||
struct git_attr *attr = a->state[i].attr;
|
||||
const char **n = &(check[attr->attr_nr].value);
|
||||
const char *v = a->state[i].setto;
|
||||
|
||||
if (*n == ATTR__UNKNOWN) {
|
||||
debug_set(what, a->u.pattern, attr, v);
|
||||
debug_set(what,
|
||||
a->is_macro ? a->u.attr->name : a->u.pattern,
|
||||
attr, v);
|
||||
*n = v;
|
||||
rem--;
|
||||
rem = macroexpand_one(attr->attr_nr, rem);
|
||||
}
|
||||
}
|
||||
return rem;
|
||||
@ -629,19 +634,27 @@ static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem)
|
||||
return rem;
|
||||
}
|
||||
|
||||
static int macroexpand(struct attr_stack *stk, int rem)
|
||||
static int macroexpand_one(int attr_nr, int rem)
|
||||
{
|
||||
struct attr_stack *stk;
|
||||
struct match_attr *a = NULL;
|
||||
int i;
|
||||
struct git_attr_check *check = check_all_attr;
|
||||
|
||||
for (i = stk->num_matches - 1; 0 < rem && 0 <= i; i--) {
|
||||
struct match_attr *a = stk->attrs[i];
|
||||
if (!a->is_macro)
|
||||
continue;
|
||||
if (check[a->u.attr->attr_nr].value != ATTR__TRUE)
|
||||
continue;
|
||||
if (check_all_attr[attr_nr].value != ATTR__TRUE)
|
||||
return rem;
|
||||
|
||||
for (stk = attr_stack; !a && stk; stk = stk->prev)
|
||||
for (i = stk->num_matches - 1; !a && 0 <= i; i--) {
|
||||
struct match_attr *ma = stk->attrs[i];
|
||||
if (!ma->is_macro)
|
||||
continue;
|
||||
if (ma->u.attr->attr_nr == attr_nr)
|
||||
a = ma;
|
||||
}
|
||||
|
||||
if (a)
|
||||
rem = fill_one("expand", a, rem);
|
||||
}
|
||||
|
||||
return rem;
|
||||
}
|
||||
|
||||
@ -666,9 +679,6 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
|
||||
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
|
||||
rem = fill(path, pathlen, stk, rem);
|
||||
|
||||
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
|
||||
rem = macroexpand(stk, rem);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *value = check_all_attr[check[i].attr->attr_nr].value;
|
||||
if (value == ATTR__UNKNOWN)
|
||||
|
@ -20,8 +20,12 @@ test_expect_success 'setup' '
|
||||
|
||||
mkdir -p a/b/d a/c &&
|
||||
(
|
||||
echo "[attr]notest !test"
|
||||
echo "f test=f"
|
||||
echo "a/i test=a/i"
|
||||
echo "onoff test -test"
|
||||
echo "offon -test test"
|
||||
echo "no notest"
|
||||
) >.gitattributes &&
|
||||
(
|
||||
echo "g test=a/g" &&
|
||||
@ -30,6 +34,7 @@ test_expect_success 'setup' '
|
||||
(
|
||||
echo "h test=a/b/h" &&
|
||||
echo "d/* test=a/b/d/*"
|
||||
echo "d/yes notest"
|
||||
) >a/b/.gitattributes
|
||||
|
||||
'
|
||||
@ -44,6 +49,11 @@ test_expect_success 'attribute test' '
|
||||
attr_check b/g unspecified &&
|
||||
attr_check a/b/h a/b/h &&
|
||||
attr_check a/b/d/g "a/b/d/*"
|
||||
attr_check onoff unset
|
||||
attr_check offon set
|
||||
attr_check no unspecified
|
||||
attr_check a/b/d/no "a/b/d/*"
|
||||
attr_check a/b/d/yes unspecified
|
||||
|
||||
'
|
||||
|
||||
@ -58,6 +68,11 @@ 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
|
||||
|
||||
sed -e "s/:.*//" < expect | git check-attr --stdin test > actual &&
|
||||
|
Loading…
Reference in New Issue
Block a user