From be58e70dbadf3cb3f4aa5829d513d886ae8bc460 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 5 Oct 2008 17:43:21 -0400 Subject: diff: unify external diff and funcname parsing code Both sets of code assume that one specifies a diff profile as a gitattribute via the "diff=foo" attribute. They then pull information about that profile from the config as diff.foo.*. The code for each is currently completely separate from the other, which has several disadvantages: - there is duplication as we maintain code to create and search the separate lists of external drivers and funcname patterns - it is difficult to add new profile options, since it is unclear where they should go - the code is difficult to follow, as we rely on the "check if this file is binary" code to find the funcname pattern as a side effect. This is the first step in refactoring the binary-checking code. This patch factors out these diff profiles into "userdiff" drivers. A file with "diff=foo" uses the "foo" driver, which is specified by a single struct. Note that one major difference between the two pieces of code is that the funcname patterns are always loaded, whereas external drivers are loaded only for the "git diff" porcelain; the new code takes care to retain that situation. Signed-off-by: Jeff King Signed-off-by: Shawn O. Pearce --- userdiff.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 userdiff.c (limited to 'userdiff.c') diff --git a/userdiff.c b/userdiff.c new file mode 100644 index 0000000000..80e2857abb --- /dev/null +++ b/userdiff.c @@ -0,0 +1,160 @@ +#include "userdiff.h" +#include "cache.h" +#include "attr.h" + +static struct userdiff_driver *drivers; +static int ndrivers; +static int drivers_alloc; + +#define FUNCNAME(name, pattern) \ + { name, NULL, { pattern, REG_EXTENDED } } +static struct userdiff_driver builtin_drivers[] = { +FUNCNAME("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$"), +FUNCNAME("java", + "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n" + "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$"), +FUNCNAME("objc", + /* Negate C statements that can look like functions */ + "!^[ \t]*(do|for|if|else|return|switch|while)\n" + /* Objective-C methods */ + "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n" + /* C functions */ + "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n" + /* Objective-C class/protocol definitions */ + "^(@(implementation|interface|protocol)[ \t].*)$"), +FUNCNAME("pascal", + "^((procedure|function|constructor|destructor|interface|" + "implementation|initialization|finalization)[ \t]*.*)$" + "\n" + "^(.*=[ \t]*(class|record).*)$"), +FUNCNAME("php", "^[\t ]*((function|class).*)"), +FUNCNAME("python", "^[ \t]*((class|def)[ \t].*)$"), +FUNCNAME("ruby", "^[ \t]*((class|module|def)[ \t].*)$"), +FUNCNAME("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$"), +FUNCNAME("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$"), +}; +#undef FUNCNAME + +static struct userdiff_driver driver_true = { + "diff=true", + NULL, + { NULL, 0 } +}; +struct userdiff_driver *USERDIFF_ATTR_TRUE = &driver_true; + +static struct userdiff_driver driver_false = { + "!diff", + NULL, + { NULL, 0 } +}; +struct userdiff_driver *USERDIFF_ATTR_FALSE = &driver_false; + +static struct userdiff_driver *userdiff_find_by_namelen(const char *k, int len) +{ + int i; + for (i = 0; i < ndrivers; i++) { + struct userdiff_driver *drv = drivers + i; + if (!strncmp(drv->name, k, len) && !drv->name[len]) + return drv; + } + for (i = 0; i < ARRAY_SIZE(builtin_drivers); i++) { + struct userdiff_driver *drv = builtin_drivers + i; + if (!strncmp(drv->name, k, len) && !drv->name[len]) + return drv; + } + return NULL; +} + +static struct userdiff_driver *parse_driver(const char *var, + const char *value, const char *type) +{ + struct userdiff_driver *drv; + const char *dot; + const char *name; + int namelen; + + if (prefixcmp(var, "diff.")) + return NULL; + dot = strrchr(var, '.'); + if (dot == var + 4) + return NULL; + if (strcmp(type, dot+1)) + return NULL; + + name = var + 5; + namelen = dot - name; + drv = userdiff_find_by_namelen(name, namelen); + if (!drv) { + ALLOC_GROW(drivers, ndrivers+1, drivers_alloc); + drv = &drivers[ndrivers++]; + memset(drv, 0, sizeof(*drv)); + drv->name = xmemdupz(name, namelen); + } + return drv; +} + +static int parse_funcname(struct userdiff_funcname *f, const char *k, + const char *v, int cflags) +{ + if (git_config_string(&f->pattern, k, v) < 0) + return -1; + f->cflags = cflags; + return 1; +} + +static int parse_string(const char **d, const char *k, const char *v) +{ + if (git_config_string(d, k, v) < 0) + return -1; + return 1; +} + +int userdiff_config_basic(const char *k, const char *v) +{ + struct userdiff_driver *drv; + + if ((drv = parse_driver(k, v, "funcname"))) + return parse_funcname(&drv->funcname, k, v, 0); + if ((drv = parse_driver(k, v, "xfuncname"))) + return parse_funcname(&drv->funcname, k, v, REG_EXTENDED); + + return 0; +} + +int userdiff_config_porcelain(const char *k, const char *v) +{ + struct userdiff_driver *drv; + + if ((drv = parse_driver(k, v, "command"))) + return parse_string(&drv->external, k, v); + + return 0; +} + +struct userdiff_driver *userdiff_find_by_name(const char *name) { + int len = strlen(name); + return userdiff_find_by_namelen(name, len); +} + +struct userdiff_driver *userdiff_find_by_path(const char *path) +{ + static struct git_attr *attr; + struct git_attr_check check; + + if (!attr) + attr = git_attr("diff", 4); + check.attr = attr; + + if (!path) + return NULL; + if (git_checkattr(path, 1, &check)) + return NULL; + + if (ATTR_TRUE(check.value)) + return &driver_true; + if (ATTR_FALSE(check.value)) + return &driver_false; + if (ATTR_UNSET(check.value)) + return NULL; + return userdiff_find_by_name(check.value); +} -- cgit v1.3 From 122aa6f9c000d0d286898e2eb7b3504ac6cb9ebd Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 5 Oct 2008 17:43:36 -0400 Subject: diff: introduce diff..binary The "diff" gitattribute is somewhat overloaded right now. It can say one of three things: 1. this file is definitely binary, or definitely not (i.e., diff or !diff) 2. this file should use an external diff engine (i.e., diff=foo, diff.foo.command = custom-script) 3. this file should use particular funcname patterns (i.e., diff=foo, diff.foo.(x?)funcname = some-regex) Most of the time, there is no conflict between these uses, since using one implies that the other is irrelevant (e.g., an external diff engine will decide for itself whether the file is binary). However, there is at least one conflicting situation: there is no way to say "use the regular rules to determine whether this file is binary, but if we do diff it textually, use this funcname pattern." That is, currently setting diff=foo indicates that the file is definitely text. This patch introduces a "binary" config option for a diff driver, so that one can explicitly set diff.foo.binary. We default this value to "don't know". That is, setting a diff attribute to "foo" and using "diff.foo.funcname" will have no effect on the binaryness of a file. To get the current behavior, one can set diff.foo.binary to true. This patch also has one additional advantage: it cleans up the interface to the userdiff code a bit. Before, calling code had to know more about whether attributes were false, true, or unset to determine binaryness. Now that binaryness is a property of a driver, we can represent these situations just by passing back a driver struct. Signed-off-by: Jeff King Signed-off-by: Shawn O. Pearce --- diff.c | 52 ++++++++++++++++++++++------------------------------ diffcore.h | 8 ++++++-- userdiff.c | 19 ++++++++++++++++--- userdiff.h | 4 +--- 4 files changed, 45 insertions(+), 38 deletions(-) (limited to 'userdiff.c') diff --git a/diff.c b/diff.c index d50355e842..dabd7f50ec 100644 --- a/diff.c +++ b/diff.c @@ -1268,46 +1268,37 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two) emit_binary_diff_body(file, two, one); } -static void diff_filespec_check_attr(struct diff_filespec *one) +void diff_filespec_load_driver(struct diff_filespec *one) { - struct userdiff_driver *drv; - int check_from_data = 0; - - if (one->checked_attr) - return; - - drv = userdiff_find_by_path(one->path); - one->is_binary = 0; - - /* binaryness */ - if (drv == USERDIFF_ATTR_TRUE) - ; - else if (drv == USERDIFF_ATTR_FALSE) - one->is_binary = 1; - else - check_from_data = 1; - - if (check_from_data) { - if (!one->data && DIFF_FILE_VALID(one)) - diff_populate_filespec(one, 0); - - if (one->data) - one->is_binary = buffer_is_binary(one->data, one->size); - } + if (!one->driver) + one->driver = userdiff_find_by_path(one->path); + if (!one->driver) + one->driver = userdiff_find_by_name("default"); } int diff_filespec_is_binary(struct diff_filespec *one) { - diff_filespec_check_attr(one); + if (one->is_binary == -1) { + diff_filespec_load_driver(one); + if (one->driver->binary != -1) + one->is_binary = one->driver->binary; + else { + if (!one->data && DIFF_FILE_VALID(one)) + diff_populate_filespec(one, 0); + if (one->data) + one->is_binary = buffer_is_binary(one->data, + one->size); + if (one->is_binary == -1) + one->is_binary = 0; + } + } return one->is_binary; } static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespec *one) { - struct userdiff_driver *drv = userdiff_find_by_path(one->path); - if (!drv) - drv = userdiff_find_by_name("default"); - return drv && drv->funcname.pattern ? &drv->funcname : NULL; + diff_filespec_load_driver(one); + return one->driver->funcname.pattern ? &one->driver->funcname : NULL; } void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b) @@ -1559,6 +1550,7 @@ struct diff_filespec *alloc_filespec(const char *path) spec->path = (char *)(spec + 1); memcpy(spec->path, path, namelen+1); spec->count = 1; + spec->is_binary = -1; return spec; } diff --git a/diffcore.h b/diffcore.h index 8ae35785fd..713cca785c 100644 --- a/diffcore.h +++ b/diffcore.h @@ -22,6 +22,8 @@ #define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */ +struct userdiff_driver; + struct diff_filespec { unsigned char sha1[20]; char *path; @@ -40,8 +42,10 @@ struct diff_filespec { #define DIFF_FILE_VALID(spec) (((spec)->mode) != 0) unsigned should_free : 1; /* data should be free()'ed */ unsigned should_munmap : 1; /* data should be munmap()'ed */ - unsigned checked_attr : 1; - unsigned is_binary : 1; /* data should be considered "binary" */ + + struct userdiff_driver *driver; + /* data should be considered "binary"; -1 means "don't know yet" */ + int is_binary; }; extern struct diff_filespec *alloc_filespec(const char *); diff --git a/userdiff.c b/userdiff.c index 80e2857abb..58478a6912 100644 --- a/userdiff.c +++ b/userdiff.c @@ -7,7 +7,7 @@ static int ndrivers; static int drivers_alloc; #define FUNCNAME(name, pattern) \ - { name, NULL, { pattern, REG_EXTENDED } } + { name, NULL, -1, { pattern, REG_EXTENDED } } static struct userdiff_driver builtin_drivers[] = { FUNCNAME("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$"), FUNCNAME("java", @@ -32,22 +32,23 @@ FUNCNAME("python", "^[ \t]*((class|def)[ \t].*)$"), FUNCNAME("ruby", "^[ \t]*((class|module|def)[ \t].*)$"), FUNCNAME("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$"), FUNCNAME("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$"), +{ "default", NULL, -1, { NULL, 0 } }, }; #undef FUNCNAME static struct userdiff_driver driver_true = { "diff=true", NULL, + 0, { NULL, 0 } }; -struct userdiff_driver *USERDIFF_ATTR_TRUE = &driver_true; static struct userdiff_driver driver_false = { "!diff", NULL, + 1, { NULL, 0 } }; -struct userdiff_driver *USERDIFF_ATTR_FALSE = &driver_false; static struct userdiff_driver *userdiff_find_by_namelen(const char *k, int len) { @@ -89,6 +90,7 @@ static struct userdiff_driver *parse_driver(const char *var, drv = &drivers[ndrivers++]; memset(drv, 0, sizeof(*drv)); drv->name = xmemdupz(name, namelen); + drv->binary = -1; } return drv; } @@ -109,6 +111,15 @@ static int parse_string(const char **d, const char *k, const char *v) return 1; } +static int parse_tristate(int *b, const char *k, const char *v) +{ + if (v && !strcasecmp(v, "auto")) + *b = -1; + else + *b = git_config_bool(k, v); + return 1; +} + int userdiff_config_basic(const char *k, const char *v) { struct userdiff_driver *drv; @@ -117,6 +128,8 @@ int userdiff_config_basic(const char *k, const char *v) return parse_funcname(&drv->funcname, k, v, 0); if ((drv = parse_driver(k, v, "xfuncname"))) return parse_funcname(&drv->funcname, k, v, REG_EXTENDED); + if ((drv = parse_driver(k, v, "binary"))) + return parse_tristate(&drv->binary, k, v); return 0; } diff --git a/userdiff.h b/userdiff.h index c64c5f5669..1c1eb042b4 100644 --- a/userdiff.h +++ b/userdiff.h @@ -9,12 +9,10 @@ struct userdiff_funcname { struct userdiff_driver { const char *name; const char *external; + int binary; struct userdiff_funcname funcname; }; -extern struct userdiff_driver *USERDIFF_ATTR_TRUE; -extern struct userdiff_driver *USERDIFF_ATTR_FALSE; - int userdiff_config_basic(const char *k, const char *v); int userdiff_config_porcelain(const char *k, const char *v); struct userdiff_driver *userdiff_find_by_name(const char *name); -- cgit v1.3 From 9cb92c390cefd3bf3f71bbda12eb04893c861361 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 5 Oct 2008 17:43:45 -0400 Subject: diff: add filter for converting binary to text When diffing binary files, it is sometimes nice to see the differences of a canonical text form rather than either a binary patch or simply "binary files differ." Until now, the only option for doing this was to define an external diff command to perform the diff. This was a lot of work, since the external command needed to take care of doing the diff itself (including mode changes), and lost the benefit of git's colorization and other options. This patch adds a text conversion option, which converts a file to its canonical format before performing the diff. This is less flexible than an arbitrary external diff, but is much less work to set up. For example: $ echo '*.jpg diff=exif' >>.gitattributes $ git config diff.exif.textconv exiftool $ git config diff.exif.binary false allows one to see jpg diffs represented by the text output of exiftool. Signed-off-by: Jeff King Signed-off-by: Shawn O. Pearce --- diff.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- userdiff.c | 2 ++ userdiff.h | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) (limited to 'userdiff.c') diff --git a/diff.c b/diff.c index dabd7f50ec..e368fef14f 100644 --- a/diff.c +++ b/diff.c @@ -38,6 +38,9 @@ static char diff_colors[][COLOR_MAXLEN] = { "\033[41m", /* WHITESPACE (red background) */ }; +static void diff_filespec_load_driver(struct diff_filespec *one); +static char *run_textconv(const char *, struct diff_filespec *, size_t *); + static int parse_diff_color_slot(const char *var, int ofs) { if (!strcasecmp(var+ofs, "plain")) @@ -290,8 +293,19 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one) } else if (diff_populate_filespec(one, 0)) return -1; - mf->ptr = one->data; - mf->size = one->size; + + diff_filespec_load_driver(one); + if (one->driver->textconv) { + size_t size; + mf->ptr = run_textconv(one->driver->textconv, one, &size); + if (!mf->ptr) + return -1; + mf->size = size; + } + else { + mf->ptr = one->data; + mf->size = one->size; + } return 0; } @@ -3373,3 +3387,34 @@ void diff_unmerge(struct diff_options *options, fill_filespec(one, sha1, mode); diff_queue(&diff_queued_diff, one, two)->is_unmerged = 1; } + +static char *run_textconv(const char *pgm, struct diff_filespec *spec, + size_t *outsize) +{ + struct diff_tempfile temp; + const char *argv[3]; + const char **arg = argv; + struct child_process child; + struct strbuf buf = STRBUF_INIT; + + prepare_temp_file(spec->path, &temp, spec); + *arg++ = pgm; + *arg++ = temp.name; + *arg = NULL; + + memset(&child, 0, sizeof(child)); + child.argv = argv; + child.out = -1; + if (start_command(&child) != 0 || + strbuf_read(&buf, child.out, 0) < 0 || + finish_command(&child) != 0) { + if (temp.name == temp.tmp_path) + unlink(temp.name); + error("error running textconv command '%s'", pgm); + return NULL; + } + if (temp.name == temp.tmp_path) + unlink(temp.name); + + return strbuf_detach(&buf, outsize); +} diff --git a/userdiff.c b/userdiff.c index 58478a6912..d95257ab3b 100644 --- a/userdiff.c +++ b/userdiff.c @@ -140,6 +140,8 @@ int userdiff_config_porcelain(const char *k, const char *v) if ((drv = parse_driver(k, v, "command"))) return parse_string(&drv->external, k, v); + if ((drv = parse_driver(k, v, "textconv"))) + return parse_string(&drv->textconv, k, v); return 0; } diff --git a/userdiff.h b/userdiff.h index 1c1eb042b4..f29c18ffb3 100644 --- a/userdiff.h +++ b/userdiff.h @@ -11,6 +11,7 @@ struct userdiff_driver { const char *external; int binary; struct userdiff_funcname funcname; + const char *textconv; }; int userdiff_config_basic(const char *k, const char *v); -- cgit v1.3 From c7534ef4a12bb44806d522fc8e3961e390f9169b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 26 Oct 2008 00:45:55 -0400 Subject: userdiff: require explicitly allowing textconv Diffs that have been produced with textconv almost certainly cannot be applied, so we want to be careful not to generate them in things like format-patch. This introduces a new diff options, ALLOW_TEXTCONV, which controls this behavior. It is off by default, but is explicitly turned on for the "log" family of commands, as well as the "diff" porcelain (but not diff-* plumbing). Because both text conversion and external diffing are controlled by these diff options, we can get rid of the "plumbing versus porcelain" distinction when reading the config. This was an attempt to control the same thing, but suffered from being too coarse-grained. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-diff.c | 1 + builtin-log.c | 1 + diff.c | 26 +++++++++++--------------- diff.h | 1 + t/t4030-diff-textconv.sh | 2 +- userdiff.c | 10 +--------- userdiff.h | 3 +-- 7 files changed, 17 insertions(+), 27 deletions(-) (limited to 'userdiff.c') diff --git a/builtin-diff.c b/builtin-diff.c index 9c8c295732..2de5834c11 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -300,6 +300,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) } DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL); DIFF_OPT_SET(&rev.diffopt, RECURSIVE); + DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV); /* * If the user asked for our exit code then don't start a diff --git a/builtin-log.c b/builtin-log.c index a0944f70a4..75d698f0ce 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -59,6 +59,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, } else die("unrecognized argument: %s", arg); } + DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV); } /* diff --git a/diff.c b/diff.c index 6f01595ece..608223ab56 100644 --- a/diff.c +++ b/diff.c @@ -93,12 +93,6 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) if (!strcmp(var, "diff.external")) return git_config_string(&external_diff_cmd_cfg, var, value); - switch (userdiff_config_porcelain(var, value)) { - case 0: break; - case -1: return -1; - default: return 0; - } - return git_diff_basic_config(var, value, cb); } @@ -109,6 +103,12 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) return 0; } + switch (userdiff_config(var, value)) { + case 0: break; + case -1: return -1; + default: return 0; + } + if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) { int slot = parse_diff_color_slot(var, 11); if (!value) @@ -123,12 +123,6 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) return 0; } - switch (userdiff_config_basic(var, value)) { - case 0: break; - case -1: return -1; - default: return 0; - } - return git_color_default_config(var, value, cb); } @@ -1335,7 +1329,7 @@ static void builtin_diff(const char *name_a, const char *set = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); const char *a_prefix, *b_prefix; - const char *textconv_one, *textconv_two; + const char *textconv_one = NULL, *textconv_two = NULL; diff_set_mnemonic_prefix(o, "a/", "b/"); if (DIFF_OPT_TST(o, REVERSE_DIFF)) { @@ -1389,8 +1383,10 @@ static void builtin_diff(const char *name_a, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - textconv_one = get_textconv(one); - textconv_two = get_textconv(two); + if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) { + textconv_one = get_textconv(one); + textconv_two = get_textconv(two); + } if (!DIFF_OPT_TST(o, TEXT) && ( (diff_filespec_is_binary(one) && !textconv_one) || diff --git a/diff.h b/diff.h index a49d865bd9..42582edee6 100644 --- a/diff.h +++ b/diff.h @@ -65,6 +65,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_OPT_IGNORE_SUBMODULES (1 << 18) #define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19) #define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20) +#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21) #define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) #define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) #define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index 090a21d0b5..1df48ae12a 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -70,7 +70,7 @@ test_expect_success 'log produces text' ' test_cmp expect.text actual ' -test_expect_failure 'format-patch produces binary' ' +test_expect_success 'format-patch produces binary' ' git format-patch --no-binary --stdout HEAD^ >patch && find_diff actual && test_cmp expect.binary actual diff --git a/userdiff.c b/userdiff.c index d95257ab3b..3681062ebf 100644 --- a/userdiff.c +++ b/userdiff.c @@ -120,7 +120,7 @@ static int parse_tristate(int *b, const char *k, const char *v) return 1; } -int userdiff_config_basic(const char *k, const char *v) +int userdiff_config(const char *k, const char *v) { struct userdiff_driver *drv; @@ -130,14 +130,6 @@ int userdiff_config_basic(const char *k, const char *v) return parse_funcname(&drv->funcname, k, v, REG_EXTENDED); if ((drv = parse_driver(k, v, "binary"))) return parse_tristate(&drv->binary, k, v); - - return 0; -} - -int userdiff_config_porcelain(const char *k, const char *v) -{ - struct userdiff_driver *drv; - if ((drv = parse_driver(k, v, "command"))) return parse_string(&drv->external, k, v); if ((drv = parse_driver(k, v, "textconv"))) diff --git a/userdiff.h b/userdiff.h index f29c18ffb3..ba2945770b 100644 --- a/userdiff.h +++ b/userdiff.h @@ -14,8 +14,7 @@ struct userdiff_driver { const char *textconv; }; -int userdiff_config_basic(const char *k, const char *v); -int userdiff_config_porcelain(const char *k, const char *v); +int userdiff_config(const char *k, const char *v); struct userdiff_driver *userdiff_find_by_name(const char *name); struct userdiff_driver *userdiff_find_by_path(const char *path); -- cgit v1.3 From 80c49c3de2d5a3aa12b0980a65f1163c8aef0c16 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sat, 17 Jan 2009 17:29:48 +0100 Subject: color-words: make regex configurable via attributes Make the --color-words splitting regular expression configurable via the diff driver's 'wordregex' attribute. The user can then set the driver on a file in .gitattributes. If a regex is given on the command line, it overrides the driver's setting. We also provide built-in regexes for the languages that already had funcname patterns, and add an appropriate diff driver entry for C/++. (The patterns are designed to run UTF-8 sequences into a single chunk to make sure they remain readable.) Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 4 +++ Documentation/gitattributes.txt | 21 +++++++++++ diff.c | 10 ++++++ t/t4034-diff-words.sh | 36 +++++++++++++++++++ userdiff.c | 78 +++++++++++++++++++++++++++++++++-------- userdiff.h | 1 + 6 files changed, 135 insertions(+), 15 deletions(-) (limited to 'userdiff.c') diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 8689a92d8d..1edb82e8e1 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -102,6 +102,10 @@ differences. You may want to append `|[^[:space:]]` to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline. ++ +The regex can also be set via a diff driver, see +linkgit:gitattributes[1]; giving it explicitly overrides any diff +driver setting. --no-renames:: Turn off rename detection, even when the configuration diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 8af22eccac..ba3ba12730 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -317,6 +317,8 @@ patterns are available: - `bibtex` suitable for files with BibTeX coded references. +- `cpp` suitable for source code in the C and C++ languages. + - `html` suitable for HTML/XHTML documents. - `java` suitable for source code in the Java language. @@ -334,6 +336,25 @@ patterns are available: - `tex` suitable for source code for LaTeX documents. +Customizing word diff +^^^^^^^^^^^^^^^^^^^^^ + +You can customize the rules that `git diff --color-words` uses to +split words in a line, by specifying an appropriate regular expression +in the "diff.*.wordregex" configuration variable. For example, in TeX +a backslash followed by a sequence of letters forms a command, but +several such commands can be run together without intervening +whitespace. To separate them, use a regular expression such as + +------------------------ +[diff "tex"] + wordregex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+" +------------------------ + +A built-in pattern is provided for all languages listed in the +previous section. + + Performing text diffs of binary files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/diff.c b/diff.c index 00c661f82e..9fcde963db 100644 --- a/diff.c +++ b/diff.c @@ -1380,6 +1380,12 @@ static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespe return one->driver->funcname.pattern ? &one->driver->funcname : NULL; } +static const char *userdiff_word_regex(struct diff_filespec *one) +{ + diff_filespec_load_driver(one); + return one->driver->word_regex; +} + void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b) { if (!options->a_prefix) @@ -1540,6 +1546,10 @@ static void builtin_diff(const char *name_a, ecbdata.diff_words = xcalloc(1, sizeof(struct diff_words_data)); ecbdata.diff_words->file = o->file; + if (!o->word_regex) + o->word_regex = userdiff_word_regex(one); + if (!o->word_regex) + o->word_regex = userdiff_word_regex(two); if (o->word_regex) { ecbdata.diff_words->word_regex = (regex_t *) xmalloc(sizeof(regex_t)); diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 4873486301..744221bef9 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -84,6 +84,41 @@ test_expect_success 'word diff with a regular expression' ' ' +test_expect_success 'set a diff driver' ' + git config diff.testdriver.wordregex "[^[:space:]]" && + cat < .gitattributes +pre diff=testdriver +post diff=testdriver +EOF +' + +test_expect_success 'option overrides default' ' + + word_diff --color-words="[a-z]+" + +' + +cat > expect <<\EOF +diff --git a/pre b/post +index 330b04f..5ed8eff 100644 +--- a/pre ++++ b/post +@@ -1,3 +1,7 @@ +h(4),hh[44] + +a = b + c + +aa = a + +aeff = aeff * ( aaa ) +EOF + +test_expect_success 'use default supplied by driver' ' + + word_diff --color-words + +' + echo 'aaa (aaa)' > pre echo 'aaa (aaa) aaa' > post @@ -100,6 +135,7 @@ test_expect_success 'test parsing words for newline' ' word_diff --color-words="a+" + ' echo '(:' > pre diff --git a/userdiff.c b/userdiff.c index 3681062ebf..2b55509485 100644 --- a/userdiff.c +++ b/userdiff.c @@ -6,14 +6,20 @@ static struct userdiff_driver *drivers; static int ndrivers; static int drivers_alloc; -#define FUNCNAME(name, pattern) \ - { name, NULL, -1, { pattern, REG_EXTENDED } } +#define PATTERNS(name, pattern, wordregex) \ + { name, NULL, -1, { pattern, REG_EXTENDED }, wordregex } static struct userdiff_driver builtin_drivers[] = { -FUNCNAME("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$"), -FUNCNAME("java", +PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$", + "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"), +PATTERNS("java", "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n" - "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$"), -FUNCNAME("objc", + "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$", + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?" + "|[-+*/<>%&^|=!]=" + "|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|" + "|[^[:space:]]|[\x80-\xff]+"), +PATTERNS("objc", /* Negate C statements that can look like functions */ "!^[ \t]*(do|for|if|else|return|switch|while)\n" /* Objective-C methods */ @@ -21,20 +27,60 @@ FUNCNAME("objc", /* C functions */ "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n" /* Objective-C class/protocol definitions */ - "^(@(implementation|interface|protocol)[ \t].*)$"), -FUNCNAME("pascal", + "^(@(implementation|interface|protocol)[ \t].*)$", + /* -- */ + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?" + "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->" + "|[^[:space:]]|[\x80-\xff]+"), +PATTERNS("pascal", "^((procedure|function|constructor|destructor|interface|" "implementation|initialization|finalization)[ \t]*.*)$" "\n" - "^(.*=[ \t]*(class|record).*)$"), -FUNCNAME("php", "^[\t ]*((function|class).*)"), -FUNCNAME("python", "^[ \t]*((class|def)[ \t].*)$"), -FUNCNAME("ruby", "^[ \t]*((class|module|def)[ \t].*)$"), -FUNCNAME("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$"), -FUNCNAME("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$"), + "^(.*=[ \t]*(class|record).*)$", + /* -- */ + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+" + "|<>|<=|>=|:=|\\.\\." + "|[^[:space:]]|[\x80-\xff]+"), +PATTERNS("php", "^[\t ]*((function|class).*)", + /* -- */ + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+" + "|[-+*/<>%&^|=!.]=|--|\\+\\+|<<=?|>>=?|===|&&|\\|\\||::|->" + "|[^[:space:]]|[\x80-\xff]+"), +PATTERNS("python", "^[ \t]*((class|def)[ \t].*)$", + /* -- */ + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?" + "|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?" + "|[^[:space:]|[\x80-\xff]+"), + /* -- */ +PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$", + /* -- */ + "(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?." + "|//=?|[-+*/<>%&^|=!]=|<<=?|>>=?|===|\\.{1,3}|::|[!=]~" + "|[^[:space:]|[\x80-\xff]+"), +PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$", + "[={}\"]|[^={}\" \t]+"), +PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$", + "\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+|[^[:space:]]"), +PATTERNS("cpp", + /* Jump targets or access declarations */ + "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n" + /* C/++ functions/methods at top level */ + "^([A-Za-z_][A-Za-z_0-9]*([ \t]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n" + /* compound type at top level */ + "^((struct|class|enum)[^;]*)$", + /* -- */ + "[a-zA-Z_][a-zA-Z0-9_]*" + "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?" + "|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->" + "|[^[:space:]]|[\x80-\xff]+"), { "default", NULL, -1, { NULL, 0 } }, }; -#undef FUNCNAME +#undef PATTERNS static struct userdiff_driver driver_true = { "diff=true", @@ -134,6 +180,8 @@ int userdiff_config(const char *k, const char *v) return parse_string(&drv->external, k, v); if ((drv = parse_driver(k, v, "textconv"))) return parse_string(&drv->textconv, k, v); + if ((drv = parse_driver(k, v, "wordregex"))) + return parse_string(&drv->word_regex, k, v); return 0; } diff --git a/userdiff.h b/userdiff.h index ba2945770b..c3151594f5 100644 --- a/userdiff.h +++ b/userdiff.h @@ -11,6 +11,7 @@ struct userdiff_driver { const char *external; int binary; struct userdiff_funcname funcname; + const char *word_regex; const char *textconv; }; -- cgit v1.3 From ae3b970ac3e21324a95fea75213c2569180d74c6 Mon Sep 17 00:00:00 2001 From: Boyd Stephen Smith Jr Date: Tue, 20 Jan 2009 22:59:54 -0600 Subject: Change the spelling of "wordregex". Use "wordRegex" for configuration variable names. Use "word_regex" for C language tokens. Signed-off-by: Boyd Stephen Smith Jr. Signed-off-by: Junio C Hamano --- Documentation/config.txt | 2 +- Documentation/gitattributes.txt | 4 ++-- t/t4034-diff-words.sh | 8 ++++---- userdiff.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'userdiff.c') diff --git a/Documentation/config.txt b/Documentation/config.txt index 0ca983ac3b..332213e65d 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -639,7 +639,7 @@ diff.suppress-blank-empty:: A boolean to inhibit the standard behavior of printing a space before each empty output line. Defaults to false. -diff.wordregex:: +diff.wordRegex:: A POSIX Extended Regular Expression used to determine what is a "word" when performing word-by-word difference calculations. Character sequences that match the regular expression are "words", all other diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index ba3ba12730..227934f59a 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -341,14 +341,14 @@ Customizing word diff You can customize the rules that `git diff --color-words` uses to split words in a line, by specifying an appropriate regular expression -in the "diff.*.wordregex" configuration variable. For example, in TeX +in the "diff.*.wordRegex" configuration variable. For example, in TeX a backslash followed by a sequence of letters forms a command, but several such commands can be run together without intervening whitespace. To separate them, use a regular expression such as ------------------------ [diff "tex"] - wordregex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+" + wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+" ------------------------ A built-in pattern is provided for all languages listed in the diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 6bcc153084..4508effcaa 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -86,7 +86,7 @@ test_expect_success 'word diff with a regular expression' ' ' test_expect_success 'set a diff driver' ' - git config diff.testdriver.wordregex "[^[:space:]]" && + git config diff.testdriver.wordRegex "[^[:space:]]" && cat < .gitattributes pre diff=testdriver post diff=testdriver @@ -121,8 +121,8 @@ test_expect_success 'use regex supplied by driver' ' ' -test_expect_success 'set diff.wordregex option' ' - git config diff.wordregex "[[:alnum:]]+" +test_expect_success 'set diff.wordRegex option' ' + git config diff.wordRegex "[[:alnum:]]+" ' cp expect.letter-runs-are-words expect @@ -138,7 +138,7 @@ test_expect_success '.gitattributes override config' ' ' test_expect_success 'remove diff driver regex' ' - git config --unset diff.testdriver.wordregex + git config --unset diff.testdriver.wordRegex ' cat > expect <<\EOF diff --git a/userdiff.c b/userdiff.c index 2b55509485..d556da9751 100644 --- a/userdiff.c +++ b/userdiff.c @@ -6,8 +6,8 @@ static struct userdiff_driver *drivers; static int ndrivers; static int drivers_alloc; -#define PATTERNS(name, pattern, wordregex) \ - { name, NULL, -1, { pattern, REG_EXTENDED }, wordregex } +#define PATTERNS(name, pattern, word_regex) \ + { name, NULL, -1, { pattern, REG_EXTENDED }, word_regex } static struct userdiff_driver builtin_drivers[] = { PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$", "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"), -- cgit v1.3 From 959e2e64a594e2fb8de2585078e31b07a8da6fc9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 17 Jun 2009 16:26:06 +0200 Subject: avoid exponential regex match for java and objc function names In the old regex ^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\([^;]*)$ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ you can backtrack arbitrarily from [A-Za-z_0-9]* into [A-Za-z_], thus causing an exponential number of backtracks. Ironically it also causes the regex not to work as intended; for example "catch" can match the underlined part of the regex, the first repetition matching "c" and the second matching "atch". The replacement regex avoids this problem, because it makes sure that at least a space/tab is eaten on each repetition. In other words, a suffix of a repetition can never be a prefix of the next repetition. Signed-off-by: Paolo Bonzini Signed-off-by: Junio C Hamano --- userdiff.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'userdiff.c') diff --git a/userdiff.c b/userdiff.c index d556da9751..57529ae63d 100644 --- a/userdiff.c +++ b/userdiff.c @@ -13,7 +13,8 @@ PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$", "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"), PATTERNS("java", "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n" - "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$", + "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$", + /* -- */ "[a-zA-Z_][a-zA-Z0-9_]*" "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?" "|[-+*/<>%&^|=!]=" @@ -25,7 +26,7 @@ PATTERNS("objc", /* Objective-C methods */ "^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n" /* C functions */ - "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n" + "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n" /* Objective-C class/protocol definitions */ "^(@(implementation|interface|protocol)[ \t].*)$", /* -- */ -- cgit v1.3 From 7fb0eaa289576a1dcd7751015ba791f1bce778a9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 16 Jan 2010 20:39:59 -0800 Subject: git_attr(): fix function signature The function took (name, namelen) as its arguments, but all the public callers wanted to pass a full string. Demote the counted-string interface to an internal API status, and allow public callers to just pass the string to the function. Signed-off-by: Junio C Hamano --- archive.c | 4 ++-- attr.c | 11 ++++++++--- attr.h | 2 +- builtin-check-attr.c | 2 +- builtin-pack-objects.c | 2 +- convert.c | 6 +++--- ll-merge.c | 2 +- userdiff.c | 2 +- ws.c | 2 +- 9 files changed, 19 insertions(+), 14 deletions(-) (limited to 'userdiff.c') diff --git a/archive.c b/archive.c index 55b273246e..a9ebdc5d54 100644 --- a/archive.c +++ b/archive.c @@ -87,8 +87,8 @@ static void setup_archive_check(struct git_attr_check *check) static struct git_attr *attr_export_subst; if (!attr_export_ignore) { - attr_export_ignore = git_attr("export-ignore", 13); - attr_export_subst = git_attr("export-subst", 12); + attr_export_ignore = git_attr("export-ignore"); + attr_export_subst = git_attr("export-subst"); } check[0].attr = attr_export_ignore; check[1].attr = attr_export_subst; diff --git a/attr.c b/attr.c index 55bdb7cdeb..f5346ed32a 100644 --- a/attr.c +++ b/attr.c @@ -65,7 +65,7 @@ static int invalid_attr_name(const char *name, int namelen) return 0; } -struct git_attr *git_attr(const char *name, int len) +static struct git_attr *git_attr_internal(const char *name, int len) { unsigned hval = hash_name(name, len); unsigned pos = hval % HASHSIZE; @@ -95,6 +95,11 @@ struct git_attr *git_attr(const char *name, int len) return a; } +struct git_attr *git_attr(const char *name) +{ + return git_attr_internal(name, strlen(name)); +} + /* * .gitattributes file is one line per record, each of which is * @@ -162,7 +167,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp, else { e->setto = xmemdupz(equals + 1, ep - equals - 1); } - e->attr = git_attr(cp, len); + e->attr = git_attr_internal(cp, len); } (*num_attr)++; return ep + strspn(ep, blank); @@ -221,7 +226,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, sizeof(struct attr_state) * num_attr + (is_macro ? 0 : namelen + 1)); if (is_macro) - res->u.attr = git_attr(name, namelen); + res->u.attr = git_attr_internal(name, namelen); else { res->u.pattern = (char *)&(res->state[num_attr]); memcpy(res->u.pattern, name, namelen); diff --git a/attr.h b/attr.h index 69b5767ebc..450f49d648 100644 --- a/attr.h +++ b/attr.h @@ -8,7 +8,7 @@ struct git_attr; * Given a string, return the gitattribute object that * corresponds to it. */ -struct git_attr *git_attr(const char *, int); +struct git_attr *git_attr(const char *); /* Internal use */ extern const char git_attr__true[]; diff --git a/builtin-check-attr.c b/builtin-check-attr.c index 8bd0430098..3016d29caa 100644 --- a/builtin-check-attr.c +++ b/builtin-check-attr.c @@ -106,7 +106,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) const char *name; struct git_attr *a; name = argv[i]; - a = git_attr(name, strlen(name)); + a = git_attr(name); if (!a) return error("%s: not a valid attribute name", name); check[i].attr = a; diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 4429d53a1e..9beff352d5 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -673,7 +673,7 @@ static void setup_delta_attr_check(struct git_attr_check *check) static struct git_attr *attr_delta; if (!attr_delta) - attr_delta = git_attr("delta", 5); + attr_delta = git_attr("delta"); check[0].attr = attr_delta; } diff --git a/convert.c b/convert.c index 491e7141b4..852fd6488a 100644 --- a/convert.c +++ b/convert.c @@ -377,9 +377,9 @@ static void setup_convert_check(struct git_attr_check *check) static struct git_attr *attr_filter; if (!attr_crlf) { - attr_crlf = git_attr("crlf", 4); - attr_ident = git_attr("ident", 5); - attr_filter = git_attr("filter", 6); + attr_crlf = git_attr("crlf"); + attr_ident = git_attr("ident"); + attr_filter = git_attr("filter"); user_convert_tail = &user_convert; git_config(read_convert_config, NULL); } diff --git a/ll-merge.c b/ll-merge.c index 2d6b6d6cb1..f4b0a07377 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -344,7 +344,7 @@ static const char *git_path_check_merge(const char *path) static struct git_attr_check attr_merge_check; if (!attr_merge_check.attr) - attr_merge_check.attr = git_attr("merge", 5); + attr_merge_check.attr = git_attr("merge"); if (git_checkattr(path, 1, &attr_merge_check)) return NULL; diff --git a/userdiff.c b/userdiff.c index 57529ae63d..df992490d5 100644 --- a/userdiff.c +++ b/userdiff.c @@ -198,7 +198,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path) struct git_attr_check check; if (!attr) - attr = git_attr("diff", 4); + attr = git_attr("diff"); check.attr = attr; if (!path) diff --git a/ws.c b/ws.c index 760b5743fa..c0893386e6 100644 --- a/ws.c +++ b/ws.c @@ -64,7 +64,7 @@ static void setup_whitespace_attr_check(struct git_attr_check *check) static struct git_attr *attr_whitespace; if (!attr_whitespace) - attr_whitespace = git_attr("whitespace", 10); + attr_whitespace = git_attr("whitespace"); check[0].attr = attr_whitespace; } -- cgit v1.3