git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] convert filter: supply path to external driver

From
PWPete Wyckoff <pw@padd.com>
Date
Dec 19, 2010, 21:29 UTC
Message-ID
<20101219212925.GA7393@arf.padd.com>
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:
Show 7 quoted lines
> 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
Previous: Pete WyckoffNext: Junio C Hamano
Message 2 of 17 in “smudge/clean filter needs filename”
  1. Pete WyckoffDec 18, 2010
  2. convert filter: supply path to external driverPete Wyckoff, Dec 19, 2010
  3. Junio C HamanoDec 19, 2010
  4. Jeff KingDec 20, 2010
  5. david@lang.hmDec 20, 2010
  6. convert filter: supply path to external driverPete Wyckoff, Dec 20, 2010
  7. Junio C HamanoDec 20, 2010
  8. convert filter: supply path to external driverPete Wyckoff, Dec 21, 2010
  9. Jonathan NiederDec 21, 2010
  10. convert filter: supply path to external driverPete Wyckoff, Dec 21, 2010
  11. Junio C HamanoDec 21, 2010
  12. convert filter: supply path to external driverPete Wyckoff, Dec 22, 2010
  13. Junio C HamanoDec 22, 2010
  14. Junio C HamanoDec 22, 2010
  15. Johannes SixtDec 20, 2010
  16. Junio C HamanoDec 20, 2010
  17. Pete WyckoffDec 20, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.