Merge branch 'jc/dotdot-is-parent-directory' into maint-1.7.11
authorJunio C Hamano <gitster@pobox.com>
Wed, 12 Sep 2012 21:00:34 +0000 (14:00 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 12 Sep 2012 21:00:34 +0000 (14:00 -0700)
"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

Documentation/revisions.txt
builtin/rev-parse.c
revision.c
t/t1506-rev-parse-diagnosis.sh
t/t4202-log.sh

index dc0070b..69d996b 100644 (file)
@@ -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
index 13495b8..47b4e7a 100644 (file)
@@ -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;
@@ -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);
index 6d21ac7..7210496 100644 (file)
@@ -1134,15 +1134,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;
index c5cb77a..f950c10 100755 (executable)
@@ -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
index 71be59d..45058cc 100755 (executable)
@@ -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