From: Pete Wyckoff <pw@padd.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Jonathan Nieder <jrnieder@gmail.com>,
git@vger.kernel.org, Jeff King <peff@peff.net>,
Johannes Sixt <j.sixt@viscovery.net>
Subject: [PATCH v5] convert filter: supply path to external driver
Date: Wed, 22 Dec 2010 06:40:13 -0800 [thread overview]
Message-ID: <20101222144013.GA22089@honk.padd.com> (raw)
In-Reply-To: <7vzkry7rb4.fsf@alter.siamese.dyndns.org>
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.
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.
Signed-off-by: Pete Wyckoff <pw@padd.com>
---
gitster@pobox.com wrote on Tue, 21 Dec 2010 13:24 -0800:
> [detailed review]
Changes from v4:
- Updated commit message, docs per Junio mods
- Removed space after shell redirection ">"
- Simplified test case per Junio recommendations
Hopefully this is the last round of review and it is
safe to stage now. Thanks,
-- Pete
Documentation/gitattributes.txt | 10 +++++++++
convert.c | 22 +++++++++++++++++++-
t/t0021-conversion.sh | 42 +++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+), 1 deletions(-)
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 564586b..8c2fdd1 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -317,6 +317,16 @@ command is "cat").
smudge = cat
------------------------
+Sequence "%f" on the filter command line is replaced with the name of
+the file the filter is working on. A filter might use this in keyword
+substitution. For example:
+
+------------------------
+[filter "p4"]
+ clean = git-p4-filter --clean %f
+ smudge = git-p4-filter --smudge %f
+------------------------
+
Interaction between checkin/checkout attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/convert.c b/convert.c
index e41a31e..8f020bc 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,23 @@ static int filter_buffer(int in, int out, void *data)
int write_err, status;
const char *argv[] = { NULL, NULL };
- argv[0] = params->cmd;
+ /* apply % substitution to cmd */
+ struct strbuf cmd = STRBUF_INIT;
+ struct strbuf path = STRBUF_INIT;
+ struct strbuf_expand_dict_entry dict[] = {
+ "f", NULL,
+ NULL, NULL,
+ };
+
+ /* quote the path to preserve spaces, etc. */
+ sq_quote_buf(&path, params->path);
+ dict[0].value = path.buf;
+
+ /* expand all %f with the quoted path */
+ strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
+ strbuf_release(&path);
+
+ argv[0] = cmd.buf;
memset(&child_process, 0, sizeof(child_process));
child_process.argv = argv;
@@ -349,6 +366,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 +395,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))
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index 828e35b..aacfd00 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -93,4 +93,46 @@ test_expect_success expanded_in_repo '
cmp expanded-keywords expected-output
'
+# 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' '
+ cat >argc.sh <<-EOF &&
+ #!$SHELL_PATH
+ echo argc: \$# "\$@"
+ EOF
+ normal=name-no-magic &&
+ special="name with '\''sq'\'' and \$x" &&
+ echo some test text >"$normal" &&
+ echo some test text >"$special" &&
+ git add "$normal" "$special" &&
+ git commit -q -m "add files" &&
+ 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 "sh ./argc.sh %f" &&
+ rm "$normal" "$special" &&
+ git checkout -- "$normal" "$special" &&
+
+ # make sure argc.sh counted the right number of args
+ echo "argc: 1 $normal" >expect &&
+ test_cmp expect "$normal" &&
+ echo "argc: 1 $special" >expect &&
+ test_cmp expect "$special" &&
+
+ # do the same thing, but with more args in the filter expression
+ git config filter.argc.smudge "sh ./argc.sh %f --my-extra-arg" &&
+ rm "$normal" "$special" &&
+ git checkout -- "$normal" "$special" &&
+
+ # make sure argc.sh counted the right number of args
+ echo "argc: 2 $normal --my-extra-arg" >expect &&
+ test_cmp expect "$normal" &&
+ echo "argc: 2 $special --my-extra-arg" >expect &&
+ test_cmp expect "$special" &&
+ :
+'
+
test_done
--
1.7.2.3
next prev parent reply other threads:[~2010-12-22 14:40 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 ` [PATCH] convert filter: supply path to external driver Pete Wyckoff
2010-12-19 21:59 ` 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 ` Pete Wyckoff [this message]
2010-12-22 18:10 ` [PATCH v5] " 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=20101222144013.GA22089@honk.padd.com \
--to=pw@padd.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j.sixt@viscovery.net \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
/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).