diff options
| author | Jeff King <peff@peff.net> | 2011-05-23 16:31:05 -0400 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2011-05-24 09:08:17 -0700 | 
| commit | 0508fe533dfe1b890f6a2d31ca42ba25466e8ff5 (patch) | |
| tree | 748d9bcd266ca173d6269a07c95343ccc8cf2a76 /combine-diff.c | |
| parent | 3813e69031d2df2702f50b9649fa2e40ea11e558 (diff) | |
| download | git-0508fe533dfe1b890f6a2d31ca42ba25466e8ff5.tar.gz | |
combine-diff: respect textconv attributes
When doing a combined diff, we did not respect textconv attributes at
all. This generally lead to us printing "Binary files differ" when we
could show a combined diff of the converted text.
This patch converts file contents according to textconv attributes. The
implementation is slightly ugly; because the textconv code is tightly
linked with the diff_filespec code, we temporarily create a diff_filespec
during conversion. In practice, though, this should not create a
performance problem.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'combine-diff.c')
| -rw-r--r-- | combine-diff.c | 41 | 
1 files changed, 32 insertions, 9 deletions
diff --git a/combine-diff.c b/combine-diff.c index 94a207f477..be67cfcd45 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -93,7 +93,9 @@ struct sline {  	unsigned long *p_lno;  }; -static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size) +static char *grab_blob(const unsigned char *sha1, unsigned int mode, +		       unsigned long *size, struct userdiff_driver *textconv, +		       const char *path)  {  	char *blob;  	enum object_type type; @@ -106,6 +108,11 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned lo  		/* deleted blob */  		*size = 0;  		return xcalloc(1, 1); +	} else if (textconv) { +		struct diff_filespec *df = alloc_filespec(path); +		fill_filespec(df, sha1, mode); +		*size = fill_textconv(textconv, df, &blob); +		free_filespec(df);  	} else {  		blob = read_sha1_file(sha1, &type, size);  		if (type != OBJ_BLOB) @@ -205,7 +212,9 @@ static void consume_line(void *state_, char *line, unsigned long len)  static void combine_diff(const unsigned char *parent, unsigned int mode,  			 mmfile_t *result_file,  			 struct sline *sline, unsigned int cnt, int n, -			 int num_parent, int result_deleted) +			 int num_parent, int result_deleted, +			 struct userdiff_driver *textconv, +			 const char *path)  {  	unsigned int p_lno, lno;  	unsigned long nmask = (1UL << n); @@ -218,7 +227,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,  	if (result_deleted)  		return; /* result deleted */ -	parent_file.ptr = grab_blob(parent, mode, &sz); +	parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);  	parent_file.size = sz;  	memset(&xpp, 0, sizeof(xpp));  	xpp.flags = 0; @@ -771,16 +780,20 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,  	int working_tree_file = is_null_sha1(elem->sha1);  	mmfile_t result_file;  	struct userdiff_driver *userdiff; +	struct userdiff_driver *textconv = NULL;  	int is_binary;  	context = opt->context;  	userdiff = userdiff_find_by_path(elem->path);  	if (!userdiff)  		userdiff = userdiff_find_by_name("default"); +	if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV)) +		textconv = userdiff_get_textconv(userdiff);  	/* Read the result of merge first */  	if (!working_tree_file) -		result = grab_blob(elem->sha1, elem->mode, &result_size); +		result = grab_blob(elem->sha1, elem->mode, &result_size, +				   textconv, elem->path);  	else {  		/* Used by diff-tree to read from the working tree */  		struct stat st; @@ -803,9 +816,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,  		} else if (S_ISDIR(st.st_mode)) {  			unsigned char sha1[20];  			if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0) -				result = grab_blob(elem->sha1, elem->mode, &result_size); +				result = grab_blob(elem->sha1, elem->mode, +						   &result_size, NULL, NULL);  			else -				result = grab_blob(sha1, elem->mode, &result_size); +				result = grab_blob(sha1, elem->mode, +						   &result_size, NULL, NULL); +		} else if (textconv) { +			struct diff_filespec *df = alloc_filespec(elem->path); +			fill_filespec(df, null_sha1, st.st_mode); +			result_size = fill_textconv(textconv, df, &result); +			free_filespec(df);  		} else if (0 <= (fd = open(elem->path, O_RDONLY))) {  			size_t len = xsize_t(st.st_size);  			ssize_t done; @@ -862,7 +882,9 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,  		}  	} -	if (userdiff->binary != -1) +	if (textconv) +		is_binary = 0; +	else if (userdiff->binary != -1)  		is_binary = userdiff->binary;  	else {  		is_binary = buffer_is_binary(result, result_size); @@ -871,7 +893,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,  			unsigned long size;  			buf = grab_blob(elem->parent[i].sha1,  					elem->parent[i].mode, -					&size); +					&size, NULL, NULL);  			if (buffer_is_binary(buf, size))  				is_binary = 1;  			free(buf); @@ -932,7 +954,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,  			combine_diff(elem->parent[i].sha1,  				     elem->parent[i].mode,  				     &result_file, sline, -				     cnt, i, num_parent, result_deleted); +				     cnt, i, num_parent, result_deleted, +				     textconv, elem->path);  	}  	show_hunks = make_hunks(sline, cnt, num_parent, dense);  | 
