Permalink
Browse files

Merge branch 'jc/dotdot-is-parent-directory'

"git log .." errored out saying it is both rev range and a path when
there is no disambiguating "--" is on the command line.  Update the
command line parser to interpret ".." as a path in such a case.

* jc/dotdot-is-parent-directory:
  specifying ranges: we did not mean to make ".." an empty set
  • Loading branch information...
2 parents 096bbd6 + 003c84f commit 7764a3b35c53b6859963ddad92bfc90563ac8baa @gitster gitster committed Sep 7, 2012
Showing with 56 additions and 4 deletions.
  1. +7 −0 Documentation/revisions.txt
  2. +14 −2 builtin/rev-parse.c
  3. +14 −2 revision.c
  4. +14 −0 t/t1506-rev-parse-diagnosis.sh
  5. +7 −0 t/t4202-log.sh
@@ -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
View
@@ -230,6 +230,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;
@@ -241,9 +242,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_committish(this, sha1) && !get_sha1_committish(next, end)) {
show_rev(NORMAL, end, next);
show_rev(symmetric ? NORMAL : REVERSED, sha1, this);
View
@@ -1134,15 +1134,27 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
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_committish(this, from_sha1) &&
!get_sha1_committish(next, sha1)) {
struct commit *a, *b;
@@ -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
View
@@ -806,4 +806,11 @@ test_expect_success 'log --graph with diff and stats' '
test_i18ncmp 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 7764a3b

Please sign in to comment.