提交 9800c0df 编写于 作者: S Shawn O. Pearce

Merge branch 'bc/master-diff-hunk-header-fix'

* bc/master-diff-hunk-header-fix:
  Clarify commit error message for unmerged files
  Use strchrnul() instead of strchr() plus manual workaround
  Use remove_path from dir.c instead of own implementation
  Add remove_path: a function to remove as much as possible of a path
  git-submodule: Fix "Unable to checkout" for the initial 'update'
  Clarify how the user can satisfy stash's 'dirty state' check.
  t4018-diff-funcname: test syntax of builtin xfuncname patterns
  t4018-diff-funcname: test syntax of builtin xfuncname patterns
  make "git remote" report multiple URLs
  diff hunk pattern: fix misconverted "\{" tex macro introducers
  diff: fix "multiple regexp" semantics to find hunk header comment
  diff: use extended regexp to find hunk headers
  diff: use extended regexp to find hunk headers
  diff.*.xfuncname which uses "extended" regex's for hunk header selection
  diff.c: associate a flag with each pattern and use it for compiling regex
  diff.c: return pattern entry pointer rather than just the hunk header pattern

Conflicts:
	builtin-merge-recursive.c
	t/t7201-co.sh
	xdiff-interface.h
...@@ -288,13 +288,13 @@ for paths. ...@@ -288,13 +288,13 @@ for paths.
*.tex diff=tex *.tex diff=tex
------------------------ ------------------------
Then, you would define a "diff.tex.funcname" configuration to Then, you would define a "diff.tex.xfuncname" configuration to
specify a regular expression that matches a line that you would specify a regular expression that matches a line that you would
want to appear as the hunk header "TEXT", like this: want to appear as the hunk header "TEXT", like this:
------------------------ ------------------------
[diff "tex"] [diff "tex"]
funcname = "^\\(\\\\\\(sub\\)*section{.*\\)$" xfuncname = "^(\\\\(sub)*section\\{.*)$"
------------------------ ------------------------
Note. A single level of backslashes are eaten by the Note. A single level of backslashes are eaten by the
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "delta.h" #include "delta.h"
#include "builtin.h" #include "builtin.h"
#include "string-list.h" #include "string-list.h"
#include "dir.h"
/* /*
* --check turns on checking that the working tree matches the * --check turns on checking that the working tree matches the
...@@ -2735,15 +2736,7 @@ static void remove_file(struct patch *patch, int rmdir_empty) ...@@ -2735,15 +2736,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)
warning("unable to remove submodule %s", warning("unable to remove submodule %s",
patch->old_name); patch->old_name);
} else if (!unlink(patch->old_name) && rmdir_empty) { } else if (!unlink(patch->old_name) && rmdir_empty) {
char *name = xstrdup(patch->old_name); remove_path(patch->old_name);
char *end = strrchr(name, '/');
while (end) {
*end = 0;
if (rmdir(name))
break;
end = strrchr(name, '/');
}
free(name);
} }
} }
} }
......
...@@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) ...@@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
active_cache_tree = cache_tree(); active_cache_tree = cache_tree();
if (cache_tree_update(active_cache_tree, if (cache_tree_update(active_cache_tree,
active_cache, active_nr, 0, 0) < 0) { active_cache, active_nr, 0, 0) < 0) {
error("Error building trees"); error("Error building trees; the index is unmerged?");
return 0; return 0;
} }
......
...@@ -320,9 +320,7 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un ...@@ -320,9 +320,7 @@ static const char *find_wholine(const char *who, int wholen, const char *buf, un
static const char *copy_line(const char *buf) static const char *copy_line(const char *buf)
{ {
const char *eol = strchr(buf, '\n'); const char *eol = strchrnul(buf, '\n');
if (!eol) // simulate strchrnul()
eol = buf + strlen(buf);
return xmemdupz(buf, eol - buf); return xmemdupz(buf, eol - buf);
} }
......
...@@ -650,10 +650,13 @@ static int get_one_entry(struct remote *remote, void *priv) ...@@ -650,10 +650,13 @@ static int get_one_entry(struct remote *remote, void *priv)
{ {
struct string_list *list = priv; struct string_list *list = priv;
string_list_append(remote->name, list)->util = remote->url_nr ? if (remote->url_nr > 0) {
(void *)remote->url[0] : NULL; int i;
if (remote->url_nr > 1)
warning("Remote %s has more than one URL", remote->name); for (i = 0; i < remote->url_nr; i++)
string_list_append(remote->name, list)->util = (void *)remote->url[i];
} else
string_list_append(remote->name, list)->util = NULL;
return 0; return 0;
} }
...@@ -669,10 +672,14 @@ static int show_all(void) ...@@ -669,10 +672,14 @@ static int show_all(void)
sort_string_list(&list); sort_string_list(&list);
for (i = 0; i < list.nr; i++) { for (i = 0; i < list.nr; i++) {
struct string_list_item *item = list.items + i; struct string_list_item *item = list.items + i;
printf("%s%s%s\n", item->string, if (verbose)
verbose ? "\t" : "", printf("%s\t%s\n", item->string,
verbose && item->util ? item->util ? (const char *)item->util : "");
(const char *)item->util : ""); else {
if (i && !strcmp((item - 1)->string, item->string))
continue;
printf("%s\n", item->string);
}
} }
} }
return result; return result;
......
...@@ -29,26 +29,6 @@ static void add_list(const char *name) ...@@ -29,26 +29,6 @@ static void add_list(const char *name)
list.name[list.nr++] = name; list.name[list.nr++] = name;
} }
static int remove_file(const char *name)
{
int ret;
char *slash;
ret = unlink(name);
if (ret && errno == ENOENT)
/* The user has removed it from the filesystem by hand */
ret = errno = 0;
if (!ret && (slash = strrchr(name, '/'))) {
char *n = xstrdup(name);
do {
n[slash - name] = 0;
name = n;
} while (!rmdir(name) && (slash = strrchr(name, '/')));
}
return ret;
}
static int check_local_mod(unsigned char *head, int index_only) static int check_local_mod(unsigned char *head, int index_only)
{ {
/* items in list are already sorted in the cache order, /* items in list are already sorted in the cache order,
...@@ -239,7 +219,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) ...@@ -239,7 +219,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
int removed = 0; int removed = 0;
for (i = 0; i < list.nr; i++) { for (i = 0; i < list.nr; i++) {
const char *path = list.name[i]; const char *path = list.name[i];
if (!remove_file(path)) { if (!remove_path(path)) {
removed = 1; removed = 1;
continue; continue;
} }
......
...@@ -96,32 +96,37 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val ...@@ -96,32 +96,37 @@ static int parse_lldiff_command(const char *var, const char *ep, const char *val
* to define a customized regexp to find the beginning of a function to * to define a customized regexp to find the beginning of a function to
* be used for hunk header lines of "diff -p" style output. * be used for hunk header lines of "diff -p" style output.
*/ */
static struct funcname_pattern { struct funcname_pattern_entry {
char *name; char *name;
char *pattern; char *pattern;
struct funcname_pattern *next; int cflags;
};
static struct funcname_pattern_list {
struct funcname_pattern_list *next;
struct funcname_pattern_entry e;
} *funcname_pattern_list; } *funcname_pattern_list;
static int parse_funcname_pattern(const char *var, const char *ep, const char *value) static int parse_funcname_pattern(const char *var, const char *ep, const char *value, int cflags)
{ {
const char *name; const char *name;
int namelen; int namelen;
struct funcname_pattern *pp; struct funcname_pattern_list *pp;
name = var + 5; /* "diff." */ name = var + 5; /* "diff." */
namelen = ep - name; namelen = ep - name;
for (pp = funcname_pattern_list; pp; pp = pp->next) for (pp = funcname_pattern_list; pp; pp = pp->next)
if (!strncmp(pp->name, name, namelen) && !pp->name[namelen]) if (!strncmp(pp->e.name, name, namelen) && !pp->e.name[namelen])
break; break;
if (!pp) { if (!pp) {
pp = xcalloc(1, sizeof(*pp)); pp = xcalloc(1, sizeof(*pp));
pp->name = xmemdupz(name, namelen); pp->e.name = xmemdupz(name, namelen);
pp->next = funcname_pattern_list; pp->next = funcname_pattern_list;
funcname_pattern_list = pp; funcname_pattern_list = pp;
} }
free(pp->pattern); free(pp->e.pattern);
pp->pattern = xstrdup(value); pp->e.pattern = xstrdup(value);
pp->e.cflags = cflags;
return 0; return 0;
} }
...@@ -194,7 +199,13 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) ...@@ -194,7 +199,13 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
if (!strcmp(ep, ".funcname")) { if (!strcmp(ep, ".funcname")) {
if (!value) if (!value)
return config_error_nonbool(var); return config_error_nonbool(var);
return parse_funcname_pattern(var, ep, value); return parse_funcname_pattern(var, ep, value,
0);
} else if (!strcmp(ep, ".xfuncname")) {
if (!value)
return config_error_nonbool(var);
return parse_funcname_pattern(var, ep, value,
REG_EXTENDED);
} }
} }
} }
...@@ -1400,42 +1411,45 @@ int diff_filespec_is_binary(struct diff_filespec *one) ...@@ -1400,42 +1411,45 @@ int diff_filespec_is_binary(struct diff_filespec *one)
return one->is_binary; return one->is_binary;
} }
static const char *funcname_pattern(const char *ident) static const struct funcname_pattern_entry *funcname_pattern(const char *ident)
{ {
struct funcname_pattern *pp; struct funcname_pattern_list *pp;
for (pp = funcname_pattern_list; pp; pp = pp->next) for (pp = funcname_pattern_list; pp; pp = pp->next)
if (!strcmp(ident, pp->name)) if (!strcmp(ident, pp->e.name))
return pp->pattern; return &pp->e;
return NULL; return NULL;
} }
static struct builtin_funcname_pattern { static const struct funcname_pattern_entry builtin_funcname_pattern[] = {
const char *name; { "bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
const char *pattern; REG_EXTENDED },
} builtin_funcname_pattern[] = { { "html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$", REG_EXTENDED },
{ "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" }, { "java",
{ "html", "^\\s*\\(<[Hh][1-6]\\s.*>.*\\)$" }, "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
{ "java", "!^[ ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|" "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$",
"new\\|return\\|switch\\|throw\\|while\\)\n" REG_EXTENDED },
"^[ ]*\\(\\([ ]*" { "pascal",
"[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}" "^((procedure|function|constructor|destructor|interface|"
"[ ]*([^;]*\\)$" }, "implementation|initialization|finalization)[ \t]*.*)$"
{ "pascal", "^\\(\\(procedure\\|function\\|constructor\\|" "\n"
"destructor\\|interface\\|implementation\\|" "^(.*=[ \t]*(class|record).*)$",
"initialization\\|finalization\\)[ \t]*.*\\)$" REG_EXTENDED },
"\\|" { "php", "^[\t ]*((function|class).*)", REG_EXTENDED },
"^\\(.*=[ \t]*\\(class\\|record\\).*\\)$" { "python", "^[ \t]*((class|def)[ \t].*)$", REG_EXTENDED },
}, { "ruby", "^[ \t]*((class|module|def)[ \t].*)$",
{ "php", "^[\t ]*\\(\\(function\\|class\\).*\\)" }, REG_EXTENDED },
{ "python", "^\\s*\\(\\(class\\|def\\)\\s.*\\)$" }, { "bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
{ "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" }, REG_EXTENDED },
{ "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" }, { "tex",
"^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
REG_EXTENDED },
}; };
static const char *diff_funcname_pattern(struct diff_filespec *one) static const struct funcname_pattern_entry *diff_funcname_pattern(struct diff_filespec *one)
{ {
const char *ident, *pattern; const char *ident;
const struct funcname_pattern_entry *pe;
int i; int i;
diff_filespec_check_attr(one); diff_filespec_check_attr(one);
...@@ -1450,9 +1464,9 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) ...@@ -1450,9 +1464,9 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)
return funcname_pattern("default"); return funcname_pattern("default");
/* Look up custom "funcname.$ident" regexp from config. */ /* Look up custom "funcname.$ident" regexp from config. */
pattern = funcname_pattern(ident); pe = funcname_pattern(ident);
if (pattern) if (pe)
return pattern; return pe;
/* /*
* And define built-in fallback patterns here. Note that * And define built-in fallback patterns here. Note that
...@@ -1460,7 +1474,7 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) ...@@ -1460,7 +1474,7 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)
*/ */
for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++) for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++)
if (!strcmp(ident, builtin_funcname_pattern[i].name)) if (!strcmp(ident, builtin_funcname_pattern[i].name))
return builtin_funcname_pattern[i].pattern; return &builtin_funcname_pattern[i];
return NULL; return NULL;
} }
...@@ -1556,11 +1570,11 @@ static void builtin_diff(const char *name_a, ...@@ -1556,11 +1570,11 @@ static void builtin_diff(const char *name_a,
xdemitconf_t xecfg; xdemitconf_t xecfg;
xdemitcb_t ecb; xdemitcb_t ecb;
struct emit_callback ecbdata; struct emit_callback ecbdata;
const char *funcname_pattern; const struct funcname_pattern_entry *pe;
funcname_pattern = diff_funcname_pattern(one); pe = diff_funcname_pattern(one);
if (!funcname_pattern) if (!pe)
funcname_pattern = diff_funcname_pattern(two); pe = diff_funcname_pattern(two);
memset(&xecfg, 0, sizeof(xecfg)); memset(&xecfg, 0, sizeof(xecfg));
memset(&ecbdata, 0, sizeof(ecbdata)); memset(&ecbdata, 0, sizeof(ecbdata));
...@@ -1572,8 +1586,8 @@ static void builtin_diff(const char *name_a, ...@@ -1572,8 +1586,8 @@ static void builtin_diff(const char *name_a,
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context; xecfg.ctxlen = o->context;
xecfg.flags = XDL_EMIT_FUNCNAMES; xecfg.flags = XDL_EMIT_FUNCNAMES;
if (funcname_pattern) if (pe)
xdiff_set_find_func(&xecfg, funcname_pattern); xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
if (!diffopts) if (!diffopts)
; ;
else if (!prefixcmp(diffopts, "--unified=")) else if (!prefixcmp(diffopts, "--unified="))
......
...@@ -831,3 +831,23 @@ void setup_standard_excludes(struct dir_struct *dir) ...@@ -831,3 +831,23 @@ void setup_standard_excludes(struct dir_struct *dir)
if (excludes_file && !access(excludes_file, R_OK)) if (excludes_file && !access(excludes_file, R_OK))
add_excludes_from_file(dir, excludes_file); add_excludes_from_file(dir, excludes_file);
} }
int remove_path(const char *name)
{
char *slash;
if (unlink(name) && errno != ENOENT)
return -1;
slash = strrchr(name, '/');
if (slash) {
char *dirs = xstrdup(name);
slash = dirs + (slash - name);
do {
*slash = '\0';
} while (rmdir(dirs) && (slash = strrchr(dirs, '/')));
free(dirs);
}
return 0;
}
...@@ -81,4 +81,7 @@ extern int is_inside_dir(const char *dir); ...@@ -81,4 +81,7 @@ extern int is_inside_dir(const char *dir);
extern void setup_standard_excludes(struct dir_struct *dir); extern void setup_standard_excludes(struct dir_struct *dir);
extern int remove_dir_recursively(struct strbuf *path, int only_empty); extern int remove_dir_recursively(struct strbuf *path, int only_empty);
/* tries to remove the path with empty directories along it, ignores ENOENT */
extern int remove_path(const char *path);
#endif #endif
...@@ -161,7 +161,7 @@ show_stash () { ...@@ -161,7 +161,7 @@ show_stash () {
apply_stash () { apply_stash () {
git update-index -q --refresh && git update-index -q --refresh &&
git diff-files --quiet --ignore-submodules || git diff-files --quiet --ignore-submodules ||
die 'Cannot restore on top of a dirty state' die 'Cannot apply to a dirty working tree, please stage your changes'
unstash_index= unstash_index=
case "$1" in case "$1" in
......
...@@ -194,7 +194,7 @@ cmd_add() ...@@ -194,7 +194,7 @@ cmd_add()
else else
module_clone "$path" "$realrepo" || exit module_clone "$path" "$realrepo" || exit
(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || (unset GIT_DIR; cd "$path" && git checkout -f -q ${branch:+-b "$branch" "origin/$branch"}) ||
die "Unable to checkout submodule '$path'" die "Unable to checkout submodule '$path'"
fi fi
...@@ -340,8 +340,13 @@ cmd_update() ...@@ -340,8 +340,13 @@ cmd_update()
if test "$subsha1" != "$sha1" if test "$subsha1" != "$sha1"
then then
force=
if test -z "$subsha1"
then
force="-f"
fi
(unset GIT_DIR; cd "$path" && git-fetch && (unset GIT_DIR; cd "$path" && git-fetch &&
git-checkout -q "$sha1") || git-checkout $force -q "$sha1") ||
die "Unable to checkout '$sha1' in submodule path '$path'" die "Unable to checkout '$sha1' in submodule path '$path'"
say "Submodule path '$path': checked out '$sha1'" say "Submodule path '$path': checked out '$sha1'"
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "interpolate.h" #include "interpolate.h"
#include "attr.h" #include "attr.h"
#include "merge-recursive.h" #include "merge-recursive.h"
#include "dir.h"
static struct tree *shift_tree_object(struct tree *one, struct tree *two) static struct tree *shift_tree_object(struct tree *one, struct tree *two)
{ {
...@@ -392,22 +393,6 @@ static int update_stages(const char *path, struct diff_filespec *o, ...@@ -392,22 +393,6 @@ static int update_stages(const char *path, struct diff_filespec *o,
return 0; return 0;
} }
static int remove_path(const char *name)
{
char *slash, *dirs;
if (unlink(name))
return -1;
dirs = xstrdup(name);
while ((slash = strrchr(name, '/'))) {
*slash = '\0';
if (rmdir(name) != 0)
break;
}
free(dirs);
return 0;
}
static int remove_file(struct merge_options *o, int clean, static int remove_file(struct merge_options *o, int clean,
const char *path, int no_wd) const char *path, int no_wd)
{ {
......
...@@ -32,7 +32,18 @@ EOF ...@@ -32,7 +32,18 @@ EOF
sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java
builtin_patterns="bibtex html java pascal php python ruby tex"
for p in $builtin_patterns
do
test_expect_success "builtin $p pattern compiles" '
echo "*.java diff=$p" > .gitattributes &&
! ( git diff --no-index Beer.java Beer-correct.java 2>&1 |
grep "fatal" > /dev/null )
'
done
test_expect_success 'default behaviour' ' test_expect_success 'default behaviour' '
rm -f .gitattributes &&
git diff --no-index Beer.java Beer-correct.java | git diff --no-index Beer.java Beer-correct.java |
grep "^@@.*@@ public class Beer" grep "^@@.*@@ public class Beer"
' '
...@@ -58,7 +69,7 @@ test_expect_success 'last regexp must not be negated' ' ...@@ -58,7 +69,7 @@ test_expect_success 'last regexp must not be negated' '
' '
test_expect_success 'alternation in pattern' ' test_expect_success 'alternation in pattern' '
git config diff.java.funcname "^[ ]*\\(\\(public\\|static\\).*\\)$" git config diff.java.xfuncname "^[ ]*((public|static).*)$" &&
git diff --no-index Beer.java Beer-correct.java | git diff --no-index Beer.java Beer-correct.java |
grep "^@@.*@@ public static void main(" grep "^@@.*@@ public static void main("
' '
......
...@@ -194,31 +194,34 @@ static long ff_regexp(const char *line, long len, ...@@ -194,31 +194,34 @@ static long ff_regexp(const char *line, long len,
char *line_buffer = xstrndup(line, len); /* make NUL terminated */ char *line_buffer = xstrndup(line, len); /* make NUL terminated */
struct ff_regs *regs = priv; struct ff_regs *regs = priv;
regmatch_t pmatch[2]; regmatch_t pmatch[2];
int result = 0, i; int i;
int result = -1;
for (i = 0; i < regs->nr; i++) { for (i = 0; i < regs->nr; i++) {
struct ff_reg *reg = regs->array + i; struct ff_reg *reg = regs->array + i;
if (reg->negate ^ !!regexec(&reg->re, if (!regexec(&reg->re, line_buffer, 2, pmatch, 0)) {
line_buffer, 2, pmatch, 0)) { if (reg->negate)
free(line_buffer); goto fail;
return -1; break;
} }
} }
if (regs->nr <= i)
goto fail;
i = pmatch[1].rm_so >= 0 ? 1 : 0; i = pmatch[1].rm_so >= 0 ? 1 : 0;
line += pmatch[i].rm_so; line += pmatch[i].rm_so;
result = pmatch[i].rm_eo - pmatch[i].rm_so; result = pmatch[i].rm_eo - pmatch[i].rm_so;
if (result > buffer_size) if (result > buffer_size)
result = buffer_size; result = buffer_size;
else else
while (result > 0 && (isspace(line[result - 1]) || while (result > 0 && (isspace(line[result - 1])))
line[result - 1] == '\n'))
result--; result--;
memcpy(buffer, line, result); memcpy(buffer, line, result);
fail:
free(line_buffer); free(line_buffer);
return result; return result;
} }
void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value) void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value, int cflags)
{ {
int i; int i;
struct ff_regs *regs; struct ff_regs *regs;
...@@ -243,7 +246,7 @@ void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value) ...@@ -243,7 +246,7 @@ void xdiff_set_find_func(xdemitconf_t *xecfg, const char *value)
expression = buffer = xstrndup(value, ep - value); expression = buffer = xstrndup(value, ep - value);
else else
expression = value; expression = value;
if (regcomp(&reg->re, expression, 0)) if (regcomp(&reg->re, expression, cflags))
die("Invalid regexp to look for hunk header: %s", expression); die("Invalid regexp to look for hunk header: %s", expression);
free(buffer); free(buffer);
value = ep + 1; value = ep + 1;
......
...@@ -16,7 +16,7 @@ int parse_hunk_header(char *line, int len, ...@@ -16,7 +16,7 @@ int parse_hunk_header(char *line, int len,
int read_mmfile(mmfile_t *ptr, const char *filename); int read_mmfile(mmfile_t *ptr, const char *filename);
int buffer_is_binary(const char *ptr, unsigned long size); int buffer_is_binary(const char *ptr, unsigned long size);
extern void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line); extern void xdiff_set_find_func(xdemitconf_t *xecfg, const char *line, int cflags);
extern int git_xmerge_config(const char *var, const char *value, void *cb); extern int git_xmerge_config(const char *var, const char *value, void *cb);
extern int git_xmerge_style; extern int git_xmerge_style;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册