Add new @ shortcut for HEAD
authorFelipe Contreras <felipe.contreras@gmail.com>
Tue, 7 May 2013 22:04:31 +0000 (17:04 -0500)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 May 2013 19:13:12 +0000 (12:13 -0700)
Typing 'HEAD' is tedious, especially when we can use '@' instead.

The reason for choosing '@' is that it follows naturally from the
ref@op syntax (e.g. HEAD@{u}), except we have no ref, and no
operation, and when we don't have those, it makes sens to assume
'HEAD'.

So now we can use 'git show @~1', and all that goody goodness.

Until now '@' was a valid name, but it conflicts with this idea, so
let's make it invalid. Probably very few people, if any, used this name.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-check-ref-format.txt
Documentation/revisions.txt
refs.c
sha1_name.c
t/t1508-at-combinations.sh
index ec1739a896074c96bd94603592ca72bcee0b927f..e8035ece4213f4a056651cf20f570256cccb1e54 100644 (file)
@@ -54,6 +54,8 @@ Git imposes the following rules on how references are named:
 
 . They cannot contain a sequence `@{`.
 
+. They cannot be the single character `@`.
+
 . They cannot contain a `\`.
 
 These rules make it easy for shell script based tools to parse
index d477b3f6bcb2c410952b573421d28189d1d1a790..09896a37b1a7b735b0defc9d2c7eb2a14cc713ab 100644 (file)
@@ -58,6 +58,9 @@ the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file.
 While the ref name encoding is unspecified, UTF-8 is preferred as
 some output processing may assume ref names in UTF-8.
 
+'@'::
+  '@' alone is a shortcut for 'HEAD'.
+
 '<refname>@\{<date>\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}'::
   A ref followed by the suffix '@' with a date specification
   enclosed in a brace
diff --git a/refs.c b/refs.c
index de2d8eb866062649a0d0f23a77e350bca1a182cd..4e70b3eca037a084fae0eae00386cd040305ce21 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -72,6 +72,10 @@ int check_refname_format(const char *refname, int flags)
 {
        int component_len, component_count = 0;
 
+       if (!strcmp(refname, "@"))
+               /* Refname is a single character '@'. */
+               return -1;
+
        while (1) {
                /* We are at the start of a path component. */
                component_len = check_refname_component(refname, flags);
index f60c951234cd82355de0c38395985561c7f16c49..4428df19a7d3fff7c5d4a403f1677b694170129f 100644 (file)
@@ -972,6 +972,17 @@ int get_sha1_mb(const char *name, unsigned char *sha1)
        return st;
 }
 
+/* parse @something syntax, when 'something' is not {.*} */
+static int interpret_empty_at(const char *name, int namelen, int len, struct strbuf *buf)
+{
+       if (len || name[1] == '{')
+               return -1;
+
+       strbuf_reset(buf);
+       strbuf_add(buf, "HEAD", 4);
+       return 1;
+}
+
 static int reinterpret(const char *name, int namelen, int len, struct strbuf *buf)
 {
        /* we have extra data, which might need further processing */
@@ -1032,9 +1043,15 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
        cp = strchr(name, '@');
        if (!cp)
                return -1;
+
+       len = interpret_empty_at(name, namelen, cp - name, buf);
+       if (len > 0)
+               return reinterpret(name, namelen, len, buf);
+
        tmp_len = upstream_mark(cp, namelen - (cp - name));
        if (!tmp_len)
                return -1;
+
        len = cp + tmp_len - name;
        cp = xstrndup(name, cp - name);
        upstream = branch_get(*cp ? cp : NULL);
index e5aea3b89602fdaf5ed3a9a230a604dd3f48cda0..4db1613f8a313b3d292132592c8e408dd95f05c9 100755 (executable)
@@ -55,6 +55,8 @@ check "HEAD@{u}" ref refs/heads/upstream-branch
 check "@{u}@{1}" commit upstream-one
 check "@{-1}@{u}" ref refs/heads/master
 check "@{-1}@{u}@{1}" commit master-one
+check "@" commit new-two
+check "@@{u}" ref refs/heads/upstream-branch
 nonsense "@{u}@{-1}"
 nonsense "@{0}@{0}"
 nonsense "@{1}@{u}"