Merge branch 'jc/maint-add-sync-stat'
* jc/maint-add-sync-stat: t2200: test more cases of "add -u" git-add: make the entry stat-clean after re-adding the same contents ce_match_stat, run_diff_files: use symbolic constants for readability Conflicts: builtin-add.cmaint
						commit
						c78a24986d
					
				|  | @ -120,7 +120,7 @@ void add_files_to_cache(int verbose, const char *prefix, const char **files) | ||||||
| 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; | 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; | ||||||
| 	rev.diffopt.format_callback = update_callback; | 	rev.diffopt.format_callback = update_callback; | ||||||
| 	rev.diffopt.format_callback_data = &verbose; | 	rev.diffopt.format_callback_data = &verbose; | ||||||
| 	run_diff_files(&rev, 0); | 	run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void refresh(int verbose, const char **pathspec) | static void refresh(int verbose, const char **pathspec) | ||||||
|  |  | ||||||
|  | @ -1993,7 +1993,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st) | ||||||
| 			return -1; | 			return -1; | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	return ce_match_stat(ce, st, 1); | 	return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int check_patch(struct patch *patch, struct patch *prev_patch) | static int check_patch(struct patch *patch, struct patch *prev_patch) | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										14
									
								
								cache.h
								
								
								
								
							|  | @ -175,8 +175,8 @@ extern struct index_state the_index; | ||||||
| #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path)) | #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path)) | ||||||
| #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose)) | #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose)) | ||||||
| #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL) | #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL) | ||||||
| #define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really)) | #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) | ||||||
| #define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really)) | #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| enum object_type { | enum object_type { | ||||||
|  | @ -268,8 +268,14 @@ extern int remove_file_from_index(struct index_state *, const char *path); | ||||||
| extern int add_file_to_index(struct index_state *, const char *path, int verbose); | extern int add_file_to_index(struct index_state *, const char *path, int verbose); | ||||||
| extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); | extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); | ||||||
| extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); | extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); | ||||||
| extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int); |  | ||||||
| extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int); | /* do stat comparison even if CE_VALID is true */ | ||||||
|  | #define CE_MATCH_IGNORE_VALID		01 | ||||||
|  | /* do not check the contents but report dirty on racily-clean entries */ | ||||||
|  | #define CE_MATCH_RACY_IS_DIRTY	02 | ||||||
|  | extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int); | ||||||
|  | extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int); | ||||||
|  |  | ||||||
| extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); | extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); | ||||||
| extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); | extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); | ||||||
| extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object); | extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object); | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ int main(int ac, char **av) | ||||||
|  |  | ||||||
| 		if (ce_match_stat(ce, &st, 0)) | 		if (ce_match_stat(ce, &st, 0)) | ||||||
| 			dirty++; | 			dirty++; | ||||||
| 		else if (ce_match_stat(ce, &st, 2)) | 		else if (ce_match_stat(ce, &st, CE_MATCH_RACY_IS_DIRTY)) | ||||||
| 			racy++; | 			racy++; | ||||||
| 		else | 		else | ||||||
| 			clean++; | 			clean++; | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								diff-lib.c
								
								
								
								
							
							
						
						
									
										20
									
								
								diff-lib.c
								
								
								
								
							|  | @ -173,9 +173,10 @@ static int is_in_index(const char *path) | ||||||
