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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.