built-in diff: minimum tweaks
This fixes up a couple of minor issues with the real built-in diff to be more usable: - Omit ---/+++ header unless we emit diff output; - Detect and punt binary diff like GNU does; - Honor GIT_DIFF_OPTS minimally (only -u<number> and --unified=<number> are currently supported); - Omit line count of 1 from "@@ -l,k +m,n @@" hunk header (i.e. when k == 1 or n == 1) - Adjust testsuite for the lack of -p support. Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									621c53cc08
								
							
						
					
					
						commit
						3ce8f08944
					
				
							
								
								
									
										41
									
								
								diff.c
								
								
								
								
							
							
						
						
									
										41
									
								
								diff.c
								
								
								
								
							|  | @ -212,16 +212,37 @@ static int fill_mmfile(mmfile_t *mf, const char *file) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct emit_callback { | ||||||
|  | 	const char **label_path; | ||||||
|  | }; | ||||||
|  |  | ||||||
| static int fn_out(void *priv, mmbuffer_t *mb, int nbuf) | static int fn_out(void *priv, mmbuffer_t *mb, int nbuf) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
|  | 	struct emit_callback *ecbdata = priv; | ||||||
|  |  | ||||||
|  | 	if (ecbdata->label_path[0]) { | ||||||
|  | 		printf("--- %s\n", ecbdata->label_path[0]); | ||||||
|  | 		printf("+++ %s\n", ecbdata->label_path[1]); | ||||||
|  | 		ecbdata->label_path[0] = ecbdata->label_path[1] = NULL; | ||||||
|  | 	} | ||||||
| 	for (i = 0; i < nbuf; i++) | 	for (i = 0; i < nbuf; i++) | ||||||
| 		if (!fwrite(mb[i].ptr, mb[i].size, 1, stdout)) | 		if (!fwrite(mb[i].ptr, mb[i].size, 1, stdout)) | ||||||
| 			return -1; | 			return -1; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #define FIRST_FEW_BYTES 8000 | ||||||
|  | static int mmfile_is_binary(mmfile_t *mf) | ||||||
|  | { | ||||||
|  | 	long sz = mf->size; | ||||||
|  | 	if (FIRST_FEW_BYTES < sz) | ||||||
|  | 		sz = FIRST_FEW_BYTES; | ||||||
|  | 	if (memchr(mf->ptr, 0, sz)) | ||||||
|  | 		return 1; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| static const char *builtin_diff(const char *name_a, | static const char *builtin_diff(const char *name_a, | ||||||
| 			 const char *name_b, | 			 const char *name_b, | ||||||
| 			 struct diff_tempfile *temp, | 			 struct diff_tempfile *temp, | ||||||
|  | @ -306,22 +327,32 @@ static const char *builtin_diff(const char *name_a, | ||||||
| 	if (label_path[1][0] != '/') | 	if (label_path[1][0] != '/') | ||||||
| 		label_path[1] = quote_two("b/", name_b); | 		label_path[1] = quote_two("b/", name_b); | ||||||
|  |  | ||||||
| 	printf("--- %s\n", label_path[0]); |  | ||||||
| 	printf("+++ %s\n", label_path[1]); |  | ||||||
|  |  | ||||||
| 	if (fill_mmfile(&mf1, temp[0].name) < 0 || | 	if (fill_mmfile(&mf1, temp[0].name) < 0 || | ||||||
| 	    fill_mmfile(&mf2, temp[1].name) < 0) | 	    fill_mmfile(&mf2, temp[1].name) < 0) | ||||||
| 		die("unable to read files to diff"); | 		die("unable to read files to diff"); | ||||||
|  |  | ||||||
| 	/* Crazy xdl interfaces.. */ | 	if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) | ||||||
| 	{ | 		printf("Binary files %s and %s differ\n", | ||||||
|  | 		       label_path[0], label_path[1]); | ||||||
|  | 	else { | ||||||
|  | 		/* Crazy xdl interfaces.. */ | ||||||
|  | 		const char *diffopts = getenv("GIT_DIFF_OPTS"); | ||||||
| 		xpparam_t xpp; | 		xpparam_t xpp; | ||||||
| 		xdemitconf_t xecfg; | 		xdemitconf_t xecfg; | ||||||
| 		xdemitcb_t ecb; | 		xdemitcb_t ecb; | ||||||
|  | 		struct emit_callback ecbdata; | ||||||
|  |  | ||||||
|  | 		ecbdata.label_path = label_path; | ||||||
| 		xpp.flags = XDF_NEED_MINIMAL; | 		xpp.flags = XDF_NEED_MINIMAL; | ||||||
| 		xecfg.ctxlen = 3; | 		xecfg.ctxlen = 3; | ||||||
|  | 		if (!diffopts) | ||||||
|  | 			; | ||||||
|  | 		else if (!strncmp(diffopts, "--unified=", 10)) | ||||||
|  | 			xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10); | ||||||
|  | 		else if (!strncmp(diffopts, "-u", 2)) | ||||||
|  | 			xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10); | ||||||
| 		ecb.outf = fn_out; | 		ecb.outf = fn_out; | ||||||
|  | 		ecb.priv = &ecbdata; | ||||||
| 		xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); | 		xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -49,7 +49,7 @@ rename from path0 | ||||||
| rename to path1 | rename to path1 | ||||||
| --- a/path0 | --- a/path0 | ||||||
| +++ b/path1 | +++ b/path1 | ||||||
| @@ -8,7 +8,7 @@ Line 7 | @@ -8,7 +8,7 @@ | ||||||
|  Line 8 |  Line 8 | ||||||
|  Line 9 |  Line 9 | ||||||
|  Line 10 |  Line 10 | ||||||
|  |  | ||||||
|  | @ -245,20 +245,24 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb) { | ||||||
|  |  | ||||||
| 	nb += xdl_num_out(buf + nb, c1 ? s1: 0); | 	nb += xdl_num_out(buf + nb, c1 ? s1: 0); | ||||||
|  |  | ||||||
| 	memcpy(buf + nb, ",", 1); | 	if (c1 != 1) { | ||||||
| 	nb += 1; | 		memcpy(buf + nb, ",", 1); | ||||||
|  | 		nb += 1; | ||||||
|  |  | ||||||
| 	nb += xdl_num_out(buf + nb, c1); | 		nb += xdl_num_out(buf + nb, c1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	memcpy(buf + nb, " +", 2); | 	memcpy(buf + nb, " +", 2); | ||||||
| 	nb += 2; | 	nb += 2; | ||||||
|  |  | ||||||
| 	nb += xdl_num_out(buf + nb, c2 ? s2: 0); | 	nb += xdl_num_out(buf + nb, c2 ? s2: 0); | ||||||
|  |  | ||||||
| 	memcpy(buf + nb, ",", 1); | 	if (c2 != 1) { | ||||||
| 	nb += 1; | 		memcpy(buf + nb, ",", 1); | ||||||
|  | 		nb += 1; | ||||||
|  |  | ||||||
| 	nb += xdl_num_out(buf + nb, c2); | 		nb += xdl_num_out(buf + nb, c2); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	memcpy(buf + nb, " @@\n", 4); | 	memcpy(buf + nb, " @@\n", 4); | ||||||
| 	nb += 4; | 	nb += 4; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano