diff-files: -c and --cc options.
This ports the "combined diff" to diff-files so that differences to the working tree files since stage 2 and stage 3 are shown the same way as combined diff output from diff-tree for the merge commit would be shown if the current working tree files are committed. Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									3ec1909fda
								
							
						
					
					
						commit
						ea726d02e9
					
				|  | @ -4,14 +4,6 @@ | |||
| #include "diffcore.h" | ||||
| #include "quote.h" | ||||
|  | ||||
| struct path_list { | ||||
| 	struct path_list *next; | ||||
| 	int len; | ||||
| 	char *path; | ||||
| 	unsigned char sha1[20]; | ||||
| 	unsigned char parent_sha1[FLEX_ARRAY][20]; | ||||
| }; | ||||
|  | ||||
| static int uninteresting(struct diff_filepair *p) | ||||
| { | ||||
| 	if (diff_unmodified_pair(p)) | ||||
|  | @ -21,15 +13,14 @@ static int uninteresting(struct diff_filepair *p) | |||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct path_list *intersect_paths(struct path_list *curr, | ||||
| 					 int n, int num_parent) | ||||
| static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent) | ||||
| { | ||||
| 	struct diff_queue_struct *q = &diff_queued_diff; | ||||
| 	struct path_list *p; | ||||
| 	struct combine_diff_path *p; | ||||
| 	int i; | ||||
|  | ||||
| 	if (!n) { | ||||
| 		struct path_list *list = NULL, **tail = &list; | ||||
| 		struct combine_diff_path *list = NULL, **tail = &list; | ||||
| 		for (i = 0; i < q->nr; i++) { | ||||
| 			int len; | ||||
| 			const char *path; | ||||
|  | @ -532,18 +523,52 @@ static void dump_sline(struct sline *sline, int cnt, int num_parent) | |||
| 	} | ||||
| } | ||||
|  | ||||
| static int show_combined_diff(struct path_list *elem, int num_parent, | ||||
| int show_combined_diff(struct combine_diff_path *elem, int num_parent, | ||||
| 		       int dense, const char *header, int show_empty) | ||||
| { | ||||
| 	unsigned long size, cnt, lno; | ||||
| 	char *result, *cp, *ep; | ||||
| 	struct sline *sline; /* survived lines */ | ||||
| 	int i, show_hunks, shown_header = 0; | ||||
| 	char ourtmp[TMPPATHLEN]; | ||||
| 	char ourtmp_buf[TMPPATHLEN]; | ||||
| 	char *ourtmp = ourtmp_buf; | ||||
|  | ||||
| 	/* Read the result of merge first */ | ||||
| 	if (memcmp(elem->sha1, null_sha1, 20)) { | ||||
| 		result = grab_blob(elem->sha1, &size); | ||||
| 		write_to_temp_file(ourtmp, result, size); | ||||
| 	} | ||||
| 	else { | ||||
| 		struct stat st; | ||||
| 		int fd; | ||||
| 		ourtmp = elem->path; | ||||
| 		if (0 <= (fd = open(ourtmp, O_RDONLY)) && | ||||
| 		    !fstat(fd, &st)) { | ||||
| 			int len = st.st_size; | ||||
| 			int cnt = 0; | ||||
|  | ||||
| 			size = len; | ||||
| 			result = xmalloc(len + 1); | ||||
| 			while (cnt < len) { | ||||
| 				int done = xread(fd, result+cnt, len-cnt); | ||||
| 				if (done == 0) | ||||
| 					break; | ||||
| 				if (done < 0) | ||||
| 					die("read error '%s'", ourtmp); | ||||
| 				cnt += done; | ||||
| 			} | ||||
| 			result[len] = 0; | ||||
| 		} | ||||
| 		else { | ||||
| 			/* deleted file */ | ||||
| 			size = 0; | ||||
| 			result = xmalloc(1); | ||||
| 			result[0] = 0; | ||||
| 			ourtmp = "/dev/null"; | ||||
| 		} | ||||
| 		if (0 <= fd) | ||||
| 			close(fd); | ||||
| 	} | ||||
|  | ||||
| 	for (cnt = 0, cp = result; cp - result < size; cp++) { | ||||
| 		if (*cp == '\n') | ||||
|  | @ -589,6 +614,7 @@ static int show_combined_diff(struct path_list *elem, int num_parent, | |||
| 		putchar('\n'); | ||||
| 		dump_sline(sline, cnt, num_parent); | ||||
| 	} | ||||
| 	if (ourtmp == ourtmp_buf) | ||||
| 		unlink(ourtmp); | ||||
| 	free(result); | ||||
|  | ||||
|  | @ -613,7 +639,7 @@ int diff_tree_combined_merge(const unsigned char *sha1, | |||
| 	struct commit *commit = lookup_commit(sha1); | ||||
| 	struct diff_options diffopts; | ||||
| 	struct commit_list *parents; | ||||
| 	struct path_list *p, *paths = NULL; | ||||
| 	struct combine_diff_path *p, *paths = NULL; | ||||
| 	int num_parent, i, num_paths; | ||||
|  | ||||
| 	diff_setup(&diffopts); | ||||
|  | @ -654,7 +680,7 @@ int diff_tree_combined_merge(const unsigned char *sha1, | |||
|  | ||||
| 	/* Clean things up */ | ||||
| 	while (paths) { | ||||
| 		struct path_list *tmp = paths; | ||||
| 		struct combine_diff_path *tmp = paths; | ||||
| 		paths = paths->next; | ||||
| 		free(tmp); | ||||
| 	} | ||||
|  |  | |||
							
								
								
									
										45
									
								
								diff-files.c
								
								
								
								
							
							
						
						
									
										45
									
								
								diff-files.c
								
								
								
								
							|  | @ -7,12 +7,14 @@ | |||
| #include "diff.h" | ||||
|  | ||||
| static const char diff_files_usage[] = | ||||
| "git-diff-files [-q] [-0/-1/2/3] [<common diff options>] [<path>...]" | ||||
| "git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]" | ||||
| COMMON_DIFF_OPTIONS_HELP; | ||||
|  | ||||
| static struct diff_options diff_options; | ||||
| static int silent = 0; | ||||
| static int diff_unmerged_stage = 2; | ||||
| static int combine_merges = 0; | ||||
| static int dense_combined_merges = 0; | ||||
|  | ||||
| static void show_unmerge(const char *path) | ||||
| { | ||||
|  | @ -66,6 +68,10 @@ int main(int argc, const char **argv) | |||
| 			; /* no-op */ | ||||
| 		else if (!strcmp(argv[1], "-s")) | ||||
| 			; /* no-op */ | ||||
| 		else if (!strcmp(argv[1], "-c")) | ||||
| 			combine_merges = 1; | ||||
| 		else if (!strcmp(argv[1], "--cc")) | ||||
| 			dense_combined_merges = combine_merges = 1; | ||||
| 		else { | ||||
| 			int diff_opt_cnt; | ||||
| 			diff_opt_cnt = diff_opt_parse(&diff_options, | ||||
|  | @ -82,6 +88,9 @@ int main(int argc, const char **argv) | |||
| 		} | ||||
| 		argv++; argc--; | ||||
| 	} | ||||
| 	if (combine_merges) { | ||||
| 		diff_options.output_format = DIFF_FORMAT_PATCH; | ||||
| 	} | ||||
|  | ||||
| 	/* Find the directory, and set up the pathspec */ | ||||
| 	pathspec = get_pathspec(prefix, argv + 1); | ||||
|  | @ -108,14 +117,35 @@ int main(int argc, const char **argv) | |||
| 			continue; | ||||
|  | ||||
| 		if (ce_stage(ce)) { | ||||
| 			show_unmerge(ce->name); | ||||
| 			struct { | ||||
| 				struct combine_diff_path p; | ||||
| 				unsigned char fill[4][20]; | ||||
| 			} combine; | ||||
|  | ||||
| 			combine.p.next = NULL; | ||||
| 			combine.p.len = ce_namelen(ce); | ||||
| 			combine.p.path = xmalloc(combine.p.len + 1); | ||||
| 			memcpy(combine.p.path, ce->name, combine.p.len); | ||||
| 			combine.p.path[combine.p.len] = 0; | ||||
| 			memset(combine.p.sha1, 0, 100); | ||||
|  | ||||
| 			while (i < entries) { | ||||
| 				struct cache_entry *nce = active_cache[i]; | ||||
| 				int stage; | ||||
|  | ||||
| 				if (strcmp(ce->name, nce->name)) | ||||
| 					break; | ||||
|  | ||||
| 				/* Stage #2 (ours) is the first parent, | ||||
| 				 * stage #3 (theirs) is the second. | ||||
| 				 */ | ||||
| 				stage = ce_stage(nce); | ||||
| 				if (2 <= stage) | ||||
| 					memcpy(combine.p.parent_sha1[stage-2], | ||||
| 					       nce->sha1, 20); | ||||
|  | ||||
| 				/* diff against the proper unmerged stage */ | ||||
| 				if (ce_stage(nce) == diff_unmerged_stage) | ||||
| 				if (stage == diff_unmerged_stage) | ||||
| 					ce = nce; | ||||
| 				i++; | ||||
| 			} | ||||
|  | @ -123,10 +153,19 @@ int main(int argc, const char **argv) | |||
| 			 * Compensate for loop update | ||||
| 			 */ | ||||
| 			i--; | ||||
|  | ||||
| 			if (combine_merges) { | ||||
| 				show_combined_diff(&combine.p, 2, | ||||
| 						   dense_combined_merges, | ||||
| 						   NULL, 0); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			/* | ||||
| 			 * Show the diff for the 'ce' if we found the one | ||||
| 			 * from the desired stage. | ||||
| 			 */ | ||||
| 			show_unmerge(ce->name); | ||||
| 			if (ce_stage(ce) != diff_unmerged_stage) | ||||
| 				continue; | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										11
									
								
								diff.h
								
								
								
								
							
							
						
						
									
										11
									
								
								diff.h
								
								
								
								
							|  | @ -56,6 +56,17 @@ extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2, | |||
| extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new, | ||||
| 			  const char *base, struct diff_options *opt); | ||||
|  | ||||
| struct combine_diff_path { | ||||
| 	struct combine_diff_path *next; | ||||
| 	int len; | ||||
| 	char *path; | ||||
| 	unsigned char sha1[20]; | ||||
| 	unsigned char parent_sha1[FLEX_ARRAY][20]; | ||||
| }; | ||||
|  | ||||
| int show_combined_diff(struct combine_diff_path *elem, int num_parent, | ||||
| 		       int dense, const char *header, int show_empty); | ||||
|  | ||||
| extern int diff_tree_combined_merge(const unsigned char *sha1, const char *, int, int); | ||||
|  | ||||
| extern void diff_addremove(struct diff_options *, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano