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

Re: [PATCH v4] convert filter: supply path to external driver

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 21, 2010, 21:24 UTC
Message-ID
<7vzkry7rb4.fsf@alter.siamese.dyndns.org>
In-Reply-To
<20101221203322.GA13868@honk.padd.com>
Pete Wyckoff <pw@padd.com> writes:
Show 14 quoted lines
> 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 "%f" conversion specifier to the gitattribute for filter.
> It will be expanded with the path name to the file when invoking
> the external filter command.  The path name is quoted and
> special characters are escaped to prevent the shell from splitting
> incorrectly.

You do not specify the filter in attributes file, and this is not just about splitting incorrectly (think $var substitutions). I rephrased the last paragraph when I tentatively queued v3 (and then I had to discard it after seeing this round) like this:

    Allow "%f" in the custom filter command line specified in the
    configuration.  This will be substituted by the filename inside a
    single-quote pair to be passed to the shell.
> I couldn't quite bring myself to delete the nice spaces in
> redirections like "> test".  Rest of the usage in t/ seems
> to be about 1/3 for space, 2/3 against.

While existing mistakes by others do not make a good excuse to throw unnecessary code-churn patches at me, it is not an excuse to introduce more mistakes of the same kind in new code.

Show 18 quoted lines
>  Documentation/gitattributes.txt |   12 +++++++++
>  convert.c                       |   22 +++++++++++++++++-
>  t/t0021-conversion.sh           |   48 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+), 1 deletions(-)
>
> diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
> index 564586b..1afcf01 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 "%f" 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:

Maybe "important" to you, but not really. Just let the reader decide the importance. I rephrased this when I tentatively queued v3 (and then I had to discard it after seeing this round) like this:

    Sequence "%f" on the filter command line is replaced with the name of
    the file the filter is working on (a filter can use this in keyword
    substitution, for example):
Show 23 quoted lines
> diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
> index 828e35b..69c22a6 100755
> --- a/t/t0021-conversion.sh
> +++ b/t/t0021-conversion.sh
> @@ -93,4 +93,52 @@ test_expect_success expanded_in_repo '
>  	cmp expanded-keywords expected-output
>  '
>  
> +test_expect_success 'filter shell-escaped filenames setup' '
> +	cat >argc.sh <<-EOF &&
> +	#!$SHELL_PATH
> +	echo argc: \$# "\$@"
> +	EOF
> +	chmod +x argc.sh
> +'
>
> +# The use of %f in a filter definition is expanded to the path to
> +# the filename being smudged or cleaned.  It must be shell escaped.
> +# First, set up some interesting file names and pet them in
> +# .gitattributes.
> +test_expect_success 'filter shell-escaped filenames test' '
> +	norm=name-no-magic &&
> +	spec=$(echo name:sgl\"dbl\ spc!bang | tr : \\047) &&

I think this is going overboard. The correctness of sq_quote_buf() is not what we are really testing with this test; we are primarily interested in testing that '%f' is substituted here. You can and should drop at least dq from the funny pathname, so that this can be run on Windows as well. Perhaps (note two SPs between "name" and "with"):

	special="name  with '\''sq'\'' and \$x" &&

Do not over-abbreviate variable names unnecessarily; it will only confuse the readers. "spec" typically stands for "specification", but you don't mean that here.

Also if you define the filter as "sh ./argc.sh %f", you should be able to stop worrying about the "chmod +x" failing, no?

> +	echo some test text > test &&
> +	cat test > $norm &&
> +	cat test > "$spec" &&
Quote both for consistency.
	cat test >"$norm"
        cat test >"$spec"
> +	git add $norm &&
> +	git add "$spec" &&
Why add them separately?
Show 10 quoted lines
> +	echo "name* filter=argc" > .gitattributes &&
> +
> +	# delete the files and check them out again, using a smudge filter
> +	# that will count the args and echo the command-line back to us
> +	git config filter.argc.smudge "./argc.sh %f" &&
> +	rm $norm "$spec" &&
> +	git checkout -- $norm "$spec" &&
> +
> +	# make sure argc.sh counted the right number of args
> +	echo "argc: 1 $norm" > res &&

Perhaps "res" stands for "result", but both are misleading as it is unclear if that is an expected result or an actual result.

	echo "argc: 1 $norm" >expect &&
Thanks.
Previous: Pete WyckoffNext: Pete Wyckoff
Message 11 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.