Skip to content

Commit

Permalink
Merge branch 'js/range-diff-wo-dotdot' into seen
Browse files Browse the repository at this point in the history
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.

Getting closer.
cf. <xmqqzh107m5d.fsf@gitster.c.googlers.com>

* js/range-diff-wo-dotdot:
  range-diff(docs): explain how to specify commit ranges
  range-diff: handle commit ranges other than A..B
  range-diff: refactor check for commit range
  • Loading branch information
gitster committed Jan 25, 2021
2 parents 588dfe1 + 2b4a67f commit f103fb4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
13 changes: 13 additions & 0 deletions Documentation/git-range-diff.txt
Expand Up @@ -28,6 +28,19 @@ Finally, the list of matching commits is shown in the order of the
second commit range, with unmatched commits being inserted just after
all of their ancestors have been shown.

There are three ways to specify the commit ranges:

- `<range1> <range2>`: Either commit range can be of the form
`<base>..<rev>`, `<rev>^!` or `<rev>^-<n>`. See `SPECIFYING RANGES`
in linkgit:gitrevisions[7] for more details.

- `<rev1>...<rev2>`. This resembles the symmetric ranges mentioned in
the `SPECIFYING RANGES` section of linkgit:gitrevisions[7], and is
equivalent to `<base>..<rev1> <base>..<rev2>` where `<base>` is the
merge base as obtained via `git merge-base <rev1> <rev2>`.

- `<base> <rev1> <rev2>`: This is equivalent to `<base>..<rev1>
<base>..<rev2>`.

OPTIONS
-------
Expand Down
32 changes: 28 additions & 4 deletions builtin/range-diff.c
Expand Up @@ -11,6 +11,30 @@ N_("git range-diff [<options>] <base> <old-tip> <new-tip>"),
NULL
};

static int is_range(const char *range)
{
size_t i;
char c;

if (strstr(range, ".."))
return 1;

i = strlen(range);
c = i ? range[--i] : 0;
if (c == '!')
i--; /* might be ...^! or ...^@ */
else if (isdigit(c)) {
/* handle ...^-<n> */
while (i > 2 && isdigit(range[--i]))
; /* keep trimming trailing digits */
if (i < 2 || range[i--] != '-')
return 0;
} else
return 0;

return i > 0 && range[i] == '^';
}

int cmd_range_diff(int argc, const char **argv, const char *prefix)
{
int creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT;
Expand Down Expand Up @@ -46,12 +70,12 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
diffopt.use_color = 1;

if (argc == 2) {
if (!strstr(argv[0], ".."))
die(_("no .. in range: '%s'"), argv[0]);
if (!is_range(argv[0]))
die(_("not a commit range: '%s'"), argv[0]);
strbuf_addstr(&range1, argv[0]);

if (!strstr(argv[1], ".."))
die(_("no .. in range: '%s'"), argv[1]);
if (!is_range(argv[1]))
die(_("not a commit range: '%s'"), argv[1]);
strbuf_addstr(&range2, argv[1]);
} else if (argc == 3) {
strbuf_addf(&range1, "%s..%s", argv[0], argv[1]);
Expand Down
8 changes: 8 additions & 0 deletions t/t3206-range-diff.sh
Expand Up @@ -153,6 +153,14 @@ test_expect_success 'simple A B C (unmodified)' '
test_cmp expect actual
'

test_expect_success 'A^! and A^-<n> (unmodified)' '
git range-diff --no-color topic^! unmodified^-1 >actual &&
cat >expect <<-EOF &&
1: $(test_oid t4) = 1: $(test_oid u4) s/12/B/
EOF
test_cmp expect actual
'

test_expect_success 'trivial reordering' '
git range-diff --no-color main topic reordered >actual &&
cat >expect <<-EOF &&
Expand Down

0 comments on commit f103fb4

Please sign in to comment.