git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matthieu Moy <Matthieu.Moy@imag.fr>
To: git@vger.kernel.org
Cc: Matthieu Moy <Matthieu.Moy@imag.fr>
Subject: [PATCH] Implement a textconv filter for "git diff"
Date: Sun, 28 Sep 2008 04:06:56 +0200	[thread overview]
Message-ID: <1222567618-22156-4-git-send-email-Matthieu.Moy@imag.fr> (raw)
In-Reply-To: <1222567618-22156-3-git-send-email-Matthieu.Moy@imag.fr>

That feature is similar to the custom diff driver, but the user only has
to provide a text filter (a command to convert a file into a plain-text
representation). Git takes care of diffing, mode change, ...

For example, with

[textconv "odt2txt"]
          command=odt2txt

*.ods textconv=odt2txt
*.odp textconv=odt2txt
*.odt textconv=odt2txt

One can use "git diff" on OpenOffice files (including "git diff --color"
and friends).

This could be extended so that "git blame" can use it also.
---
 diff.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/diff.c b/diff.c
index 6917981..7cbc42b 100644
--- a/diff.c
+++ b/diff.c
@@ -181,6 +181,12 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 		if (ep != var + 4 && !strcmp(ep, ".command"))
 			return parse_ll_command(var, var + 5, ep, value, DIFF_DRIVER);
 	}
+	if (!prefixcmp(var, "textconv.")) {
+		const char *ep = strrchr(var, '.');
+
+		if (ep != var + 8 && !strcmp(ep, ".command"))
+			return parse_ll_command(var, var + 9, ep, value, TEXTCONV_DRIVER);
+	}
 
 	return git_diff_basic_config(var, value, cb);
 }
@@ -262,6 +268,10 @@ static struct diff_tempfile {
 
 /* Forward declarations */
 static int run_command_to_buf(const char **argv, char **buf, size_t * size);
+static const char *external_cmd_attr(const char *name, int driver_index);
+static void prepare_temp_file(const char *name,
+			      struct diff_tempfile *temp,
+			      struct diff_filespec *one);
 /* End forward declarations */
 
 static int count_lines(const char *data, int size)
@@ -1511,6 +1521,52 @@ static int run_command_to_buf(const char **argv, char **buf, size_t * size)
 	return 0;
 }
 
