Skip to content

Commit

Permalink
Merge branch 'js/range-diff-wo-dotdot' into next
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.

* 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
  • Loading branch information
gitster committed Feb 8, 2021
2 parents 3ba9f80 + 2cc543d commit 9ae8b46
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 5 deletions.
11 changes: 11 additions & 0 deletions Documentation/git-range-diff.txt
Expand Up @@ -28,6 +28,17 @@ 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 is equivalent to
`<rev2>..<rev1> <rev1>..<rev2>`.

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

OPTIONS
-------
Expand Down
2 changes: 1 addition & 1 deletion builtin/log.c
Expand Up @@ -1672,7 +1672,7 @@ static void infer_range_diff_ranges(struct strbuf *r1,
struct commit *head)
{
const char *head_oid = oid_to_hex(&head->object.oid);
int prev_is_range = !!strstr(prev, "..");
int prev_is_range = is_range_diff_range(prev);

if (prev_is_range)
strbuf_addstr(r1, prev);
Expand Down
9 changes: 5 additions & 4 deletions builtin/range-diff.c
Expand Up @@ -3,6 +3,7 @@
#include "parse-options.h"
#include "range-diff.h"
#include "config.h"
#include "revision.h"

static const char * const builtin_range_diff_usage[] = {
N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"),
Expand Down Expand Up @@ -46,12 +47,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_diff_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_diff_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
29 changes: 29 additions & 0 deletions range-diff.c
Expand Up @@ -11,6 +11,7 @@
#include "pretty.h"
#include "userdiff.h"
#include "apply.h"
#include "revision.h"

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

return res;
}

int is_range_diff_range(const char *arg)
{
char *copy = xstrdup(arg); /* setup_revisions() modifies it */
const char *argv[] = { "", copy, "--", NULL };
int i, positive = 0, negative = 0;
struct rev_info revs;

init_revisions(&revs, NULL);
if (setup_revisions(3, argv, &revs, NULL) == 1) {
for (i = 0; i < revs.pending.nr; i++)
if (revs.pending.objects[i].item->flags & UNINTERESTING)
negative++;
else
positive++;
for (i = 0; i < revs.pending.nr; i++) {
struct object *obj = revs.pending.objects[i].item;

if (obj->type == OBJ_COMMIT)
clear_commit_marks((struct commit *)obj,
ALL_REV_FLAGS);
}
}

free(copy);
object_array_clear(&revs.pending);
return negative > 0 && positive > 0;
}
6 changes: 6 additions & 0 deletions range-diff.h
Expand Up @@ -16,4 +16,10 @@ int show_range_diff(const char *range1, const char *range2,
const struct diff_options *diffopt,
const struct strvec *other_arg);

/*
* Determine whether the given argument is usable as a range argument of `git
* range-diff`, e.g. A..B.
*/
int is_range_diff_range(const char *arg);

#endif
13 changes: 13 additions & 0 deletions t/t3206-range-diff.sh
Expand Up @@ -153,6 +153,19 @@ 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 'A^{/..} is not mistaken for a range' '
test_must_fail git range-diff topic^.. topic^{/..} 2>error &&
test_i18ngrep "not a commit range" error
'

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

0 comments on commit 9ae8b46

Please sign in to comment.