git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pete Wyckoff <pw@padd.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH] convert filter: supply path to external driver
Date: Sun, 19 Dec 2010 16:29:25 -0500	[thread overview]
Message-ID: <20101219212925.GA7393@arf.padd.com> (raw)
In-Reply-To: <20101218223822.GA18902@arf.padd.com>

Filtering to support keyword expansion may need the name of
the file being filtered.  In particular, to support p4 keywords
like

    $File: //depot/product/dir/script.sh $

the smudge filter needs to know the name of the file it is
smudging.

Add a "%s" conversion specifier to the gitattribute for filter.
It will be expanded with the path name to the file when invoking
the external filter command.

Signed-off-by: Pete Wyckoff <pw@padd.com>
---

pw@padd.com wrote on Sat, 18 Dec 2010 17:38 -0500:
> I'm using git-p4 to import and work with upstream p4
> repositories.  Some of the files are ktext, meaning they expect
> expansion of $Id$ and similar identifiers.
> 
> Using the filter driver for this file, I can do the "clean" part
> easily, but to calculate the "smudge" correctly, I need to know
> the filename inside the filter driver.

This works fine for me.  It is backward compatible, and leaves
open the possibility of adding other % modifiers if we find
a need later.

I have a filter that handles all the p4 $Keyword$ expansions,
now, using this patch.  It can go into contrib if others would
find it useful.  This seriously reduces many hassles associated
with my git-p4 workflow, where a plethora of ancillary systems
rely on keyword expansion in the source.

Cc Junio for comments as the original author of convert filter
code.

		-- Pete


 Documentation/gitattributes.txt |   12 ++++++++++++
 convert.c                       |   15 ++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 564586b..9ac2138 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -317,6 +317,18 @@ command is "cat").
 	smudge = cat
 ------------------------
 
+If your filter needs the path of the file it is working on,
+you can use the "%s" conversion specification.  It will be
+replaced with the relative path to the file.  This is important
+for keyword substitution that depends on the name of the
+file.  Like this:
+
+------------------------
+[filter "p4"]
+	clean = git-p4-filter --clean %s
+	smudge = git-p4-filter --smudge %s
+------------------------
+
 
 Interaction between checkin/checkout attributes
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/convert.c b/convert.c
index e41a31e..d4c6ed1 100644
--- a/convert.c
+++ b/convert.c
@@ -317,6 +317,7 @@ struct filter_params {
 	const char *src;
 	unsigned long size;
 	const char *cmd;
+	const char *path;
 };
 
 static int filter_buffer(int in, int out, void *data)
@@ -329,7 +330,16 @@ static int filter_buffer(int in, int out, void *data)
 	int write_err, status;
 	const char *argv[] = { NULL, NULL };
 
-	argv[0] = params->cmd;
+	/* replace optional %s with path */
+	struct strbuf cmd = STRBUF_INIT;
+	struct strbuf_expand_dict_entry dict[] = {
+	    "s", params->path,
+	    NULL, NULL,
+	};
+
+	strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
+
+	argv[0] = cmd.buf;
 
 	memset(&child_process, 0, sizeof(child_process));
 	child_process.argv = argv;
@@ -349,6 +359,8 @@ static int filter_buffer(int in, int out, void *data)
 	status = finish_command(&child_process);
 	if (status)
 		error("external filter %s failed %d", params->cmd, status);
+
+	strbuf_release(&cmd);
 	return (write_err || status);
 }
 
@@ -376,6 +388,7 @@ static int apply_filter(const char *path, const char *src, size_t len,
 	params.src = src;
 	params.size = len;
 	params.cmd = cmd;
+	params.path = path;
 
 	fflush(NULL);
 	if (start_async(&async))
-- 
1.7.2.3

  reply	other threads:[~2010-12-19 21:29 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-18 22:38 smudge/clean filter needs filename Pete Wyckoff
2010-12-19 21:29 ` Pete Wyckoff [this message]
2010-12-19 21:59   ` [PATCH] convert filter: supply path to external driver Junio C Hamano
2010-12-20  2:24     ` Jeff King
2010-12-20  5:52       ` david
2010-12-20 16:09     ` [PATCH v2] " Pete Wyckoff
2010-12-20 17:59       ` Junio C Hamano
2010-12-21 13:44         ` [PATCH v3] " Pete Wyckoff
2010-12-21 18:19           ` Jonathan Nieder
2010-12-21 20:33             ` [PATCH v4] " Pete Wyckoff
2010-12-21 21:24               ` Junio C Hamano
2010-12-22 14:40                 ` [PATCH v5] " Pete Wyckoff
2010-12-22 18:10                   ` Junio C Hamano
2010-12-22 23:22                     ` Junio C Hamano
2010-12-20  8:04   ` [PATCH] " Johannes Sixt
2010-12-20  8:52     ` Junio C Hamano
2010-12-20 14:41     ` Pete Wyckoff

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=20101219212925.GA7393@arf.padd.com \
    --to=pw@padd.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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).