git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add an option to require a filter to be successful
@ 2012-02-16 23:18 Jehan Bing
  2012-02-17  0:03 ` Junio C Hamano
  0 siblings, 1 reply; 8+ messages in thread
From: Jehan Bing @ 2012-02-16 23:18 UTC (permalink / raw)
  To: git; +Cc: jehan

By default, if a filter driver fails, the unfiltered content will be
used. This patch adds a "filter.<name>.required" config option. When
set to true, git will abort if the filter fails.

A typical usage would be for a "bigfile" filter, where the smudge
command can fail if the file is not available locally. Without the
"required", the content of repository, i.e. a reference to the real
content, will be checked out. Unless one saves the output logs, it
then fairly easy to lose track of what "bigfile" wasn't checked out
correctly.

Another example would be for an encrypted repository if the clean
command (encryption) fails. Without the "required", an unencrypted
content could be stored in the repository by mistake.

Signed-off-by: Jehan Bing <jehan@orb.com>
---
 Documentation/gitattributes.txt |   14 ++++++++++++
 convert.c                       |   28 +++++++++++++++++++++---
 t/t0021-conversion.sh           |   43 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index a85b187..4d1af93 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -305,6 +305,10 @@ intent is that if someone unsets the filter driver definition,
 or does not have the appropriate filter program, the project
 should still be usable.
 
+The exception is if the filter definition has the `required`
+attribute set to `true`. In that case, the filter must apply
+successfully or git will abort the current operation.
+
 For example, in .gitattributes, you would assign the `filter`
 attribute for paths.
 
@@ -335,6 +339,16 @@ input that is already correctly indented.  In this case, the lack of a
 smudge filter means that the clean filter _must_ accept its own output
 without modifying it.
 
+If you do not wish git to continue if `clean` or `smudge` fail, you can
+add a `required` attribute to the filter:
+
+------------------------
+[filter "crypt"]
+	clean = openssl enc ...
+	smudge = openssl enc -d ...
+	required = true
+------------------------
+
 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:
diff --git a/convert.c b/convert.c
index 12868ed..6c95a90 100644
--- a/convert.c
+++ b/convert.c
@@ -429,6 +429,7 @@ static struct convert_driver {
 	struct convert_driver *next;
 	const char *smudge;
 	const char *clean;
+	int required;
 } *user_convert, **user_convert_tail;
 
 static int read_convert_config(const char *var, const char *value, void *cb)
@@ -472,6 +473,11 @@ static int read_convert_config(const char *var, const char *value, void *cb)
 	if (!strcmp("clean", ep))
 		return git_config_string(&drv->clean, var, value);
 
+	if (!strcmp("required", ep)) {
+		drv->required = git_config_bool(var, value);
+		return 0;
+	}
+
 	return 0;
 }
 
@@ -747,13 +753,19 @@ int convert_to_git(const char *path, const char *src, size_t len,
 {
 	int ret = 0;
 	const char *filter = NULL;
+	int required = 0;
 	struct conv_attrs ca;
 
 	convert_attrs(&ca, path);
-	if (ca.drv)
+	if (ca.drv) {
 		filter = ca.drv->clean;
+		required = ca.drv->required;
+	}
 
 	ret |= apply_filter(path, src, len, dst, filter);
+	if (!ret && required)
+		die("required filter '%s' failed", ca.drv->name);
+
 	if (ret) {
 		src = dst->buf;
 		len = dst->len;
@@ -771,13 +783,16 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
 					    size_t len, struct strbuf *dst,
 					    int normalizing)
 {
-	int ret = 0;
+	int ret = 0, ret_filter = 0;
 	const char *filter = NULL;
+	int required = 0;
 	struct conv_attrs ca;
 
 	convert_attrs(&ca, path);
-	if (ca.drv)
+	if (ca.drv) {
 		filter = ca.drv->smudge;
+		required = ca.drv->required;
+	}
 
 	ret |= ident_to_worktree(path, src, len, dst, ca.ident);
 	if (ret) {
@@ -796,7 +811,12 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
 			len = dst->len;
 		}
 	}
-	return ret | apply_filter(path, src, len, dst, filter);
+
+	ret_filter = apply_filter(path, src, len, dst, filter);
+	if (!ret_filter && required)
+		die("required filter %s failed", ca.drv->name);
+
+	return ret | ret_filter;
 }
 
 int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index f19e651..f80a59f 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -153,4 +153,47 @@ test_expect_success 'filter shell-escaped filenames' '
 	:
 '
 
+test_expect_success 'required filter success' '
+	git config filter.required.smudge cat &&
+	git config filter.required.clean cat &&
+	git config filter.required.required true &&
+
+	{
+	    echo "*.r filter=required"
+	} >.gitattributes &&
+
+	echo test > test.r &&
+	git add test.r &&
+	rm -f test.r &&
+	git checkout -- test.r
+'
+
+test_expect_success 'required filter smudge failure' '
+	git config filter.failsmudge.smudge false &&
+	git config filter.failsmudge.clean cat &&
+	git config filter.failsmudge.required true &&
+
+	{
+	    echo "*.fs filter=failsmudge"
+	} >.gitattributes &&
+
+	echo test > test.fs &&
+	git add test.fs &&
+	rm -f test.fs &&
+	! git checkout -- test.fs
+'
+
+test_expect_success 'required filter clean failure' '
+	git config filter.failclean.smudge cat &&
+	git config filter.failclean.clean false &&
+	git config filter.failclean.required true &&
+
+	{
+	    echo "*.fc filter=failclean"
+	} >.gitattributes &&
+
+	echo test > test.fc &&
+	! git add test.fc
+'
+
 test_done
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-02-18  7:28 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-16 23:18 [PATCH] Add an option to require a filter to be successful Jehan Bing
2012-02-17  0:03 ` Junio C Hamano
2012-02-17  1:19   ` [PATCH v2] Add a setting " jehan
2012-02-17  7:08     ` Johannes Sixt
2012-02-17 15:35       ` Junio C Hamano
2012-02-18  0:07       ` Junio C Hamano
2012-02-18  0:43         ` Jehan Bing
2012-02-18  7:27           ` Junio C Hamano

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).