Make git-diff-cache skip any comparisons which don't match pathspec
This brings all the same pathspec optimizations that git-diff-tree does to git-diff-cache.
This commit is contained in:
		
							
								
								
									
										30
									
								
								diff-cache.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								diff-cache.c
									
									
									
									
									
								
							@ -87,12 +87,37 @@ static int show_modified(struct cache_entry *old,
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int diff_cache(struct cache_entry **ac, int entries)
 | 
					static int ce_path_match(const struct cache_entry *ce, const char **pathspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char *match, *name;
 | 
				
			||||||
 | 
						int len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!pathspec)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = ce_namelen(ce);
 | 
				
			||||||
 | 
						name = ce->name;
 | 
				
			||||||
 | 
						while ((match = *pathspec++) != NULL) {
 | 
				
			||||||
 | 
							int matchlen = strlen(match);
 | 
				
			||||||
 | 
							if (matchlen > len)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (memcmp(name, match, matchlen))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (name[matchlen] == '/' || !name[matchlen])
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int diff_cache(struct cache_entry **ac, int entries, const char **pathspec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while (entries) {
 | 
						while (entries) {
 | 
				
			||||||
		struct cache_entry *ce = *ac;
 | 
							struct cache_entry *ce = *ac;
 | 
				
			||||||
		int same = (entries > 1) && ce_same_name(ce, ac[1]);
 | 
							int same = (entries > 1) && ce_same_name(ce, ac[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!ce_path_match(ce, pathspec))
 | 
				
			||||||
 | 
								goto skip_entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (ce_stage(ce)) {
 | 
							switch (ce_stage(ce)) {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			/* No stage 1 entry? That means it's a new file */
 | 
								/* No stage 1 entry? That means it's a new file */
 | 
				
			||||||
@ -130,6 +155,7 @@ static int diff_cache(struct cache_entry **ac, int entries)
 | 
				
			|||||||
			die("impossible cache entry stage");
 | 
								die("impossible cache entry stage");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skip_entry:
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Ignore all the different stages for this file,
 | 
							 * Ignore all the different stages for this file,
 | 
				
			||||||
		 * we've handled the relevant cases now.
 | 
							 * we've handled the relevant cases now.
 | 
				
			||||||
@ -281,7 +307,7 @@ int main(int argc, const char **argv)
 | 
				
			|||||||
	if (read_tree(tree, size, 1, pathspec))
 | 
						if (read_tree(tree, size, 1, pathspec))
 | 
				
			||||||
		die("unable to read tree object %s", tree_name);
 | 
							die("unable to read tree object %s", tree_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = diff_cache(active_cache, active_nr);
 | 
						ret = diff_cache(active_cache, active_nr, pathspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	diffcore_std(pathspec,
 | 
						diffcore_std(pathspec,
 | 
				
			||||||
		     detect_rename, diff_score_opt,
 | 
							     detect_rename, diff_score_opt,
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user