Skip to content

Commit 6c65b5e

Browse files
committed
Merge the attributes fix in from maint-1.6.6 branch
Signed-off-by: Junio C Hamano <[email protected]>
2 parents 8769e93 + f14f980 commit 6c65b5e

File tree

4 files changed

+66
-33
lines changed

4 files changed

+66
-33
lines changed

Documentation/RelNotes/1.7.6.6.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Git v1.7.6.6 Release Notes
2+
==========================
3+
4+
Fixes since v1.7.6.5
5+
--------------------
6+
7+
* The code to look up attributes for paths reused entries from a wrong
8+
directory when two paths in question are in adjacent directories and
9+
the name of the one directory is a prefix of the other.
10+
11+
Also contains minor fixes and documentation updates.

Documentation/config.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,8 @@ rerere.enabled::
17111711
conflict hunks can be resolved automatically, should they be
17121712
encountered again. By default, linkgit:git-rerere[1] is
17131713
enabled if there is an `rr-cache` directory under the
1714-
`$GIT_DIR`.
1714+
`$GIT_DIR`, e.g. if "rerere" was previously used in the
1715+
repository.
17151716

17161717
sendemail.identity::
17171718
A configuration identity. When given, causes values in the

attr.c

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -495,47 +495,48 @@ static int git_attr_system(void)
495495

496496
static void bootstrap_attr_stack(void)
497497
{
498-
if (!attr_stack) {
499-
struct attr_stack *elem;
498+
struct attr_stack *elem;
500499

501-
elem = read_attr_from_array(builtin_attr);
502-
elem->origin = NULL;
503-
elem->prev = attr_stack;
504-
attr_stack = elem;
500+
if (attr_stack)
501+
return;
505502

506-
if (git_attr_system()) {
507-
elem = read_attr_from_file(git_etc_gitattributes(), 1);
508-
if (elem) {
509-
elem->origin = NULL;
510-
elem->prev = attr_stack;
511-
attr_stack = elem;
512-
}
513-
}
503+
elem = read_attr_from_array(builtin_attr);
504+
elem->origin = NULL;
505+
elem->prev = attr_stack;
506+
attr_stack = elem;
514507

515-
if (git_attributes_file) {
516-
elem = read_attr_from_file(git_attributes_file, 1);
517-
if (elem) {
518-
elem->origin = NULL;
519-
elem->prev = attr_stack;
520-
attr_stack = elem;
521-
}
508+
if (git_attr_system()) {
509+
elem = read_attr_from_file(git_etc_gitattributes(), 1);
510+
if (elem) {
511+
elem->origin = NULL;
512+
elem->prev = attr_stack;
513+
attr_stack = elem;
522514
}
515+
}
523516

524-
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
525-
elem = read_attr(GITATTRIBUTES_FILE, 1);
526-
elem->origin = xstrdup("");
517+
if (git_attributes_file) {
518+
elem = read_attr_from_file(git_attributes_file, 1);
519+
if (elem) {
520+
elem->origin = NULL;
527521
elem->prev = attr_stack;
528522
attr_stack = elem;
529-
debug_push(elem);
530523
}
524+
}
531525

532-
elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
533-
if (!elem)
534-
elem = xcalloc(1, sizeof(*elem));
535-
elem->origin = NULL;
526+
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
527+
elem = read_attr(GITATTRIBUTES_FILE, 1);
528+
elem->origin = xstrdup("");
536529
elem->prev = attr_stack;
537530
attr_stack = elem;
531+
debug_push(elem);
538532
}
533+
534+
elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
535+
if (!elem)
536+
elem = xcalloc(1, sizeof(*elem));
537+
elem->origin = NULL;
538+
elem->prev = attr_stack;
539+
attr_stack = elem;
539540
}
540541

541542
static void prepare_attr_stack(const char *path)
@@ -575,14 +576,17 @@ static void prepare_attr_stack(const char *path)
575576

576577
/*
577578
* Pop the ones from directories that are not the prefix of
578-
* the path we are checking.
579+
* the path we are checking. Break out of the loop when we see
580+
* the root one (whose origin is an empty string "") or the builtin
581+
* one (whose origin is NULL) without popping it.
579582
*/
580-
while (attr_stack && attr_stack->origin) {
583+
while (attr_stack->origin) {
581584
int namelen = strlen(attr_stack->origin);
582585

583586
elem = attr_stack;
584587
if (namelen <= dirlen &&
585-
!strncmp(elem->origin, path, namelen))
588+
!strncmp(elem->origin, path, namelen) &&
589+
(!namelen || path[namelen] == '/'))
586590
break;
587591

588592
debug_pop(elem);
@@ -594,8 +598,15 @@ static void prepare_attr_stack(const char *path)
594598
* Read from parent directories and push them down
595599
*/
596600
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
601+
/*
602+
* bootstrap_attr_stack() should have added, and the
603+
* above loop should have stopped before popping, the
604+
* root element whose attr_stack->origin is set to an
605+
* empty string.
606+
*/
597607
struct strbuf pathbuf = STRBUF_INIT;
598608

609+
assert(attr_stack->origin);
599610
while (1) {
600611
len = strlen(attr_stack->origin);
601612
if (dirlen <= len)

t/t0003-attributes.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ test_expect_success 'relative paths' '
172172
173173
'
174174

175+
test_expect_success 'prefixes are not confused with leading directories' '
176+
attr_check a_plus/g unspecified &&
177+
cat >expect <<-\EOF &&
178+
a/g: test: a/g
179+
a_plus/g: test: unspecified
180+
EOF
181+
git check-attr test a/g a_plus/g >actual &&
182+
test_cmp expect actual
183+
'
184+
175185
test_expect_success 'core.attributesfile' '
176186
attr_check global unspecified &&
177187
git config core.attributesfile "$HOME/global-gitattributes" &&

0 commit comments

Comments
 (0)