Merge the attributes fix in from maint-1.6.6 branch
Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
						commit
						6c65b5ea43
					
				|  | @ -0,0 +1,11 @@ | ||||||
|  | Git v1.7.6.6 Release Notes | ||||||
|  | ========================== | ||||||
|  |  | ||||||
|  | Fixes since v1.7.6.5 | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  |  * The code to look up attributes for paths reused entries from a wrong | ||||||
|  |    directory when two paths in question are in adjacent directories and | ||||||
|  |    the name of the one directory is a prefix of the other. | ||||||
|  |  | ||||||
|  | Also contains minor fixes and documentation updates. | ||||||
|  | @ -1711,7 +1711,8 @@ rerere.enabled:: | ||||||
| 	conflict hunks can be resolved automatically, should they be | 	conflict hunks can be resolved automatically, should they be | ||||||
| 	encountered again.  By default, linkgit:git-rerere[1] is | 	encountered again.  By default, linkgit:git-rerere[1] is | ||||||
| 	enabled if there is an `rr-cache` directory under the | 	enabled if there is an `rr-cache` directory under the | ||||||
| 	`$GIT_DIR`. | 	`$GIT_DIR`, e.g. if "rerere" was previously used in the | ||||||
|  | 	repository. | ||||||
|  |  | ||||||
| sendemail.identity:: | sendemail.identity:: | ||||||
| 	A configuration identity. When given, causes values in the | 	A configuration identity. When given, causes values in the | ||||||
|  |  | ||||||
							
								
								
									
										79
									
								
								attr.c
								
								
								
								
							
							
						
						
									
										79
									
								
								attr.c
								
								
								
								
							|  | @ -495,47 +495,48 @@ static int git_attr_system(void) | ||||||