| } | } | ||||||
|  |  | ||||||
| static int handle_diff_files_args(struct rev_info *revs, | static int handle_diff_files_args(struct rev_info *revs, | ||||||
| 		int argc, const char **argv, int *silent) | 				  int argc, const char **argv, | ||||||
|  | 				  unsigned int *options) | ||||||
| { | { | ||||||
| 	*silent = 0; | 	*options = 0; | ||||||
|  |  | ||||||
| 	/* revs->max_count == -2 means --no-index */ | 	/* revs->max_count == -2 means --no-index */ | ||||||
| 	while (1 < argc && argv[1][0] == '-') { | 	while (1 < argc && argv[1][0] == '-') { | ||||||
|  | @ -192,7 +193,7 @@ static int handle_diff_files_args(struct rev_info *revs, | ||||||
| 			revs->diffopt.no_index = 1; | 			revs->diffopt.no_index = 1; | ||||||
| 		} | 		} | ||||||
| 		else if (!strcmp(argv[1], "-q")) | 		else if (!strcmp(argv[1], "-q")) | ||||||
| 			*silent = 1; | 			*options |= DIFF_SILENT_ON_REMOVED; | ||||||
| 		else | 		else | ||||||
| 			return error("invalid option: %s", argv[1]); | 			return error("invalid option: %s", argv[1]); | ||||||
| 		argv++; argc--; | 		argv++; argc--; | ||||||
|  | @ -305,9 +306,9 @@ int setup_diff_no_index(struct rev_info *revs, | ||||||
|  |  | ||||||
| int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) | int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) | ||||||
| { | { | ||||||
| 	int silent_on_removed; | 	unsigned int options; | ||||||
|  |  | ||||||
| 	if (handle_diff_files_args(revs, argc, argv, &silent_on_removed)) | 	if (handle_diff_files_args(revs, argc, argv, &options)) | ||||||
| 		return -1; | 		return -1; | ||||||
|  |  | ||||||
| 	if (revs->diffopt.no_index) { | 	if (revs->diffopt.no_index) { | ||||||
|  | @ -329,13 +330,16 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) | ||||||
| 		perror("read_cache"); | 		perror("read_cache"); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	return run_diff_files(revs, silent_on_removed); | 	return run_diff_files(revs, options); | ||||||
| } | } | ||||||
|  |  | ||||||
| int run_diff_files(struct rev_info *revs, int silent_on_removed) | int run_diff_files(struct rev_info *revs, unsigned int option) | ||||||
| { | { | ||||||
| 	int entries, i; | 	int entries, i; | ||||||
| 	int diff_unmerged_stage = revs->max_count; | 	int diff_unmerged_stage = revs->max_count; | ||||||
|  | 	int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; | ||||||
|  | 	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) | ||||||
|  | 			      ? CE_MATCH_RACY_IS_DIRTY : 0); | ||||||
|  |  | ||||||
| 	if (diff_unmerged_stage < 0) | 	if (diff_unmerged_stage < 0) | ||||||
| 		diff_unmerged_stage = 2; | 		diff_unmerged_stage = 2; | ||||||
|  | @ -441,7 +445,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) | ||||||
| 				       ce->sha1, ce->name, NULL); | 				       ce->sha1, ce->name, NULL); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		changed = ce_match_stat(ce, &st, 0); | 		changed = ce_match_stat(ce, &st, ce_option); | ||||||
| 		if (!changed && !revs->diffopt.find_copies_harder) | 		if (!changed && !revs->diffopt.find_copies_harder) | ||||||
| 			continue; | 			continue; | ||||||
| 		oldmode = ntohl(ce->ce_mode); | 		oldmode = ntohl(ce->ce_mode); | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								diff.h
								
								
								
								
							
							
						
						
									
										6
									
								
								diff.h
								
								
								
								
							|  | @ -224,7 +224,11 @@ extern void diff_flush(struct diff_options*); | ||||||
|  |  | ||||||
| extern const char *diff_unique_abbrev(const unsigned char *, int); | extern const char *diff_unique_abbrev(const unsigned char *, int); | ||||||
|  |  | ||||||
| extern int run_diff_files(struct rev_info *revs, int silent_on_removed); | /* do not report anything on removed paths */ | ||||||
|  | #define DIFF_SILENT_ON_REMOVED 01 | ||||||
|  | /* report racily-clean paths as modified */ | ||||||
|  | #define DIFF_RACY_IS_MODIFIED 02 | ||||||
|  | extern int run_diff_files(struct rev_info *revs, unsigned int option); | ||||||
| extern int setup_diff_no_index(struct rev_info *revs, | extern int setup_diff_no_index(struct rev_info *revs, | ||||||
| 		int argc, const char ** argv, int nongit, const char *prefix); | 		int argc, const char ** argv, int nongit, const char *prefix); | ||||||
| extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv); | extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv); | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								entry.c
								
								
								
								
							
							
						
						
									
										2
									
								
								entry.c
								
								
								
								
							|  | @ -203,7 +203,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t | ||||||
