1397
}
1398
1399
static void builtin_checkdiff(const char *name_a, const char *name_b,
1400
+ const char *attr_path,
1401
struct diff_filespec *one,
1402
struct diff_filespec *two, struct diff_options *o)
1403
{
1412
data.filename = name_b ? name_b : name_a;
1413
data.lineno = 0;
1414
data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
1414
- data.ws_rule = whitespace_rule(data.filename);
1415
+ data.ws_rule = whitespace_rule(attr_path);
1416
1417
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1418
die("unable to read files to diff");
1832
{
1833
struct git_attr_check attr_diff_check;
1834
1835
+ if (!name)
1836
+ return NULL;
1837
+
1838
setup_diff_attr_check(&attr_diff_check);
1839
if (!git_checkattr(name, 1, &attr_diff_check)) {
1840
const char *value = attr_diff_check.value;
1854
static void run_diff_cmd(const char *pgm,
1855
const char *name,
1856
const char *other,
1857
+ const char *attr_path,
1858
struct diff_filespec *one,
1859
struct diff_filespec *two,
1860
const char *xfrm_msg,
1864
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
1865
pgm = NULL;
1866
else {
1862
- const char *cmd = external_diff_attr(name);
1867
+ const char *cmd = external_diff_attr(attr_path);
1868
if (cmd)
1869
pgm = cmd;
1870
}
1905
return p->score * 100 / MAX_SCORE;
1906
}
1907
1908
+static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
1909
+{
1910
+ /* Strip the prefix but do not molest /dev/null and absolute paths */
1911
+ if (*namep && **namep != '/')
1912
+ *namep += prefix_length;
1913
+ if (*otherp && **otherp != '/')
1914
+ *otherp += prefix_length;
1915
+}
1916
+
1917
static void run_diff(struct diff_filepair *p, struct diff_options *o)
1918
{
1919
const char *pgm = external_diff();
1923
struct diff_filespec *two = p->two;
1924
const char *name;
1925
const char *other;
1926
+ const char *attr_path;
1927
int complete_rewrite = 0;
1928
1929
+ name = p->one->path;
1930
+ other = (strcmp(name, p->two->path) ? p->two->path : NULL);
1931
+ attr_path = name;
1932
+ if (o->prefix_length)
1933
+ strip_prefix(o->prefix_length, &name, &other);
1934
1935
if (DIFF_PAIR_UNMERGED(p)) {
1916
- run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, o, 0);
1936
+ run_diff_cmd(pgm, name, NULL, attr_path,
1937
+ NULL, NULL, NULL, o, 0);
1938
return;
1939
}
1940
1920
- name = p->one->path;
1921
- other = (strcmp(name, p->two->path) ? p->two->path : NULL);
1941
diff_fill_sha1_info(one);
1942
diff_fill_sha1_info(two);
1943
2000
* needs to be split into deletion and creation.
2001
*/
2002
struct diff_filespec *null = alloc_filespec(two->path);
1984
- run_diff_cmd(NULL, name, other, one, null, xfrm_msg, o, 0);
2003
+ run_diff_cmd(NULL, name, other, attr_path,
2004
+ one, null, xfrm_msg, o, 0);
2005
free(null);
2006
null = alloc_filespec(one->path);
1987
- run_diff_cmd(NULL, name, other, null, two, xfrm_msg, o, 0);
2007
+ run_diff_cmd(NULL, name, other, attr_path,
2008
+ null, two, xfrm_msg, o, 0);
2009
free(null);
2010
}
2011
else
1991
- run_diff_cmd(pgm, name, other, one, two, xfrm_msg, o,
1992
- complete_rewrite);
2012
+ run_diff_cmd(pgm, name, other, attr_path,
2013
+ one, two, xfrm_msg, o, complete_rewrite);
2014
2015
strbuf_release(&msg);
2016
}
2031
name = p->one->path;
2032
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
2033
2034
+ if (o->prefix_length)
2035
+ strip_prefix(o->prefix_length, &name, &other);
2036
+
2037
diff_fill_sha1_info(p->one);
2038
diff_fill_sha1_info(p->two);
2039
2046
{
2047
const char *name;
2048
const char *other;
2049
+ const char *attr_path;
2050
2051
if (DIFF_PAIR_UNMERGED(p)) {
2052
/* unmerged */
2055
2056
name = p->one->path;
2057
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
2058
+ attr_path = other ? other : name;
2059
+
2060
+ if (o->prefix_length)
2061
+ strip_prefix(o->prefix_length, &name, &other);
2062
2063
diff_fill_sha1_info(p->one);
2064
diff_fill_sha1_info(p->two);
2065
2037
- builtin_checkdiff(name, other, p->one, p->two, o);
2066
+ builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
2067
}
2068
2069
void diff_setup(struct diff_options *options)
2105
if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
2106
options->detect_rename = DIFF_DETECT_COPY;
2107
2108
+ if (!DIFF_OPT_TST(options, RELATIVE_NAME))
2109
+ options->prefix = NULL;
2110
+ if (options->prefix)
2111
+ options->prefix_length = strlen(options->prefix);
2112
+ else
2113
+ options->prefix_length = 0;
2114
+
2115
if (options->output_format & (DIFF_FORMAT_NAME |
2116
DIFF_FORMAT_NAME_STATUS |
2117
DIFF_FORMAT_CHECKDIFF |
2300
}
2301
else if (!strcmp(arg, "--no-renames"))
2302
options->detect_rename = 0;
2303
+ else if (!strcmp(arg, "--relative"))
2304
+ DIFF_OPT_SET(options, RELATIVE_NAME);
2305
2306
/* xdiff options */
2307
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
2513
printf("%c%c", p->status, inter_name_termination);
2514
}
2515
2478
- if (p->status == DIFF_STATUS_COPIED || p->status == DIFF_STATUS_RENAMED) {
2479
- write_name_quoted(p->one->path, stdout, inter_name_termination);
2480
- write_name_quoted(p->two->path, stdout, line_termination);
2516
+ if (p->status == DIFF_STATUS_COPIED ||
2517
+ p->status == DIFF_STATUS_RENAMED) {
2518
+ const char *name_a, *name_b;
2519
+ name_a = p->one->path;
2520
+ name_b = p->two->path;
2521
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
2522
+ write_name_quoted(name_a, stdout, inter_name_termination);
2523
+ write_name_quoted(name_b, stdout, line_termination);
2524
} else {
2482
- const char *path = p->one->mode ? p->one->path : p->two->path;
2483
- write_name_quoted(path, stdout, line_termination);
2525
+ const char *name_a, *name_b;
2526
+ name_a = p->one->mode ? p->one->path : p->two->path;
2527
+ name_b = NULL;
2528
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
2529
+ write_name_quoted(name_a, stdout, line_termination);
2530
}
2531
}
2532
2723
diff_flush_checkdiff(p, opt);
2724
else if (fmt & (DIFF_FORMAT_RAW | DIFF_FORMAT_NAME_STATUS))
2725
diff_flush_raw(p, opt);
2680
- else if (fmt & DIFF_FORMAT_NAME)
2681
- write_name_quoted(p->two->path, stdout, opt->line_termination);
2726
+ else if (fmt & DIFF_FORMAT_NAME) {
2727
+ const char *name_a, *name_b;
2728
+ name_a = p->two->path;
2729
+ name_b = NULL;
2730
+ strip_prefix(opt->prefix_length, &name_a, &name_b);
2731
+ write_name_quoted(name_a, stdout, opt->line_termination);
2732
+ }
2733
}
2734
2735
static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
3215
3216
if (!path) path = "";
3217
sprintf(concatpath, "%s%s", base, path);
3218
+
3219
+ if (options->prefix &&
3220
+ strncmp(concatpath, options->prefix, options->prefix_length))
3221
+ return;
3222
+
3223
one = alloc_filespec(concatpath);
3224
two = alloc_filespec(concatpath);
3225
3249
}
3250
if (!path) path = "";
3251
sprintf(concatpath, "%s%s", base, path);
3252
+
3253
+ if (options->prefix &&
3254
+ strncmp(concatpath, options->prefix, options->prefix_length))
3255
+ return;
3256
+
3257
one = alloc_filespec(concatpath);
3258
two = alloc_filespec(concatpath);
3259
fill_filespec(one, old_sha1, old_mode);
3268
unsigned mode, const unsigned char *sha1)
3269
{
3270
struct diff_filespec *one, *two;
3271
+
3272
+ if (options->prefix &&
3273
+ strncmp(path, options->prefix, options->prefix_length))
3274
+ return;
3275
+
3276
one = alloc_filespec(path);
3277
two = alloc_filespec(path);
3278
fill_filespec(one, sha1, mode);