Make read-cache.c "the_index" free.
This makes all low-level functions defined in read-cache.c to take an explicit index_state structure as their first parameter, to specify which index to work on. These functions traditionally operated on "the_index" and were named foo_cache(); the counterparts this patch introduces are called foo_index(). The traditional foo_cache() functions are made into macros that give "the_index" to their corresponding foo_index() functions. Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									228e94f935
								
							
						
					
					
						commit
						4aab5b46f4
					
				
							
								
								
									
										39
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										39
									
								
								cache.h
								
								
								
								
							|  | @ -154,12 +154,27 @@ struct index_state { | |||
|  | ||||
| extern struct index_state the_index; | ||||
|  | ||||
| #ifndef NO_THE_INDEX_COMPATIBILITY_MACROS | ||||
| #define active_cache (the_index.cache) | ||||
| #define active_nr (the_index.cache_nr) | ||||
| #define active_alloc (the_index.cache_alloc) | ||||
| #define active_cache_changed (the_index.cache_changed) | ||||
| #define active_cache_tree (the_index.cache_tree) | ||||
|  | ||||
| #define read_cache() read_index(&the_index) | ||||
| #define read_cache_from(path) read_index_from(&the_index, (path)) | ||||
| #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd)) | ||||
| #define discard_cache() discard_index(&the_index) | ||||
| #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen)) | ||||
| #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option)) | ||||
| #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos)) | ||||
| #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 refresh_cache(flags) refresh_index(&the_index, flags) | ||||
| #define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really)) | ||||
| #define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really)) | ||||
| #endif | ||||
|  | ||||
| enum object_type { | ||||
| 	OBJ_BAD = -1, | ||||
| 	OBJ_NONE = 0, | ||||
|  | @ -208,23 +223,23 @@ extern void verify_non_filename(const char *prefix, const char *name); | |||
| #define alloc_nr(x) (((x)+16)*3/2) | ||||
|  | ||||
| /* Initialize and use the cache information */ | ||||
| extern int read_cache(void); | ||||
| extern int read_cache_from(const char *path); | ||||
| extern int write_cache(int newfd, struct cache_entry **cache, int entries); | ||||
| extern int discard_cache(void); | ||||
| extern int read_index(struct index_state *); | ||||
| extern int read_index_from(struct index_state *, const char *path); | ||||
| extern int write_index(struct index_state *, int newfd); | ||||
| extern int discard_index(struct index_state *); | ||||
| extern int verify_path(const char *path); | ||||
| extern int cache_name_pos(const char *name, int namelen); | ||||
| extern int index_name_pos(struct index_state *, const char *name, int namelen); | ||||
| #define ADD_CACHE_OK_TO_ADD 1		/* Ok to add */ | ||||
| #define ADD_CACHE_OK_TO_REPLACE 2	/* Ok to replace file/directory */ | ||||
| #define ADD_CACHE_SKIP_DFCHECK 4	/* Ok to skip DF conflict checks */ | ||||
| extern int add_cache_entry(struct cache_entry *ce, int option); | ||||
| extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option); | ||||
| extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); | ||||
| extern int remove_cache_entry_at(int pos); | ||||
| extern int remove_file_from_cache(const char *path); | ||||
| extern int add_file_to_cache(const char *path, int verbose); | ||||
| extern int remove_index_entry_at(struct index_state *, int pos); | ||||
| 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 ce_same_name(struct cache_entry *a, struct cache_entry *b); | ||||
| extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int); | ||||
| extern int ce_modified(struct cache_entry *ce, struct stat *st, int); | ||||
| 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); | ||||
| 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 read_pipe(int fd, char** return_buf, unsigned long* return_size); | ||||
|  | @ -236,7 +251,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); | |||
| #define REFRESH_UNMERGED	0x0002	/* allow unmerged */ | ||||
| #define REFRESH_QUIET		0x0004	/* be quiet about it */ | ||||
| #define REFRESH_IGNORE_MISSING	0x0008	/* ignore non-existent */ | ||||
| extern int refresh_cache(unsigned int flags); | ||||
| extern int refresh_index(struct index_state *, unsigned int flags); | ||||
|  | ||||
| struct lock_file { | ||||
| 	struct lock_file *next; | ||||
|  |  | |||
							
								
								
									
										237
									
								
								read-cache.c
								
								
								
								
							
							
						
						
									
										237
									
								
								read-cache.c
								
								
								
								
							|  | @ -3,6 +3,7 @@ | |||
|  * | ||||
|  * Copyright (C) Linus Torvalds, 2005 | ||||
|  */ | ||||
| #define NO_THE_INDEX_COMPATIBILITY_MACROS | ||||
| #include "cache.h" | ||||
| #include "cache-tree.h" | ||||
| #include "refs.h" | ||||
|  | @ -20,9 +21,6 @@ | |||
| #define CACHE_EXT_TREE 0x54524545	/* "TREE" */ | ||||
|  | ||||
| struct index_state the_index; | ||||
| #define index_file_timestamp (the_index.timestamp) | ||||
| #define cache_mmap (the_index.mmap) | ||||
| #define cache_mmap_size (the_index.mmap_size) | ||||
|  | ||||
| /* | ||||
|  * This only updates the "non-critical" parts of the directory | ||||
|  | @ -192,7 +190,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) | |||
| 	return changed; | ||||
| } | ||||
|  | ||||
| int ce_match_stat(struct cache_entry *ce, struct stat *st, int options) | ||||
| int ie_match_stat(struct index_state *istate, | ||||
| 		  struct cache_entry *ce, struct stat *st, int options) | ||||
| { | ||||
| 	unsigned int changed; | ||||
| 	int ignore_valid = options & 01; | ||||
|  | @ -224,8 +223,8 @@ int ce_match_stat(struct cache_entry *ce, struct stat *st, int options) | |||
| 	 * carefully than others. | ||||
| 	 */ | ||||
| 	if (!changed && | ||||
| 	    index_file_timestamp && | ||||
| 	    index_file_timestamp <= ntohl(ce->ce_mtime.sec)) { | ||||
| 	    istate->timestamp && | ||||
| 	    istate->timestamp <= ntohl(ce->ce_mtime.sec)) { | ||||
| 		if (assume_racy_is_modified) | ||||
| 			changed |= DATA_CHANGED; | ||||
| 		else | ||||
|  | @ -235,10 +234,11 @@ int ce_match_stat(struct cache_entry *ce, struct stat *st, int options) | |||
| 	return changed; | ||||
| } | ||||
|  | ||||
| int ce_modified(struct cache_entry *ce, struct stat *st, int really) | ||||
| int ie_modified(struct index_state *istate, | ||||
| 		struct cache_entry *ce, struct stat *st, int really) | ||||
| { | ||||
| 	int changed, changed_fs; | ||||
| 	changed = ce_match_stat(ce, st, really); | ||||
| 	changed = ie_match_stat(istate, ce, st, really); | ||||
| 	if (!changed) | ||||
| 		return 0; | ||||
| 	/* | ||||
|  | @ -306,15 +306,15 @@ int cache_name_compare(const char *name1, int flags1, const char *name2, int fla | |||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int cache_name_pos(const char *name, int namelen) | ||||
| int index_name_pos(struct index_state *istate, const char *name, int namelen) | ||||
| { | ||||
| 	int first, last; | ||||
|  | ||||
| 	first = 0; | ||||
| 	last = active_nr; | ||||
| 	last = istate->cache_nr; | ||||
| 	while (last > first) { | ||||
| 		int next = (last + first) >> 1; | ||||
| 		struct cache_entry *ce = active_cache[next]; | ||||
| 		struct cache_entry *ce = istate->cache[next]; | ||||
| 		int cmp = cache_name_compare(name, namelen, ce->name, ntohs(ce->ce_flags)); | ||||
| 		if (!cmp) | ||||
| 			return next; | ||||
|  | @ -328,27 +328,29 @@ int cache_name_pos(const char *name, int namelen) | |||
| } | ||||
|  | ||||
| /* Remove entry, return true if there are more entries to go.. */ | ||||
| int remove_cache_entry_at(int pos) | ||||
| int remove_index_entry_at(struct index_state *istate, int pos) | ||||
| { | ||||
| 	active_cache_changed = 1; | ||||
| 	active_nr--; | ||||
| 	if (pos >= active_nr) | ||||
| 	istate->cache_changed = 1; | ||||
| 	istate->cache_nr--; | ||||
| 	if (pos >= istate->cache_nr) | ||||
| 		return 0; | ||||
| 	memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *)); | ||||
| 	memmove(istate->cache + pos, | ||||
| 		istate->cache + pos + 1, | ||||
| 		(istate->cache_nr - pos) * sizeof(struct cache_entry *)); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int remove_file_from_cache(const char *path) | ||||
| int remove_file_from_index(struct index_state *istate, const char *path) | ||||
| { | ||||
| 	int pos = cache_name_pos(path, strlen(path)); | ||||
| 	int pos = index_name_pos(istate, path, strlen(path)); | ||||
| 	if (pos < 0) | ||||
| 		pos = -pos-1; | ||||
| 	while (pos < active_nr && !strcmp(active_cache[pos]->name, path)) | ||||
| 		remove_cache_entry_at(pos); | ||||
| 	while (pos < istate->cache_nr && !strcmp(istate->cache[pos]->name, path)) | ||||
| 		remove_index_entry_at(istate, pos); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int add_file_to_cache(const char *path, int verbose) | ||||
| int add_file_to_index(struct index_state *istate, const char *path, int verbose) | ||||
| { | ||||
| 	int size, namelen; | ||||
| 	struct stat st; | ||||
|  | @ -378,19 +380,19 @@ int add_file_to_cache(const char *path, int verbose) | |||
| 		 * from it, otherwise assume unexecutable regular file. | ||||
| 		 */ | ||||
| 		struct cache_entry *ent; | ||||
| 		int pos = cache_name_pos(path, namelen); | ||||
| 		int pos = index_name_pos(istate, path, namelen); | ||||
|  | ||||
| 		ent = (0 <= pos) ? active_cache[pos] : NULL; | ||||
| 		ent = (0 <= pos) ? istate->cache[pos] : NULL; | ||||
| 		ce->ce_mode = ce_mode_from_stat(ent, st.st_mode); | ||||
| 	} | ||||
|  | ||||
| 	if (index_path(ce->sha1, path, &st, 1)) | ||||
| 		die("unable to index file %s", path); | ||||
| 	if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)) | ||||
| 	if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)) | ||||
| 		die("unable to add %s to index",path); | ||||
| 	if (verbose) | ||||
| 		printf("add '%s'\n", path); | ||||
| 	cache_tree_invalidate_path(active_cache_tree, path); | ||||
| 	cache_tree_invalidate_path(istate->cache_tree, path); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | @ -494,15 +496,16 @@ inside: | |||
|  * Do we have another file that has the beginning components being a | ||||
|  * proper superset of the name we're trying to add? | ||||
|  */ | ||||
| static int has_file_name(const struct cache_entry *ce, int pos, int ok_to_replace) | ||||
| static int has_file_name(struct index_state *istate, | ||||
| 			 const struct cache_entry *ce, int pos, int ok_to_replace) | ||||
| { | ||||
| 	int retval = 0; | ||||
| 	int len = ce_namelen(ce); | ||||
| 	int stage = ce_stage(ce); | ||||
| 	const char *name = ce->name; | ||||
|  | ||||
| 	while (pos < active_nr) { | ||||
| 		struct cache_entry *p = active_cache[pos++]; | ||||
| 	while (pos < istate->cache_nr) { | ||||
| 		struct cache_entry *p = istate->cache[pos++]; | ||||
|  | ||||
| 		if (len >= ce_namelen(p)) | ||||
| 			break; | ||||
|  | @ -517,7 +520,7 @@ static int has_file_name(const struct cache_entry *ce, int pos, int ok_to_replac | |||
| 		retval = -1; | ||||
| 		if (!ok_to_replace) | ||||
| 			break; | ||||
| 		remove_cache_entry_at(--pos); | ||||
| 		remove_index_entry_at(istate, --pos); | ||||
| 	} | ||||
| 	return retval; | ||||
| } | ||||
|  | @ -526,7 +529,8 @@ static int has_file_name(const struct cache_entry *ce, int pos, int ok_to_replac | |||
|  * Do we have another file with a pathname that is a proper | ||||
|  * subset of the name we're trying to add? | ||||
|  */ | ||||
| static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace) | ||||
| static int has_dir_name(struct index_state *istate, | ||||
| 			const struct cache_entry *ce, int pos, int ok_to_replace) | ||||
| { | ||||
| 	int retval = 0; | ||||
| 	int stage = ce_stage(ce); | ||||
|  | @ -544,7 +548,7 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace | |||
| 		} | ||||
| 		len = slash - name; | ||||
|  | ||||
| 		pos = cache_name_pos(name, ntohs(create_ce_flags(len, stage))); | ||||
| 		pos = index_name_pos(istate, name, ntohs(create_ce_flags(len, stage))); | ||||
| 		if (pos >= 0) { | ||||
| 			/* | ||||
| 			 * Found one, but not so fast.  This could | ||||
|  | @ -554,11 +558,11 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace | |||
| 			 * it is Ok to have a directory at the same | ||||
| 			 * path. | ||||
| 			 */ | ||||
| 			if (stage || active_cache[pos]->ce_mode) { | ||||
| 			if (stage || istate->cache[pos]->ce_mode) { | ||||
| 				retval = -1; | ||||
| 				if (!ok_to_replace) | ||||
| 					break; | ||||
| 				remove_cache_entry_at(pos); | ||||
| 				remove_index_entry_at(istate, pos); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|  | @ -570,8 +574,8 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace | |||
| 		 * already matches the sub-directory, then we know | ||||
| 		 * we're ok, and we can exit. | ||||
| 		 */ | ||||
| 		while (pos < active_nr) { | ||||
| 			struct cache_entry *p = active_cache[pos]; | ||||
| 		while (pos < istate->cache_nr) { | ||||
| 			struct cache_entry *p = istate->cache[pos]; | ||||
| 			if ((ce_namelen(p) <= len) || | ||||
| 			    (p->name[len] != '/') || | ||||
| 			    memcmp(p->name, name, len)) | ||||
|  | @ -598,7 +602,9 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace | |||
|  * from the cache so the caller should recompute the insert position. | ||||
|  * When this happens, we return non-zero. | ||||
|  */ | ||||
| static int check_file_directory_conflict(const struct cache_entry *ce, int pos, int ok_to_replace) | ||||
| static int check_file_directory_conflict(struct index_state *istate, | ||||
| 					 const struct cache_entry *ce, | ||||
| 					 int pos, int ok_to_replace) | ||||
| { | ||||
| 	int retval; | ||||
|  | ||||
|  | @ -613,28 +619,28 @@ static int check_file_directory_conflict(const struct cache_entry *ce, int pos, | |||
| 	 * first, since removing those will not change the position | ||||
| 	 * in the array. | ||||
| 	 */ | ||||
| 	retval = has_file_name(ce, pos, ok_to_replace); | ||||
| 	retval = has_file_name(istate, ce, pos, ok_to_replace); | ||||
|  | ||||
| 	/* | ||||
| 	 * Then check if the path might have a clashing sub-directory | ||||
| 	 * before it. | ||||
| 	 */ | ||||
| 	return retval + has_dir_name(ce, pos, ok_to_replace); | ||||
| 	return retval + has_dir_name(istate, ce, pos, ok_to_replace); | ||||
| } | ||||
|  | ||||
| int add_cache_entry(struct cache_entry *ce, int option) | ||||
| int add_index_entry(struct index_state *istate, struct cache_entry *ce, int option) | ||||
| { | ||||
| 	int pos; | ||||
| 	int ok_to_add = option & ADD_CACHE_OK_TO_ADD; | ||||
| 	int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE; | ||||
| 	int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK; | ||||
|  | ||||
| 	pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); | ||||
| 	pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags)); | ||||
|  | ||||
| 	/* existing match? Just replace it. */ | ||||
| 	if (pos >= 0) { | ||||
| 		active_cache_changed = 1; | ||||
| 		active_cache[pos] = ce; | ||||
| 		istate->cache_changed = 1; | ||||
| 		istate->cache[pos] = ce; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	pos = -pos-1; | ||||
|  | @ -643,10 +649,10 @@ int add_cache_entry(struct cache_entry *ce, int option) | |||
| 	 * Inserting a merged entry ("stage 0") into the index | ||||
| 	 * will always replace all non-merged entries.. | ||||
| 	 */ | ||||
| 	if (pos < active_nr && ce_stage(ce) == 0) { | ||||
| 		while (ce_same_name(active_cache[pos], ce)) { | ||||
| 	if (pos < istate->cache_nr && ce_stage(ce) == 0) { | ||||
| 		while (ce_same_name(istate->cache[pos], ce)) { | ||||
| 			ok_to_add = 1; | ||||
| 			if (!remove_cache_entry_at(pos)) | ||||
| 			if (!remove_index_entry_at(istate, pos)) | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -657,25 +663,29 @@ int add_cache_entry(struct cache_entry *ce, int option) | |||
| 		return -1; | ||||
|  | ||||
| 	if (!skip_df_check && | ||||
| 	    check_file_directory_conflict(ce, pos, ok_to_replace)) { | ||||
| 	    check_file_directory_conflict(istate, ce, pos, ok_to_replace)) { | ||||
| 		if (!ok_to_replace) | ||||
| 			return error("'%s' appears as both a file and as a directory", ce->name); | ||||
| 		pos = cache_name_pos(ce->name, ntohs(ce->ce_flags)); | ||||
| 			return error("'%s' appears as both a file and as a directory", | ||||
| 				     ce->name); | ||||
| 		pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags)); | ||||
| 		pos = -pos-1; | ||||
| 	} | ||||
|  | ||||
| 	/* Make sure the array is big enough .. */ | ||||
| 	if (active_nr == active_alloc) { | ||||
| 		active_alloc = alloc_nr(active_alloc); | ||||
| 		active_cache = xrealloc(active_cache, active_alloc * sizeof(struct cache_entry *)); | ||||
| 	if (istate->cache_nr == istate->cache_alloc) { | ||||
| 		istate->cache_alloc = alloc_nr(istate->cache_alloc); | ||||
| 		istate->cache = xrealloc(istate->cache, | ||||
| 					istate->cache_alloc * sizeof(struct cache_entry *)); | ||||
| 	} | ||||
|  | ||||
| 	/* Add it in.. */ | ||||
| 	active_nr++; | ||||
| 	if (active_nr > pos) | ||||
| 		memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce)); | ||||
| 	active_cache[pos] = ce; | ||||
| 	active_cache_changed = 1; | ||||
| 	istate->cache_nr++; | ||||
| 	if (istate->cache_nr > pos) | ||||
| 		memmove(istate->cache + pos + 1, | ||||
| 			istate->cache + pos, | ||||
| 			(istate->cache_nr - pos - 1) * sizeof(ce)); | ||||
| 	istate->cache[pos] = ce; | ||||
| 	istate->cache_changed = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | @ -690,7 +700,8 @@ int add_cache_entry(struct cache_entry *ce, int option) | |||
|  * For example, you'd want to do this after doing a "git-read-tree", | ||||
|  * to link up the stat cache details with the proper files. | ||||
|  */ | ||||
| static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, int *err) | ||||
| static struct cache_entry *refresh_cache_ent(struct index_state *istate, | ||||
| 					     struct cache_entry *ce, int really, int *err) | ||||
| { | ||||
| 	struct stat st; | ||||
| 	struct cache_entry *updated; | ||||
|  | @ -702,7 +713,7 @@ static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, | |||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	changed = ce_match_stat(ce, &st, really); | ||||
| 	changed = ie_match_stat(istate, ce, &st, really); | ||||
| 	if (!changed) { | ||||
| 		if (really && assume_unchanged && | ||||
| 		    !(ce->ce_flags & htons(CE_VALID))) | ||||
|  | @ -711,7 +722,7 @@ static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, | |||
| 			return ce; | ||||
| 	} | ||||
|  | ||||
| 	if (ce_modified(ce, &st, really)) { | ||||
| 	if (ie_modified(istate, ce, &st, really)) { | ||||
| 		if (err) | ||||
| 			*err = EINVAL; | ||||
| 		return NULL; | ||||
|  | @ -734,7 +745,7 @@ static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, | |||
| 	return updated; | ||||
| } | ||||
|  | ||||
| int refresh_cache(unsigned int flags) | ||||
| int refresh_index(struct index_state *istate, unsigned int flags) | ||||
| { | ||||
| 	int i; | ||||
| 	int has_errors = 0; | ||||
|  | @ -743,14 +754,14 @@ int refresh_cache(unsigned int flags) | |||
| 	int quiet = (flags & REFRESH_QUIET) != 0; | ||||
| 	int not_new = (flags & REFRESH_IGNORE_MISSING) != 0; | ||||
|  | ||||
| 	for (i = 0; i < active_nr; i++) { | ||||
| 	for (i = 0; i < istate->cache_nr; i++) { | ||||
| 		struct cache_entry *ce, *new; | ||||
| 		int cache_errno = 0; | ||||
|  | ||||
| 		ce = active_cache[i]; | ||||
| 		ce = istate->cache[i]; | ||||
| 		if (ce_stage(ce)) { | ||||
| 			while ((i < active_nr) && | ||||
| 			       ! strcmp(active_cache[i]->name, ce->name)) | ||||
| 			while ((i < istate->cache_nr) && | ||||
| 			       ! strcmp(istate->cache[i]->name, ce->name)) | ||||
| 				i++; | ||||
| 			i--; | ||||
| 			if (allow_unmerged) | ||||
|  | @ -760,7 +771,7 @@ int refresh_cache(unsigned int flags) | |||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		new = refresh_cache_ent(ce, really, &cache_errno); | ||||
| 		new = refresh_cache_ent(istate, ce, really, &cache_errno); | ||||
| 		if (new == ce) | ||||
| 			continue; | ||||
| 		if (!new) { | ||||
|  | @ -771,7 +782,7 @@ int refresh_cache(unsigned int flags) | |||
| 				 * means the index is not valid anymore. | ||||
| 				 */ | ||||
| 				ce->ce_flags &= ~htons(CE_VALID); | ||||
| 				active_cache_changed = 1; | ||||
| 				istate->cache_changed = 1; | ||||
| 			} | ||||
| 			if (quiet) | ||||
| 				continue; | ||||
|  | @ -779,18 +790,18 @@ int refresh_cache(unsigned int flags) | |||
| 			has_errors = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 		active_cache_changed = 1; | ||||
| 		/* You can NOT just free active_cache[i] here, since it | ||||
| 		istate->cache_changed = 1; | ||||
| 		/* You can NOT just free istate->cache[i] here, since it | ||||
| 		 * might not be necessarily malloc()ed but can also come | ||||
| 		 * from mmap(). */ | ||||
| 		active_cache[i] = new; | ||||
| 		istate->cache[i] = new; | ||||
| 	} | ||||
| 	return has_errors; | ||||
| } | ||||
|  | ||||
| struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really) | ||||
| { | ||||
| 	return refresh_cache_ent(ce, really, NULL); | ||||
| 	return refresh_cache_ent(&the_index, ce, really, NULL); | ||||
| } | ||||
|  | ||||
| static int verify_hdr(struct cache_header *hdr, unsigned long size) | ||||
|  | @ -810,11 +821,12 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) | |||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_index_extension(const char *ext, void *data, unsigned long sz) | ||||
| static int read_index_extension(struct index_state *istate, | ||||
| 				const char *ext, void *data, unsigned long sz) | ||||
| { | ||||
| 	switch (CACHE_EXT(ext)) { | ||||
| 	case CACHE_EXT_TREE: | ||||
| 		active_cache_tree = cache_tree_read(data, sz); | ||||
| 		istate->cache_tree = cache_tree_read(data, sz); | ||||
| 		break; | ||||
| 	default: | ||||
| 		if (*ext < 'A' || 'Z' < *ext) | ||||
|  | @ -826,13 +838,13 @@ static int read_index_extension(const char *ext, void *data, unsigned long sz) | |||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int read_cache(void) | ||||
| int read_index(struct index_state *istate) | ||||
| { | ||||
| 	return read_cache_from(get_index_file()); | ||||
| 	return read_index_from(istate, get_index_file()); | ||||
| } | ||||
|  | ||||
| /* remember to discard_cache() before reading a different cache! */ | ||||
| int read_cache_from(const char *path) | ||||
| int read_index_from(struct index_state *istate, const char *path) | ||||
| { | ||||
| 	int fd, i; | ||||
| 	struct stat st; | ||||
|  | @ -840,11 +852,11 @@ int read_cache_from(const char *path) | |||
| 	struct cache_header *hdr; | ||||
|  | ||||
| 	errno = EBUSY; | ||||
| 	if (cache_mmap) | ||||
| 		return active_nr; | ||||
| 	if (istate->mmap) | ||||
| 		return istate->cache_nr; | ||||
|  | ||||
| 	errno = ENOENT; | ||||
| 	index_file_timestamp = 0; | ||||
| 	istate->timestamp = 0; | ||||
| 	fd = open(path, O_RDONLY); | ||||
| 	if (fd < 0) { | ||||
| 		if (errno == ENOENT) | ||||
|  | @ -853,32 +865,35 @@ int read_cache_from(const char *path) | |||
| 	} | ||||
|  | ||||
| 	if (!fstat(fd, &st)) { | ||||
| 		cache_mmap_size = xsize_t(st.st_size); | ||||
| 		istate->mmap_size = xsize_t(st.st_size); | ||||
| 		errno = EINVAL; | ||||
| 		if (cache_mmap_size >= sizeof(struct cache_header) + 20) | ||||
| 			cache_mmap = xmmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
| 		if (istate->mmap_size >= sizeof(struct cache_header) + 20) | ||||
| 			istate->mmap = xmmap(NULL, istate->mmap_size, | ||||
| 					    PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
| 		else | ||||
| 			die("index file smaller than expected"); | ||||
| 	} else | ||||
| 		die("cannot stat the open index (%s)", strerror(errno)); | ||||
| 	close(fd); | ||||
|  | ||||
| 	hdr = cache_mmap; | ||||
| 	if (verify_hdr(hdr, cache_mmap_size) < 0) | ||||
| 	hdr = istate->mmap; | ||||
| 	if (verify_hdr(hdr, istate->mmap_size) < 0) | ||||
| 		goto unmap; | ||||
|  | ||||
| 	active_nr = ntohl(hdr->hdr_entries); | ||||
| 	active_alloc = alloc_nr(active_nr); | ||||
| 	active_cache = xcalloc(active_alloc, sizeof(struct cache_entry *)); | ||||
| 	istate->cache_nr = ntohl(hdr->hdr_entries); | ||||
| 	istate->cache_alloc = alloc_nr(istate->cache_nr); | ||||
| 	istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *)); | ||||
|  | ||||
| 	offset = sizeof(*hdr); | ||||
| 	for (i = 0; i < active_nr; i++) { | ||||
| 		struct cache_entry *ce = (struct cache_entry *) ((char *) cache_mmap + offset); | ||||
| 	for (i = 0; i < istate->cache_nr; i++) { | ||||
| 		struct cache_entry *ce; | ||||
|  | ||||
| 		ce = (struct cache_entry *)((char *)(istate->mmap) + offset); | ||||
| 		offset = offset + ce_size(ce); | ||||
| 		active_cache[i] = ce; | ||||
| 		istate->cache[i] = ce; | ||||
| 	} | ||||
| 	index_file_timestamp = st.st_mtime; | ||||
| 	while (offset <= cache_mmap_size - 20 - 8) { | ||||
| 	istate->timestamp = st.st_mtime; | ||||
| 	while (offset <= istate->mmap_size - 20 - 8) { | ||||
| 		/* After an array of active_nr index entries, | ||||
| 		 * there can be arbitrary number of extended | ||||
| 		 * sections, each of which is prefixed with | ||||
|  | @ -886,35 +901,37 @@ int read_cache_from(const char *path) | |||
| 		 * in 4-byte network byte order. | ||||
| 		 */ | ||||
| 		unsigned long extsize; | ||||
| 		memcpy(&extsize, (char *) cache_mmap + offset + 4, 4); | ||||
| 		memcpy(&extsize, (char *)(istate->mmap) + offset + 4, 4); | ||||
| 		extsize = ntohl(extsize); | ||||
| 		if (read_index_extension(((const char *) cache_mmap) + offset, | ||||
| 					 (char *) cache_mmap + offset + 8, | ||||
| 		if (read_index_extension(istate, | ||||
| 					 ((const char *) (istate->mmap)) + offset, | ||||
| 					 (char *) (istate->mmap) + offset + 8, | ||||
| 					 extsize) < 0) | ||||
| 			goto unmap; | ||||
| 		offset += 8; | ||||
| 		offset += extsize; | ||||
| 	} | ||||
| 	return active_nr; | ||||
| 	return istate->cache_nr; | ||||
|  | ||||
| unmap: | ||||
| 	munmap(cache_mmap, cache_mmap_size); | ||||
| 	munmap(istate->mmap, istate->mmap_size); | ||||
| 	errno = EINVAL; | ||||
| 	die("index file corrupt"); | ||||
| } | ||||
|  | ||||
| int discard_cache(void) | ||||
| int discard_index(struct index_state *istate) | ||||
| { | ||||
| 	int ret; | ||||
|  | ||||
| 	active_nr = active_cache_changed = 0; | ||||
| 	index_file_timestamp = 0; | ||||
| 	cache_tree_free(&active_cache_tree); | ||||
| 	if (cache_mmap == NULL) | ||||
| 	istate->cache_nr = 0; | ||||
| 	istate->cache_changed = 0; | ||||
| 	istate->timestamp = 0; | ||||
| 	cache_tree_free(&(istate->cache_tree)); | ||||
| 	if (istate->mmap == NULL) | ||||
| 		return 0; | ||||
| 	ret = munmap(cache_mmap, cache_mmap_size); | ||||
| 	cache_mmap = NULL; | ||||
| 	cache_mmap_size = 0; | ||||
| 	ret = munmap(istate->mmap, istate->mmap_size); | ||||
| 	istate->mmap = NULL; | ||||
| 	istate->mmap_size = 0; | ||||
|  | ||||
| 	/* no need to throw away allocated active_cache */ | ||||
| 	return ret; | ||||
|  | @ -1033,11 +1050,13 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) | |||
| 	} | ||||
| } | ||||
|  | ||||
| int write_cache(int newfd, struct cache_entry **cache, int entries) | ||||
| int write_index(struct index_state *istate, int newfd) | ||||
| { | ||||
| 	SHA_CTX c; | ||||
| 	struct cache_header hdr; | ||||
| 	int i, removed; | ||||
| 	struct cache_entry **cache = istate->cache; | ||||
| 	int entries = istate->cache_nr; | ||||
|  | ||||
| 	for (i = removed = 0; i < entries; i++) | ||||
| 		if (!cache[i]->ce_mode) | ||||
|  | @ -1055,17 +1074,17 @@ int write_cache(int newfd, struct cache_entry **cache, int entries) | |||
| 		struct cache_entry *ce = cache[i]; | ||||
| 		if (!ce->ce_mode) | ||||
| 			continue; | ||||
| 		if (index_file_timestamp && | ||||
| 		    index_file_timestamp <= ntohl(ce->ce_mtime.sec)) | ||||
| 		if (istate->timestamp && | ||||
| 		    istate->timestamp <= ntohl(ce->ce_mtime.sec)) | ||||
| 			ce_smudge_racily_clean_entry(ce); | ||||
| 		if (ce_write(&c, newfd, ce, ce_size(ce)) < 0) | ||||
| 			return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* Write extension data here */ | ||||
| 	if (active_cache_tree) { | ||||
| 	if (istate->cache_tree) { | ||||
| 		unsigned long sz; | ||||
| 		void *data = cache_tree_write(active_cache_tree, &sz); | ||||
| 		void *data = cache_tree_write(istate->cache_tree, &sz); | ||||
| 		if (data && | ||||
| 		    !write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sz) && | ||||
| 		    !ce_write(&c, newfd, data, sz)) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano