aboutsummaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/diff.c b/diff.c
index 84876431b..6991ed4e1 100644
--- a/diff.c
+++ b/diff.c
@@ -1771,8 +1771,14 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two, char *pre
static void diff_filespec_load_driver(struct diff_filespec *one)
{
- if (!one->driver)
+ /* Use already-loaded driver */
+ if (one->driver)
+ return;
+
+ if (S_ISREG(one->mode))
one->driver = userdiff_find_by_path(one->path);
+
+ /* Fallback to default settings */
if (!one->driver)
one->driver = userdiff_find_by_name("default");
}
@@ -1820,8 +1826,7 @@ struct userdiff_driver *get_textconv(struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one))
return NULL;
- if (!S_ISREG(one->mode))
- return NULL;
+
diff_filespec_load_driver(one);
if (!one->driver->textconv)
return NULL;
@@ -2153,7 +2158,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
ecbdata.ws_rule = data.ws_rule;
check_blank_at_eof(&mf1, &mf2, &ecbdata);
- blank_at_eof = ecbdata.blank_at_eof_in_preimage;
+ blank_at_eof = ecbdata.blank_at_eof_in_postimage;
if (blank_at_eof) {
static char *err;
@@ -2386,10 +2391,14 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
}
else {
enum object_type type;
- if (size_only)
+ if (size_only) {
type = sha1_object_info(s->sha1, &s->size);
- else {
+ if (type < 0)
+ die("unable to read %s", sha1_to_hex(s->sha1));
+ } else {
s->data = read_sha1_file(s->sha1, &type, &s->size);
+ if (!s->data)
+ die("unable to read %s", sha1_to_hex(s->sha1));
s->should_free = 1;
}
}
@@ -3140,16 +3149,19 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
return stat_opt(options, av);
/* renames options */
- else if (!prefixcmp(arg, "-B")) {
+ else if (!prefixcmp(arg, "-B") || !prefixcmp(arg, "--break-rewrites=") ||
+ !strcmp(arg, "--break-rewrites")) {
if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
return error("invalid argument to -B: %s", arg+2);
}
- else if (!prefixcmp(arg, "-M")) {
+ else if (!prefixcmp(arg, "-M") || !prefixcmp(arg, "--detect-renames=") ||
+ !strcmp(arg, "--detect-renames")) {
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return error("invalid argument to -M: %s", arg+2);
options->detect_rename = DIFF_DETECT_RENAME;
}
- else if (!prefixcmp(arg, "-C")) {
+ else if (!prefixcmp(arg, "-C") || !prefixcmp(arg, "--detect-copies=") ||
+ !strcmp(arg, "--detect-copies")) {
if (options->detect_rename == DIFF_DETECT_COPY)
DIFF_OPT_SET(options, FIND_COPIES_HARDER);
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
@@ -3323,7 +3335,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
return 1;
}
-static int parse_num(const char **cp_p)
+int parse_rename_score(const char **cp_p)
{
unsigned long num, scale;
int ch, dot;
@@ -3366,10 +3378,26 @@ static int diff_scoreopt_parse(const char *opt)
if (*opt++ != '-')
return -1;
cmd = *opt++;
+ if (cmd == '-') {
+ /* convert the long-form arguments into short-form versions */
+ if (!prefixcmp(opt, "break-rewrites")) {
+ opt += strlen("break-rewrites");
+ if (*opt == 0 || *opt++ == '=')
+ cmd = 'B';
+ } else if (!prefixcmp(opt, "detect-copies")) {
+ opt += strlen("detect-copies");
+ if (*opt == 0 || *opt++ == '=')
+ cmd = 'C';
+ } else if (!prefixcmp(opt, "detect-renames")) {
+ opt += strlen("detect-renames");
+ if (*opt == 0 || *opt++ == '=')
+ cmd = 'M';
+ }
+ }
if (cmd != 'M' && cmd != 'C' && cmd != 'B')
return -1; /* that is not a -M, -C nor -B option */
- opt1 = parse_num(&opt);
+ opt1 = parse_rename_score(&opt);
if (cmd != 'B')
opt2 = 0;
else {
@@ -3379,7 +3407,7 @@ static int diff_scoreopt_parse(const char *opt)
return -1; /* we expect -B80/99 or -B80 */
else {
opt++;
- opt2 = parse_num(&opt);
+ opt2 = parse_rename_score(&opt);
}
}
if (*opt != 0)
@@ -3532,7 +3560,7 @@ static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,
if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
(DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
- return; /* no tree diffs in patch format */
+ return; /* no useful stat for tree diffs */
run_diffstat(p, o, diffstat);
}
@@ -3545,7 +3573,7 @@ static void diff_flush_checkdiff(struct diff_filepair *p,
if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
(DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
- return; /* no tree diffs in patch format */
+ return; /* nothing to check in tree diffs */
run_checkdiff(p, o);
}
@@ -3870,7 +3898,7 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
xpp.flags = 0;
xecfg.ctxlen = 3;
- xecfg.flags = XDL_EMIT_FUNCNAMES;
+ xecfg.flags = 0;
xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
&xpp, &xecfg);
}