| 	strcpy(path + len, ce->name); | 	strcpy(path + len, ce->name); | ||||||
|  |  | ||||||
| 	if (!lstat(path, &st)) { | 	if (!lstat(path, &st)) { | ||||||
| 		unsigned changed = ce_match_stat(ce, &st, 1); | 		unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); | ||||||
| 		if (!changed) | 		if (!changed) | ||||||
| 			return 0; | 			return 0; | ||||||
| 		if (!state->force) { | 		if (!state->force) { | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								read-cache.c
								
								
								
								
							
							
						
						
									
										48
									
								
								read-cache.c
								
								
								
								
							|  | @ -194,11 +194,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) | ||||||
| } | } | ||||||
|  |  | ||||||
| int ie_match_stat(struct index_state *istate, | int ie_match_stat(struct index_state *istate, | ||||||
| 		  struct cache_entry *ce, struct stat *st, int options) | 		  struct cache_entry *ce, struct stat *st, | ||||||
|  | 		  unsigned int options) | ||||||
| { | { | ||||||
| 	unsigned int changed; | 	unsigned int changed; | ||||||
| 	int ignore_valid = options & 01; | 	int ignore_valid = options & CE_MATCH_IGNORE_VALID; | ||||||
| 	int assume_racy_is_modified = options & 02; | 	int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * If it's marked as always valid in the index, it's | 	 * If it's marked as always valid in the index, it's | ||||||
|  | @ -238,10 +239,11 @@ int ie_match_stat(struct index_state *istate, | ||||||
| } | } | ||||||
|  |  | ||||||
| int ie_modified(struct index_state *istate, | int ie_modified(struct index_state *istate, | ||||||
| 		struct cache_entry *ce, struct stat *st, int really) | 		struct cache_entry *ce, struct stat *st, unsigned int options) | ||||||
| { | { | ||||||
| 	int changed, changed_fs; | 	int changed, changed_fs; | ||||||
| 	changed = ie_match_stat(istate, ce, st, really); |  | ||||||
|  | 	changed = ie_match_stat(istate, ce, st, options); | ||||||
| 	if (!changed) | 	if (!changed) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	/* | 	/* | ||||||
|  | @ -387,6 +389,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) | ||||||
| 	int size, namelen, pos; | 	int size, namelen, pos; | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	struct cache_entry *ce; | 	struct cache_entry *ce; | ||||||
|  | 	unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY; | ||||||
|  |  | ||||||
| 	if (lstat(path, &st)) | 	if (lstat(path, &st)) | ||||||
| 		die("%s: unable to stat (%s)", path, strerror(errno)); | 		die("%s: unable to stat (%s)", path, strerror(errno)); | ||||||
|  | @ -421,7 +424,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) | ||||||
| 	pos = index_name_pos(istate, ce->name, namelen); | 	pos = index_name_pos(istate, ce->name, namelen); | ||||||
| 	if (0 <= pos && | 	if (0 <= pos && | ||||||
| 	    !ce_stage(istate->cache[pos]) && | 	    !ce_stage(istate->cache[pos]) && | ||||||
| 	    !ie_modified(istate, istate->cache[pos], &st, 1)) { | 	    !ie_match_stat(istate, istate->cache[pos], &st, ce_option)) { | ||||||
| 		/* Nothing changed, really */ | 		/* Nothing changed, really */ | ||||||
| 		free(ce); | 		free(ce); | ||||||
| 		return 0; | 		return 0; | ||||||
|  | @ -783,11 +786,13 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti | ||||||
|  * to link up the stat cache details with the proper files. |  * to link up the stat cache details with the proper files. | ||||||
|  */ |  */ | ||||||
| static struct cache_entry *refresh_cache_ent(struct index_state *istate, | static struct cache_entry *refresh_cache_ent(struct index_state *istate, | ||||||
| 					     struct cache_entry *ce, int really, int *err) | 					     struct cache_entry *ce, | ||||||
|  | 					     unsigned int options, int *err) | ||||||
| { | { | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	struct cache_entry *updated; | 	struct cache_entry *updated; | ||||||
| 	int changed, size; | 	int changed, size; | ||||||
|  | 	int ignore_valid = options & CE_MATCH_IGNORE_VALID; | ||||||
|  |  | ||||||
| 	if (lstat(ce->name, &st) < 0) { | 	if (lstat(ce->name, &st) < 0) { | ||||||
| 		if (err) | 		if (err) | ||||||
|  | @ -795,16 +800,23 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	changed = ie_match_stat(istate, ce, &st, really); | 	changed = ie_match_stat(istate, ce, &st, options); | ||||||
| 	if (!changed) { | 	if (!changed) { | ||||||
| 		if (really && assume_unchanged && | 		/* | ||||||
|  | 		 * The path is unchanged.  If we were told to ignore | ||||||
|  | 		 * valid bit, then we did the actual stat check and | ||||||
|  | 		 * found that the entry is unmodified.  If the entry | ||||||
|  | 		 * is not marked VALID, this is the place to mark it | ||||||
|  | 		 * valid again, under "assume unchanged" mode. | ||||||
|  | 		 */ | ||||||
|  | 		if (ignore_valid && assume_unchanged && | ||||||
| 		    !(ce->ce_flags & htons(CE_VALID))) | 		    !(ce->ce_flags & htons(CE_VALID))) | ||||||
| 			; /* mark this one VALID again */ | 			; /* mark this one VALID again */ | ||||||
| 		else | 		else | ||||||
| 			return ce; | 			return ce; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (ie_modified(istate, ce, &st, really)) { | 	if (ie_modified(istate, ce, &st, options)) { | ||||||
| 		if (err) | 		if (err) | ||||||
| 			*err = EINVAL; | 			*err = EINVAL; | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | @ -815,13 +827,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, | ||||||
| 	memcpy(updated, ce, size); | 	memcpy(updated, ce, size); | ||||||
| 	fill_stat_cache_info(updated, &st); | 	fill_stat_cache_info(updated, &st); | ||||||
|  |  | ||||||
| 	/* In this case, if really is not set, we should leave | 	/* | ||||||
| 	 * CE_VALID bit alone.  Otherwise, paths marked with | 	 * If ignore_valid is not set, we should leave CE_VALID bit | ||||||
| 	 * --no-assume-unchanged (i.e. things to be edited) will | 	 * alone.  Otherwise, paths marked with --no-assume-unchanged | ||||||
| 	 * reacquire CE_VALID bit automatically, which is not | 	 * (i.e. things to be edited) will reacquire CE_VALID bit | ||||||
| 	 * really what we want. | 	 * automatically, which is not really what we want. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID))) | 	if (!ignore_valid && assume_unchanged && | ||||||
|  | 	    !(ce->ce_flags & htons(CE_VALID))) | ||||||
| 		updated->ce_flags &= ~htons(CE_VALID); | 		updated->ce_flags &= ~htons(CE_VALID); | ||||||
|  |  | ||||||
| 	return updated; | 	return updated; | ||||||
|  | @ -835,6 +848,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p | ||||||
| 	int allow_unmerged = (flags & REFRESH_UNMERGED) != 0; | 	int allow_unmerged = (flags & REFRESH_UNMERGED) != 0; | ||||||
| 	int quiet = (flags & REFRESH_QUIET) != 0; | 	int quiet = (flags & REFRESH_QUIET) != 0; | ||||||
| 	int not_new = (flags & REFRESH_IGNORE_MISSING) != 0; | 	int not_new = (flags & REFRESH_IGNORE_MISSING) != 0; | ||||||
|  | 	unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0; | ||||||
|  |  | ||||||
| 	for (i = 0; i < istate->cache_nr; i++) { | 	for (i = 0; i < istate->cache_nr; i++) { | ||||||
| 		struct cache_entry *ce, *new; | 		struct cache_entry *ce, *new; | ||||||
|  | @ -856,7 +870,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p | ||||||
| 		if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen)) | 		if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen)) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		new = refresh_cache_ent(istate, ce, really, &cache_errno); | 		new = refresh_cache_ent(istate, ce, options, &cache_errno); | ||||||
| 		if (new == ce) | 		if (new == ce) | ||||||
| 			continue; | 			continue; | ||||||
| 		if (!new) { | 		if (!new) { | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  |  | ||||||
| test_description='git add -u with path limiting | test_description='git add -u | ||||||
|  |  | ||||||
| This test creates a working tree state with three files: | This test creates a working tree state with three files: | ||||||
|  |  | ||||||
|  | @ -9,7 +9,10 @@ This test creates a working tree state with three files: | ||||||
|   dir/other (untracked) |   dir/other (untracked) | ||||||
|  |  | ||||||
| and issues a git add -u with path limiting on "dir" to add | and issues a git add -u with path limiting on "dir" to add | ||||||
| only the updates to dir/sub.' | only the updates to dir/sub. | ||||||
|  |  | ||||||
|  | Also tested are "git add -u" without limiting, and "git add -u" | ||||||
|  | without contents changes.' | ||||||
|  |  | ||||||
| . ./test-lib.sh | . ./test-lib.sh | ||||||
|  |  | ||||||
|  | @ -85,4 +88,27 @@ test_expect_success 'replace a file with a symlink' ' | ||||||
|  |  | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'add everything changed' ' | ||||||
|  |  | ||||||
|  | 	git add -u && | ||||||
|  | 	test -z "$(git diff-files)" | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'touch and then add -u' ' | ||||||
|  |  | ||||||
|  | 	touch check && | ||||||
|  | 	git add -u && | ||||||
|  | 	test -z "$(git diff-files)" | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'touch and then add explicitly' ' | ||||||
|  |  | ||||||
|  | 	touch check && | ||||||
|  | 	git add check && | ||||||
|  | 	test -z "$(git diff-files)" | ||||||
|  |  | ||||||
|  | ' | ||||||
|  |  | ||||||
| test_done | test_done | ||||||
|  |  | ||||||
|  | @ -404,7 +404,7 @@ static void verify_uptodate(struct cache_entry *ce, | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	if (!lstat(ce->name, &st)) { | 	if (!lstat(ce->name, &st)) { | ||||||
| 		unsigned changed = ce_match_stat(ce, &st, 1); | 		unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); | ||||||
| 		if (!changed) | 		if (!changed) | ||||||
| 			return; | 			return; | ||||||
| 		/* | 		/* | ||||||
|  | @ -925,7 +925,7 @@ int oneway_merge(struct cache_entry **src, | ||||||
| 		if (o->reset) { | 		if (o->reset) { | ||||||
| 			struct stat st; | 			struct stat st; | ||||||
| 			if (lstat(old->name, &st) || | 			if (lstat(old->name, &st) || | ||||||
| 			    ce_match_stat(old, &st, 1)) | 			    ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID)) | ||||||
| 				old->ce_flags |= htons(CE_UPDATE); | 				old->ce_flags |= htons(CE_UPDATE); | ||||||
| 		} | 		} | ||||||
| 		return keep_entry(old, o); | 		return keep_entry(old, o); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano