Skip to content

Commit 77348b0

Browse files
committed
Merge branch 'js/range-diff-wo-dotdot'
There are other ways than ".." for a single token to denote a "commit range", namely "<rev>^!" and "<rev>^-<n>", but "git range-diff" did not understand them. * js/range-diff-wo-dotdot: range-diff(docs): explain how to specify commit ranges range-diff/format-patch: handle commit ranges other than A..B range-diff/format-patch: refactor check for commit range
2 parents 69571df + 2cc543d commit 77348b0

File tree

6 files changed

+65
-5
lines changed

6 files changed

+65
-5
lines changed

Documentation/git-range-diff.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ Finally, the list of matching commits is shown in the order of the
2828
second commit range, with unmatched commits being inserted just after
2929
all of their ancestors have been shown.
3030

31+
There are three ways to specify the commit ranges:
32+
33+
- `<range1> <range2>`: Either commit range can be of the form
34+
`<base>..<rev>`, `<rev>^!` or `<rev>^-<n>`. See `SPECIFYING RANGES`
35+
in linkgit:gitrevisions[7] for more details.
36+
37+
- `<rev1>...<rev2>`. This is equivalent to
38+
`<rev2>..<rev1> <rev1>..<rev2>`.
39+
40+
- `<base> <rev1> <rev2>`: This is equivalent to `<base>..<rev1>
41+
<base>..<rev2>`.
3142

3243
OPTIONS
3344
-------

builtin/log.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ static void infer_range_diff_ranges(struct strbuf *r1,
16721672
struct commit *head)
16731673
{
16741674
const char *head_oid = oid_to_hex(&head->object.oid);
1675-
int prev_is_range = !!strstr(prev, "..");
1675+
int prev_is_range = is_range_diff_range(prev);
16761676

16771677
if (prev_is_range)
16781678
strbuf_addstr(r1, prev);

builtin/range-diff.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "parse-options.h"
44
#include "range-diff.h"
55
#include "config.h"
6+
#include "revision.h"
67

78
static const char * const builtin_range_diff_usage[] = {
89
N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"),
@@ -46,12 +47,12 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
4647
diffopt.use_color = 1;
4748

4849
if (argc == 2) {
49-
if (!strstr(argv[0], ".."))
50-
die(_("no .. in range: '%s'"), argv[0]);
50+
if (!is_range_diff_range(argv[0]))
51+
die(_("not a commit range: '%s'"), argv[0]);
5152
strbuf_addstr(&range1, argv[0]);
5253

53-
if (!strstr(argv[1], ".."))
54-
die(_("no .. in range: '%s'"), argv[1]);
54+
if (!is_range_diff_range(argv[1]))
55+
die(_("not a commit range: '%s'"), argv[1]);
5556
strbuf_addstr(&range2, argv[1]);
5657
} else if (argc == 3) {
5758
strbuf_addf(&range1, "%s..%s", argv[0], argv[1]);

range-diff.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pretty.h"
1212
#include "userdiff.h"
1313
#include "apply.h"
14+
#include "revision.h"
1415

1516
struct patch_util {
1617
/* For the search for an exact match */
@@ -564,3 +565,31 @@ int show_range_diff(const char *range1, const char *range2,
564565

565566
return res;
566567
}
568+
569+
int is_range_diff_range(const char *arg)
570+
{
571+
char *copy = xstrdup(arg); /* setup_revisions() modifies it */
572+
const char *argv[] = { "", copy, "--", NULL };
573+
int i, positive = 0, negative = 0;
574+
struct rev_info revs;
575+
576+
init_revisions(&revs, NULL);
577+
if (setup_revisions(3, argv, &revs, NULL) == 1) {
578+
for (i = 0; i < revs.pending.nr; i++)
579+
if (revs.pending.objects[i].item->flags & UNINTERESTING)
580+
negative++;
581+
else
582+
positive++;
583+
for (i = 0; i < revs.pending.nr; i++) {
584+
struct object *obj = revs.pending.objects[i].item;
585+
586+
if (obj->type == OBJ_COMMIT)
587+
clear_commit_marks((struct commit *)obj,
588+
ALL_REV_FLAGS);
589+
}
590+
}
591+
592+
free(copy);
593+
object_array_clear(&revs.pending);
594+
return negative > 0 && positive > 0;
595+
}

range-diff.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@ int show_range_diff(const char *range1, const char *range2,
1616
const struct diff_options *diffopt,
1717
const struct strvec *other_arg);
1818

19+
/*
20+
* Determine whether the given argument is usable as a range argument of `git
21+
* range-diff`, e.g. A..B.
22+
*/
23+
int is_range_diff_range(const char *arg);
24+
1925
#endif

t/t3206-range-diff.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,19 @@ test_expect_success 'simple A B C (unmodified)' '
153153
test_cmp expect actual
154154
'
155155

156+
test_expect_success 'A^! and A^-<n> (unmodified)' '
157+
git range-diff --no-color topic^! unmodified^-1 >actual &&
158+
cat >expect <<-EOF &&
159+
1: $(test_oid t4) = 1: $(test_oid u4) s/12/B/
160+
EOF
161+
test_cmp expect actual
162+
'
163+
164+
test_expect_success 'A^{/..} is not mistaken for a range' '
165+
test_must_fail git range-diff topic^.. topic^{/..} 2>error &&
166+
test_i18ngrep "not a commit range" error
167+
'
168+
156169
test_expect_success 'trivial reordering' '
157170
git range-diff --no-color main topic reordered >actual &&
158171
cat >expect <<-EOF &&

0 commit comments

Comments
 (0)