Code

Merge branch 'jb/required-filter'
authorJunio C Hamano <gitster@pobox.com>
Tue, 28 Feb 2012 21:25:57 +0000 (13:25 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 28 Feb 2012 21:25:57 +0000 (13:25 -0800)
* jb/required-filter:
  Add a setting to require a filter to be successful

Conflicts:
convert.c

1  2 
convert.c

diff --combined convert.c
index 4534e2c2b003998a590637fc43c0549ff23f71b2,c06309f5e102c36f5751fce8cb83229ff9acca42..66021550c32f86e662fe5da84c852e80ae790450
+++ b/convert.c
@@@ -2,7 -2,6 +2,7 @@@
  #include "attr.h"
  #include "run-command.h"
  #include "quote.h"
 +#include "sigchain.h"
  
  /*
   * convert.c - convert a file when checking it out and checking it in.
@@@ -196,17 -195,9 +196,17 @@@ static int crlf_to_git(const char *path
        char *dst;
  
        if (crlf_action == CRLF_BINARY ||
 -          (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) || !len)
 +          (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) ||
 +          (src && !len))
                return 0;
  
 +      /*
 +       * If we are doing a dry-run and have no source buffer, there is
 +       * nothing to analyze; we must assume we would convert.
 +       */
 +      if (!buf && !src)
 +              return 1;
 +
        gather_stats(src, len, &stats);
  
        if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
        if (!stats.cr)
                return 0;
  
 +      /*
 +       * At this point all of our source analysis is done, and we are sure we
 +       * would convert. If we are in dry-run mode, we can give an answer.
 +       */
 +      if (!buf)
 +              return 1;
 +
        /* only grow if not in place */
        if (strbuf_avail(buf) + buf->len < len)
                strbuf_grow(buf, len - buf->len);
@@@ -376,16 -360,12 +376,16 @@@ static int filter_buffer(int in, int ou
        if (start_command(&child_process))
                return error("cannot fork to run external filter %s", params->cmd);
  
 +      sigchain_push(SIGPIPE, SIG_IGN);
 +
        write_err = (write_in_full(child_process.in, params->src, params->size) < 0);
        if (close(child_process.in))
                write_err = 1;
        if (write_err)
                error("cannot feed the input to external filter %s", params->cmd);
  
 +      sigchain_pop(SIGPIPE);
 +
        status = finish_command(&child_process);
        if (status)
                error("external filter %s failed %d", params->cmd, status);
@@@ -411,9 -391,6 +411,9 @@@ static int apply_filter(const char *pat
        if (!cmd)
                return 0;
  
 +      if (!dst)
 +              return 1;
 +
        memset(&async, 0, sizeof(async));
        async.proc = filter_buffer;
        async.data = &params;
@@@ -452,6 -429,7 +452,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)
        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;
  }
  
@@@ -545,12 -528,9 +551,12 @@@ static int ident_to_git(const char *pat
  {
        char *dst, *dollar;
  
 -      if (!ident || !count_ident(src, len))
 +      if (!ident || (src && !count_ident(src, len)))
                return 0;
  
 +      if (!buf)
 +              return 1;
 +
        /* only grow if not in place */
        if (strbuf_avail(buf) + buf->len < len)
                strbuf_grow(buf, len - buf->len);
@@@ -773,20 -753,26 +779,26 @@@ int convert_to_git(const char *path, co
  {
        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) {
+       if (!ret && required)
+               die("%s: clean filter '%s' failed", path, ca.drv->name);
 +      if (ret && dst) {
                src = dst->buf;
                len = dst->len;
        }
        ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
        ret |= crlf_to_git(path, src, len, dst, ca.crlf_action, checksafe);
 -      if (ret) {
 +      if (ret && dst) {
                src = dst->buf;
                len = dst->len;
        }
@@@ -797,13 -783,16 +809,16 @@@ static int convert_to_working_tree_inte
                                            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) {
                        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)