Skip to content

Commit c8c5e43

Browse files
dschogitster
authored andcommitted
range-diff: also show the diff between patches
Just like tbdiff, we now show the diff between matching patches. This is a "diff of two diffs", so it can be a bit daunting to read for the beginner. An alternative would be to display an interdiff, i.e. the hypothetical diff which is the result of first reverting the old diff and then applying the new diff. Especially when rebasing frequently, an interdiff is often not feasible, though: if the old diff cannot be applied in reverse (due to a moving upstream), an interdiff can simply not be inferred. This commit brings `range-diff` closer to feature parity with regard to tbdiff. To make `git range-diff` respect e.g. color.diff.* settings, we have to adjust git_branch_config() accordingly. Note: while we now parse diff options such as --color, the effect is not yet the same as in tbdiff, where also the commit pairs would be colored. This is left for a later commit. Note also: while tbdiff accepts the `--no-patches` option to suppress these diffs between patches, we prefer the `-s` (or `--no-patch`) option that is automatically supported via our use of diff_opt_parse(). And finally note: to support diff options, we have to call `parse_options()` such that it keeps unknown options, and then loop over those and let `diff_opt_parse()` handle them. After that loop, we have to call `parse_options()` again, to make sure that no unknown options are left. Helped-by: Thomas Gummerer <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9dc46e0 commit c8c5e43

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

builtin/range-diff.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "builtin.h"
33
#include "parse-options.h"
44
#include "range-diff.h"
5+
#include "config.h"
56

67
static const char * const builtin_range_diff_usage[] = {
78
N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"),
@@ -13,15 +14,40 @@ NULL
1314
int cmd_range_diff(int argc, const char **argv, const char *prefix)
1415
{
1516
int creation_factor = 60;
17+
struct diff_options diffopt = { NULL };
1618
struct option options[] = {
1719
OPT_INTEGER(0, "creation-factor", &creation_factor,
1820
N_("Percentage by which creation is weighted")),
1921
OPT_END()
2022
};
21-
int res = 0;
23+
int i, j, res = 0;
2224
struct strbuf range1 = STRBUF_INIT, range2 = STRBUF_INIT;
2325

26+
git_config(git_diff_ui_config, NULL);
27+
28+
diff_setup(&diffopt);
29+
diffopt.output_format = DIFF_FORMAT_PATCH;
30+
2431
argc = parse_options(argc, argv, NULL, options,
32+
builtin_range_diff_usage, PARSE_OPT_KEEP_UNKNOWN |
33+
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);
34+
35+
for (i = j = 1; i < argc && strcmp("--", argv[i]); ) {
36+
int c = diff_opt_parse(&diffopt, argv + i, argc - i, prefix);
37+
38+
if (!c)
39+
argv[j++] = argv[i++];
40+
else
41+
i += c;
42+
}
43+
while (i < argc)
44+
argv[j++] = argv[i++];
45+
argc = j;
46+
diff_setup_done(&diffopt);
47+
48+
/* Make sure that there are no unparsed options */
49+
argc = parse_options(argc, argv, NULL,
50+
options + ARRAY_SIZE(options) - 1, /* OPT_END */
2551
builtin_range_diff_usage, 0);
2652

2753
if (argc == 2) {
@@ -59,7 +85,8 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
5985
usage_with_options(builtin_range_diff_usage, options);
6086
}
6187

62-
res = show_range_diff(range1.buf, range2.buf, creation_factor);
88+
res = show_range_diff(range1.buf, range2.buf, creation_factor,
89+
&diffopt);
6390

6491
strbuf_release(&range1);
6592
strbuf_release(&range2);

range-diff.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "hashmap.h"
77
#include "xdiff-interface.h"
88
#include "linear-assignment.h"
9+
#include "diffcore.h"
910

1011
struct patch_util {
1112
/* For the search for an exact match */
@@ -258,7 +259,31 @@ static const char *short_oid(struct patch_util *util)
258259
return find_unique_abbrev(&util->oid, DEFAULT_ABBREV);
259260
}
260261

261-
static void output(struct string_list *a, struct string_list *b)
262+
static struct diff_filespec *get_filespec(const char *name, const char *p)
263+
{
264+
struct diff_filespec *spec = alloc_filespec(name);
265+
266+
fill_filespec(spec, &null_oid, 0, 0644);
267+
spec->data = (char *)p;
268+
spec->size = strlen(p);
269+
spec->should_munmap = 0;
270+
spec->is_stdin = 1;
271+
272+
return spec;
273+
}
274+
275+
static void patch_diff(const char *a, const char *b,
276+
struct diff_options *diffopt)
277+
{
278+
diff_queue(&diff_queued_diff,
279+
get_filespec("a", a), get_filespec("b", b));
280+
281+
diffcore_std(diffopt);
282+
diff_flush(diffopt);
283+
}
284+
285+
static void output(struct string_list *a, struct string_list *b,
286+
struct diff_options *diffopt)
262287
{
263288
int i = 0, j = 0;
264289

@@ -300,14 +325,17 @@ static void output(struct string_list *a, struct string_list *b)
300325
printf("%d: %s ! %d: %s\n",
301326
b_util->matching + 1, short_oid(a_util),
302327
j + 1, short_oid(b_util));
328+
if (!(diffopt->output_format & DIFF_FORMAT_NO_OUTPUT))
329+
patch_diff(a->items[b_util->matching].string,
330+
b->items[j].string, diffopt);
303331
a_util->shown = 1;
304332
j++;
305333
}
306334
}
307335
}
308336

309337
int show_range_diff(const char *range1, const char *range2,
310-
int creation_factor)
338+
int creation_factor, struct diff_options *diffopt)
311339
{
312340
int res = 0;
313341

@@ -322,7 +350,7 @@ int show_range_diff(const char *range1, const char *range2,
322350
if (!res) {
323351
find_exact_matches(&branch1, &branch2);
324352
get_correspondences(&branch1, &branch2, creation_factor);
325-
output(&branch1, &branch2);
353+
output(&branch1, &branch2, diffopt);
326354
}
327355

328356
string_list_clear(&branch1, 1);

range-diff.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#ifndef RANGE_DIFF_H
22
#define RANGE_DIFF_H
33

4+
#include "diff.h"
5+
46
int show_range_diff(const char *range1, const char *range2,
5-
int creation_factor);
7+
int creation_factor, struct diff_options *diffopt);
68

79
#endif

0 commit comments

Comments
 (0)