|  |  | ||||||
| static void bootstrap_attr_stack(void) | static void bootstrap_attr_stack(void) | ||||||
| { | { | ||||||
| 	if (!attr_stack) { | 	struct attr_stack *elem; | ||||||
| 		struct attr_stack *elem; |  | ||||||
|  |  | ||||||
| 		elem = read_attr_from_array(builtin_attr); | 	if (attr_stack) | ||||||
| 		elem->origin = NULL; | 		return; | ||||||
| 		elem->prev = attr_stack; |  | ||||||
| 		attr_stack = elem; |  | ||||||
|  |  | ||||||
| 		if (git_attr_system()) { | 	elem = read_attr_from_array(builtin_attr); | ||||||
| 			elem = read_attr_from_file(git_etc_gitattributes(), 1); | 	elem->origin = NULL; | ||||||
| 			if (elem) { | 	elem->prev = attr_stack; | ||||||
| 				elem->origin = NULL; | 	attr_stack = elem; | ||||||
| 				elem->prev = attr_stack; |  | ||||||
| 				attr_stack = elem; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (git_attributes_file) { | 	if (git_attr_system()) { | ||||||
| 			elem = read_attr_from_file(git_attributes_file, 1); | 		elem = read_attr_from_file(git_etc_gitattributes(), 1); | ||||||
| 			if (elem) { | 		if (elem) { | ||||||
| 				elem->origin = NULL; | 			elem->origin = NULL; | ||||||
| 				elem->prev = attr_stack; |  | ||||||
| 				attr_stack = elem; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { |  | ||||||
| 			elem = read_attr(GITATTRIBUTES_FILE, 1); |  | ||||||
| 			elem->origin = xstrdup(""); |  | ||||||
| 			elem->prev = attr_stack; | 			elem->prev = attr_stack; | ||||||
| 			attr_stack = elem; | 			attr_stack = elem; | ||||||
| 			debug_push(elem); |  | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 		elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1); | 	if (git_attributes_file) { | ||||||
| 		if (!elem) | 		elem = read_attr_from_file(git_attributes_file, 1); | ||||||
| 			elem = xcalloc(1, sizeof(*elem)); | 		if (elem) { | ||||||
| 		elem->origin = NULL; | 			elem->origin = NULL; | ||||||
|  | 			elem->prev = attr_stack; | ||||||
|  | 			attr_stack = elem; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { | ||||||
|  | 		elem = read_attr(GITATTRIBUTES_FILE, 1); | ||||||
|  | 		elem->origin = xstrdup(""); | ||||||
| 		elem->prev = attr_stack; | 		elem->prev = attr_stack; | ||||||
| 		attr_stack = elem; | 		attr_stack = elem; | ||||||
|  | 		debug_push(elem); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1); | ||||||
|  | 	if (!elem) | ||||||
|  | 		elem = xcalloc(1, sizeof(*elem)); | ||||||
|  | 	elem->origin = NULL; | ||||||
|  | 	elem->prev = attr_stack; | ||||||
|  | 	attr_stack = elem; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void prepare_attr_stack(const char *path) | static void prepare_attr_stack(const char *path) | ||||||
|  | @ -575,14 +576,17 @@ static void prepare_attr_stack(const char *path) | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Pop the ones from directories that are not the prefix of | 	 * Pop the ones from directories that are not the prefix of | ||||||
| 	 * the path we are checking. | 	 * the path we are checking. Break out of the loop when we see | ||||||
|  | 	 * the root one (whose origin is an empty string "") or the builtin | ||||||
|  | 	 * one (whose origin is NULL) without popping it. | ||||||
| 	 */ | 	 */ | ||||||
| 	while (attr_stack && attr_stack->origin) { | 	while (attr_stack->origin) { | ||||||
| 		int namelen = strlen(attr_stack->origin); | 		int namelen = strlen(attr_stack->origin); | ||||||
|  |  | ||||||
| 		elem = attr_stack; | 		elem = attr_stack; | ||||||
| 		if (namelen <= dirlen && | 		if (namelen <= dirlen && | ||||||
| 		    !strncmp(elem->origin, path, namelen)) | 		    !strncmp(elem->origin, path, namelen) && | ||||||
|  | 		    (!namelen || path[namelen] == '/')) | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		debug_pop(elem); | 		debug_pop(elem); | ||||||
|  | @ -594,8 +598,15 @@ static void prepare_attr_stack(const char *path) | ||||||
| 	 * Read from parent directories and push them down | 	 * Read from parent directories and push them down | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { | 	if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { | ||||||
|  | 		/* | ||||||
|  | 		 * bootstrap_attr_stack() should have added, and the | ||||||
|  | 		 * above loop should have stopped before popping, the | ||||||
|  | 		 * root element whose attr_stack->origin is set to an | ||||||
|  | 		 * empty string. | ||||||
|  | 		 */ | ||||||
| 		struct strbuf pathbuf = STRBUF_INIT; | 		struct strbuf pathbuf = STRBUF_INIT; | ||||||
|  |  | ||||||
|  | 		assert(attr_stack->origin); | ||||||
| 		while (1) { | 		while (1) { | ||||||
| 			len = strlen(attr_stack->origin); | 			len = strlen(attr_stack->origin); | ||||||
| 			if (dirlen <= len) | 			if (dirlen <= len) | ||||||
|  |  | ||||||
|  | @ -172,6 +172,16 @@ test_expect_success 'relative paths' ' | ||||||
|  |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'prefixes are not confused with leading directories' ' | ||||||
|  | 	attr_check a_plus/g unspecified && | ||||||
|  | 	cat >expect <<-\EOF && | ||||||
|  | 	a/g: test: a/g | ||||||
|  | 	a_plus/g: test: unspecified | ||||||
|  | 	EOF | ||||||
|  | 	git check-attr test a/g a_plus/g >actual && | ||||||
|  | 	test_cmp expect actual | ||||||
|  | ' | ||||||
|  |  | ||||||
| test_expect_success 'core.attributesfile' ' | test_expect_success 'core.attributesfile' ' | ||||||
| 	attr_check global unspecified && | 	attr_check global unspecified && | ||||||
| 	git config core.attributesfile "$HOME/global-gitattributes" && | 	git config core.attributesfile "$HOME/global-gitattributes" && | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano