Navigation Menu

Skip to content

Commit

Permalink
specifying ranges: we did not mean to make ".." an empty set
Browse files Browse the repository at this point in the history
Either end of revision range operator can be omitted to default to HEAD,
as in "origin.." (what did I do since I forked) or "..origin" (what did
they do since I forked).  But the current parser interprets ".."  as an
empty range "HEAD..HEAD", and worse yet, because ".." does exist on the
filesystem, we get this annoying output:

  $ cd Documentation/howto
  $ git log .. ;# give me recent commits that touch Documentation/ area.
  fatal: ambiguous argument '..': both revision and filename
  Use '--' to separate filenames from revisions

Surely we could say "git log ../" or even "git log -- .." to disambiguate,
but we shouldn't have to.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
gitster committed Aug 23, 2012
1 parent c142616 commit 003c84f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Documentation/revisions.txt
Expand Up @@ -213,6 +213,13 @@ of 'r1' and 'r2' and is defined as
It is the set of commits that are reachable from either one of
'r1' or 'r2' but not from both.

In these two shorthands, you can omit one end and let it default to HEAD.
For example, 'origin..' is a shorthand for 'origin..HEAD' and asks "What
did I do since I forked from the origin branch?" Similarly, '..origin'
is a shorthand for 'HEAD..origin' and asks "What did the origin do since
I forked from them?" Note that '..' would mean 'HEAD..HEAD' which is an
empty range that is both reachable and unreachable from HEAD.

Two other shorthands for naming a set that is formed by a commit
and its parent commits exist. The 'r1{caret}@' notation means all
parents of 'r1'. 'r1{caret}!' includes commit 'r1' but excludes
Expand Down
16 changes: 14 additions & 2 deletions builtin/rev-parse.c
Expand Up @@ -224,6 +224,7 @@ static int try_difference(const char *arg)
const char *next;
const char *this;
int symmetric;
static const char head_by_default[] = "HEAD";

if (!(dotdot = strstr(arg, "..")))
return 0;
Expand All @@ -235,9 +236,20 @@ static int try_difference(const char *arg)
next += symmetric;

if (!*next)
next = "HEAD";
next = head_by_default;
if (dotdot == arg)
this = "HEAD";
this = head_by_default;

if (this == head_by_default && next == head_by_default &&
!symmetric) {
/*
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
*dotdot = '.';
return 0;
}

if (!get_sha1(this, sha1) && !get_sha1(next, end)) {
show_rev(NORMAL, end, next);
show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
Expand Down
16 changes: 14 additions & 2 deletions revision.c
Expand Up @@ -1132,15 +1132,27 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs,
const char *this = arg;
int symmetric = *next == '.';
unsigned int flags_exclude = flags ^ UNINTERESTING;
static const char head_by_default[] = "HEAD";
unsigned int a_flags;

*dotdot = 0;
next += symmetric;

if (!*next)
next = "HEAD";
next = head_by_default;
if (dotdot == arg)
this = "HEAD";
this = head_by_default;
if (this == head_by_default && next == head_by_default &&
!symmetric) {
/*
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
if (!cant_be_filename) {
*dotdot = '.';
return -1;
}
}
if (!get_sha1(this, from_sha1) &&
!get_sha1(next, sha1)) {
struct commit *a, *b;
Expand Down
14 changes: 14 additions & 0 deletions t/t1506-rev-parse-diagnosis.sh
Expand Up @@ -182,4 +182,18 @@ test_expect_success '<commit>:file correctly diagnosed after a pathname' '
test_cmp expect actual
'

test_expect_success 'dotdot is not an empty set' '
( H=$(git rev-parse HEAD) && echo $H && echo ^$H ) >expect &&
git rev-parse HEAD.. >actual &&
test_cmp expect actual &&
git rev-parse ..HEAD >actual &&
test_cmp expect actual &&
echo .. >expect &&
git rev-parse .. >actual &&
test_cmp expect actual
'

test_done
7 changes: 7 additions & 0 deletions t/t4202-log.sh
Expand Up @@ -806,4 +806,11 @@ test_expect_success 'log --graph with diff and stats' '
test_cmp expect actual.sanitized
'

test_expect_success 'dotdot is a parent directory' '
mkdir -p a/b &&
( echo sixth && echo fifth ) >expect &&
( cd a/b && git log --format=%s .. ) >actual &&
test_cmp expect actual
'

test_done

0 comments on commit 003c84f

Please sign in to comment.