+static int textconv_two_files(const char *textconv,
+			      const char *name_a,
+			      const char *name_b,
+			      mmfile_t *mf1,
+			      mmfile_t *mf2,
+			      struct diff_filespec *one,
+			      struct diff_filespec *two)
+{
+	const char *spawn_arg[3];
+	const char **arg = &spawn_arg[0];
+	struct diff_tempfile *temp = diff_temp;
+	char *buf_a, *buf_b;
+	size_t size_a, size_b;
+	prepare_temp_file(name_a, &temp[0], one);
+	*arg++ = textconv;
+	*arg++ = temp[0].name;
+	*arg++ = NULL;
+	/*
+	 * Run both commands before touching arguments to make sure we
+	 * do all or nothing.
+	 */
+	if(run_command_to_buf(spawn_arg, &buf_a, &size_a))
+		return -1;
+
+	prepare_temp_file(name_b, &temp[1], two);
+	spawn_arg[1] = temp[1].name;
+	if(run_command_to_buf(spawn_arg, &buf_b, &size_b))
+		return -1;
+
+	mf1->ptr = buf_a;
+	mf1->size = (long)size_a;
+	one->data = mf1->ptr;
+	one->size = mf1->size;
+	one->should_free = 1;
+	one->should_munmap = 1;
+
+	mf2->ptr = buf_b;
+	mf2->size = (long)size_b;
+	two->data = mf2->ptr;
+	two->size = mf2->size;
+	two->should_free = 1;
+	two->should_munmap = 1;
+	return 0;
+}
+
+
 static void builtin_diff(const char *name_a,
 			 const char *name_b,
 			 struct diff_filespec *one,
@@ -1574,6 +1630,18 @@ static void builtin_diff(const char *name_a,
 	if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
 		die("unable to read files to diff");
 
+	const char * textconv = external_cmd_attr(name_a, TEXTCONV_DRIVER);
+	const char * textconvb = external_cmd_attr(name_b, TEXTCONV_DRIVER);
+
+	/*
+	 * Only use the textconv driver if it is set, and is the same
+	 * for source and destination file.
+	 */
+	if (textconv && textconvb && !strcmp(textconv, textconvb))
+		if(textconv_two_files(textconv, name_a, name_b, &mf1, &mf2, one, two))
+			fprintf(stderr, "warning: textconv filter failed, "
+				"falling back to plain diff\n");
+
 	if (!DIFF_OPT_TST(o, TEXT) &&
 	    (diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) {
 		/* Quite common confusing case */
-- 
1.6.0.2.312.g1ef81a

  reply	other threads:[~2008-09-28  2:10 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-28  2:06 Implementation of a "textconv" filter for easy custom diff Matthieu Moy
2008-09-28  2:06 ` [PATCH] Facility to have multiple kinds of drivers for diff Matthieu Moy
2008-09-28  2:06   ` [PATCH] Implement run_command_to_buf (spawn a process and reads its stdout) Matthieu Moy
2008-09-28  2:06     ` Matthieu Moy [this message]
2008-09-28  2:06       ` [PATCH] Document the textconv filter Matthieu Moy
2008-09-28  2:06         ` [PATCH] Add a basic test for " Matthieu Moy
2008-09-28 11:07         ` [PATCH] Document " Johannes Sixt
2008-09-28 12:29           ` Matthieu Moy
2008-09-28  4:15       ` [PATCH] Implement a textconv filter for "git diff" Jeff King
2008-09-28 10:00         ` Matthieu Moy
2008-09-28 16:12           ` Jeff King
2008-09-28  4:10 ` Implementation of a "textconv" filter for easy custom diff Jeff King
2008-09-28  9:57   ` Matthieu Moy
2008-09-28 16:11     ` Jeff King
2008-09-30 15:19       ` Matthieu Moy
2008-09-30 16:45         ` Jeff King
2008-10-05 21:41           ` [PATCH 0/4] diff text conversion filter Jeff King
2008-10-05 21:42             ` [PATCH 1/4] t4012: use test_cmp instead of cmp Jeff King
2008-10-05 21:43             ` [PATCH 2/4] diff: unify external diff and funcname parsing code Jeff King
2008-10-05 21:43             ` [PATCH 3/4] diff: introduce diff.<driver>.binary Jeff King
2008-10-07 15:17               ` Johannes Sixt
2008-10-07 15:35                 ` Jeff King
2008-10-07 15:54                   ` Johannes Sixt
2008-10-12  5:24                   ` Junio C Hamano
2008-10-13  1:23                     ` Jeff King
2008-10-13  4:00                       ` Junio C Hamano
2008-10-13  4:15                         ` Jeff King
2008-10-13  6:10                           ` Johannes Sixt
2008-10-13 13:54                           ` Junio C Hamano
2008-10-13  8:12                         ` Matthieu Moy
2008-10-24  2:46               ` Jeff King
2008-10-24  2:48                 ` [PATCH 1/5] diff: add missing static declaration Jeff King
2008-10-24  2:50                 ` [PATCH 2/5] add userdiff textconv tests Jeff King
2008-10-24  2:53                 ` [PATCH 3/5] refactor userdiff textconv code Jeff King
2008-10-24  7:15                   ` Johannes Sixt
2008-10-24 12:40                     ` Jeff King
2008-10-24 13:51                     ` Jeff King
2008-10-24 14:01                       ` Johannes Sixt
2008-10-24 14:08                         ` Jeff King
2008-10-24 21:12                   ` Junio C Hamano
2008-10-24 22:50                     ` Jeff King
2008-10-24 22:56                       ` Jeff King
2008-10-25  0:48                         ` Jeff King
2008-10-25  0:50                           ` [PATCH 1/7] diff: add missing static declaration Jeff King
2008-10-25  0:51                           ` [PATCH 2/7] add userdiff textconv tests Jeff King
2008-10-25  0:52                           ` [PATCH 3/7] textconv: assume text-converted contents are not binary Jeff King
2008-10-25  0:52                           ` [PATCH 4/7] textconv: don't convert for every operation Jeff King
2008-10-25  5:41                             ` Junio C Hamano
2008-10-25  7:19                               ` Jeff King
2008-10-25 18:32                                 ` Junio C Hamano
2008-10-25 19:35                                   ` Jeff King
2008-10-25 23:35                                     ` Junio C Hamano
2008-10-25 23:48                                     ` Junio C Hamano
2008-10-26  4:52                                       ` Jeff King
2008-10-26  4:38                                     ` Jeff King
2008-10-26  4:41                                       ` [PATCH v3 1/8] diff: add missing static declaration Jeff King
2008-10-26  4:41                                       ` [PATCH v3 2/8] document the diff driver textconv feature Jeff King
2008-10-26  4:42                                       ` [PATCH v3 3/8] add userdiff textconv tests Jeff King
2008-10-26  4:44                                       ` [PATCH v3 4/8] refactor userdiff textconv code Jeff King
2008-10-26  4:45                                       ` [PATCH v3 5/8] userdiff: require explicitly allowing textconv Jeff King
2008-10-26  4:46                                       ` [PATCH v3 6/8] only textconv regular files Jeff King
2008-10-26  4:49                                       ` [PATCH v3 7/8] wt-status: load diff ui config Jeff King
2008-10-27  5:30                                         ` Junio C Hamano
2008-10-27  8:23                                           ` Jeff King
2008-10-26  4:50                                       ` [PATCH v3 8/8] enable textconv for diff in verbose status/commit Jeff King
2008-10-25  0:54                           ` [PATCH 5/7] userdiff: require explicitly allowing textconv Jeff King
2008-10-25  0:54                           ` [PATCH 6/7] document the diff driver textconv feature Jeff King
2008-10-25  0:55                           ` [PATCH 7/7] only textconv regular files Jeff King
2008-10-24  2:55                 ` [PATCH 4/5] userdiff: require explicitly allowing textconv Jeff King
2008-10-24  7:04                   ` Johannes Sixt
2008-10-24  2:56                 ` [PATCH 5/5] document the diff driver textconv feature Jeff King
2008-10-24  7:02                 ` [PATCH 3/4] diff: introduce diff.<driver>.binary Johannes Sixt
2008-10-05 21:43             ` [PATCH 4/4] diff: add filter for converting binary to text Jeff King
2008-10-05 22:03             ` [PATCH 0/4] diff text conversion filter Jakub Narebski
2008-10-06  6:29             ` Johannes Sixt
2008-10-06  6:52               ` Jeff King
2008-10-06  8:55                 ` Johannes Sixt
2008-10-06 15:15               ` Matthieu Moy
2008-10-07  1:20                 ` Jeff King
2008-10-07  5:52                   ` Johannes Sixt
2008-10-07  6:00                     ` Jeff King
2008-10-07  6:15                       ` Matthieu Moy
2008-10-07 15:46                         ` Jeff King
2008-10-07 16:15                           ` Johannes Sixt
2008-10-13  1:29                             ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1222567618-22156-4-git-send-email-Matthieu.Moy@imag.fr \
    --to=matthieu.moy@imag.fr \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).