diff options
author | Jehan Bing <jehan@orb.com> | 2012-02-16 17:19:03 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-02-17 07:37:08 -0800 |
commit | 36daaaca0046542f4d5576ad5766ac55f43e3fc3 (patch) | |
tree | 2c724d58d107f444acc09d69e72bbfc33fee42ce /convert.c | |
parent | 0364bb135e285d4118b69979ade3078fab50e08a (diff) | |
download | git-36daaaca0046542f4d5576ad5766ac55f43e3fc3.tar.gz |
Add a setting to require a filter to be successfuljb/required-filter
By default, a missing filter driver or a failure from the filter driver is
not an error, but merely makes the filter operation a no-op pass through.
This is useful to massage the content into a shape that is more convenient
for the platform, filesystem, and the user to use, and the content filter
mechanism is not used to turn something unusable into usable.
However, we could also use of the content filtering mechanism and store
the content that cannot be directly used in the repository (e.g. a UUID
that refers to the true content stored outside git, or an encrypted
content) and turn it into a usable form upon checkout (e.g. download the
external content, or decrypt the encrypted content). For such a use case,
the content cannot be used when filter driver fails, and we need a way to
tell Git to abort the whole operation for such a failing or missing filter
driver.
Add a new "filter.<driver>.required" configuration variable to mark the
second use case. When it is set, git will abort the operation when the
filter driver does not exist or exits with a non-zero status code.
Signed-off-by: Jehan Bing <jehan@orb.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'convert.c')
-rw-r--r-- | convert.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -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("%s: clean filter '%s' failed", path, 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("%s: smudge filter %s failed", path, ca.drv->name); + + return ret | ret_filter; } int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst) |