read-cache: mark updated entries for split index
The large part of this patch just follows CE_ENTRY_CHANGED marks. replace_index_entry() is updated to update split_index->base->cache[] as well so base->cache[] does not reference to a freed entry. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									045113a53e
								
							
						
					
					
						commit
						078a58e825
					
				|  | @ -55,6 +55,7 @@ static int mark_ce_flags(const char *path, int flag, int mark) | |||
| 			active_cache[pos]->ce_flags |= flag; | ||||
| 		else | ||||
| 			active_cache[pos]->ce_flags &= ~flag; | ||||
| 		active_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 		cache_tree_invalidate_path(&the_index, path); | ||||
| 		active_cache_changed |= CE_ENTRY_CHANGED; | ||||
| 		return 0; | ||||
|  | @ -268,6 +269,7 @@ static void chmod_path(int flip, const char *path) | |||
| 		goto fail; | ||||
| 	} | ||||
| 	cache_tree_invalidate_path(&the_index, path); | ||||
| 	ce->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 	active_cache_changed |= CE_ENTRY_CHANGED; | ||||
| 	report("chmod %cx '%s'", flip, path); | ||||
| 	return; | ||||
|  |  | |||
							
								
								
									
										2
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										2
									
								
								cache.h
								
								
								
								
							|  | @ -169,6 +169,8 @@ struct cache_entry { | |||
| /* used to temporarily mark paths matched by pathspecs */ | ||||
| #define CE_MATCHED           (1 << 26) | ||||
|  | ||||
| #define CE_UPDATE_IN_BASE    (1 << 27) | ||||
|  | ||||
| /* | ||||
|  * Extended on-disk flags | ||||
|  */ | ||||
|  |  | |||
							
								
								
									
										1
									
								
								entry.c
								
								
								
								
							
							
						
						
									
										1
									
								
								entry.c
								
								
								
								
							|  | @ -214,6 +214,7 @@ finish: | |||
| 		if (!fstat_done) | ||||
| 			lstat(ce->name, &st); | ||||
| 		fill_stat_cache_info(ce, &st); | ||||
| 		ce->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 		state->istate->cache_changed |= CE_ENTRY_CHANGED; | ||||
| 	} | ||||
| 	return 0; | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, | |||
|  | ||||
| /* changes that can be kept in $GIT_DIR/index (basically all extensions) */ | ||||
| #define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \ | ||||
| 		 CE_ENTRY_ADDED | CE_ENTRY_REMOVED) | ||||
| 		 CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED) | ||||
|  | ||||
| struct index_state the_index; | ||||
| static const char *alternate_index_output; | ||||
|  | @ -54,9 +54,11 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache | |||
| { | ||||
| 	struct cache_entry *old = istate->cache[nr]; | ||||
|  | ||||
| 	replace_index_entry_in_base(istate, old, ce); | ||||
| 	remove_name_hash(istate, old); | ||||
| 	free(old); | ||||
| 	set_index_entry(istate, nr, ce); | ||||
| 	ce->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 	istate->cache_changed |= CE_ENTRY_CHANGED; | ||||
| } | ||||
|  | ||||
|  | @ -1192,6 +1194,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, | |||
| 				 * means the index is not valid anymore. | ||||
| 				 */ | ||||
| 				ce->ce_flags &= ~CE_VALID; | ||||
| 				ce->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 				istate->cache_changed |= CE_ENTRY_CHANGED; | ||||
| 			} | ||||
| 			if (quiet) | ||||
|  |  | |||
|  | @ -100,3 +100,18 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce | |||
| 	else | ||||
| 		free(ce); | ||||
| } | ||||
|  | ||||
| void replace_index_entry_in_base(struct index_state *istate, | ||||
| 				 struct cache_entry *old, | ||||
| 				 struct cache_entry *new) | ||||
| { | ||||
| 	if (old->index && | ||||
| 	    istate->split_index && | ||||
| 	    istate->split_index->base && | ||||
| 	    old->index <= istate->split_index->base->cache_nr) { | ||||
| 		new->index = old->index; | ||||
| 		if (old != istate->split_index->base->cache[new->index - 1]) | ||||
| 			free(istate->split_index->base->cache[new->index - 1]); | ||||
| 		istate->split_index->base->cache[new->index - 1] = new; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -13,6 +13,9 @@ struct split_index { | |||
|  | ||||
| struct split_index *init_split_index(struct index_state *istate); | ||||
| void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce); | ||||
| void replace_index_entry_in_base(struct index_state *istate, | ||||
| 				 struct cache_entry *old, | ||||
| 				 struct cache_entry *new); | ||||
| int read_link_extension(struct index_state *istate, | ||||
| 			const void *data, unsigned long sz); | ||||
| int write_link_extension(struct strbuf *sb, | ||||
|  |  | |||
|  | @ -257,8 +257,10 @@ static int apply_sparse_checkout(struct index_state *istate, | |||
| 		ce->ce_flags |= CE_SKIP_WORKTREE; | ||||
| 	else | ||||
| 		ce->ce_flags &= ~CE_SKIP_WORKTREE; | ||||
| 	if (was_skip_worktree != ce_skip_worktree(ce)) | ||||
| 	if (was_skip_worktree != ce_skip_worktree(ce)) { | ||||
| 		ce->ce_flags |= CE_UPDATE_IN_BASE; | ||||
| 		istate->cache_changed |= CE_ENTRY_CHANGED; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * if (!was_skip_worktree && !ce_skip_worktree()) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy