Merge branch 'jk/head-symref'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 Feb 2009 03:40:35 +0000 (19:40 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Feb 2009 03:40:35 +0000 (19:40 -0800)
* jk/head-symref:
symbolic ref: refuse non-ref targets in HEAD
validate_headref: tighten ref-matching to just branches

builtin-symbolic-ref.c
path.c
t/t1401-symbolic-ref.sh [new file with mode: 0755]
index bfc78bb3f6eff2f8e39649b9649ae7263f143ad9..cafc4eba7cc0f8e2c89d49403b56bb746fe14545 100644 (file)
@@ -44,6 +44,9 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
                check_symref(argv[0], quiet);
                break;
        case 2:
+               if (!strcmp(argv[0], "HEAD") &&
+                   prefixcmp(argv[1], "refs/heads/"))
+                       die("Refusing to point HEAD outside of refs/heads/");
                create_symref(argv[0], argv[1], msg);
                break;
        default:
diff --git a/path.c b/path.c
index a074aea64921eb1fb90f079ede9087e6b8109f6a..108d9e9599d059a06fd0621188f45a716346ca07 100644 (file)
--- a/path.c
+++ b/path.c
@@ -154,7 +154,7 @@ int validate_headref(const char *path)
        /* Make sure it is a "refs/.." symlink */
        if (S_ISLNK(st.st_mode)) {
                len = readlink(path, buffer, sizeof(buffer)-1);
-               if (len >= 5 && !memcmp("refs/", buffer, 5))
+               if (len >= 11 && !memcmp("refs/heads/", buffer, 11))
                        return 0;
                return -1;
        }
@@ -178,7 +178,7 @@ int validate_headref(const char *path)
                len -= 4;
                while (len && isspace(*buf))
                        buf++, len--;
-               if (len >= 5 && !memcmp("refs/", buf, 5))
+               if (len >= 11 && !memcmp("refs/heads/", buf, 11))
                        return 0;
        }
 
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
new file mode 100755 (executable)
index 0000000..569f341
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+test_description='basic symbolic-ref tests'
+. ./test-lib.sh
+
+# If the tests munging HEAD fail, they can break detection of
+# the git repo, meaning that further tests will operate on
+# the surrounding git repo instead of the trash directory.
+reset_to_sane() {
+       echo ref: refs/heads/foo >.git/HEAD
+}
+
+test_expect_success 'symbolic-ref writes HEAD' '
+       git symbolic-ref HEAD refs/heads/foo &&
+       echo ref: refs/heads/foo >expect &&
+       test_cmp expect .git/HEAD
+'
+
+test_expect_success 'symbolic-ref reads HEAD' '
+       echo refs/heads/foo >expect &&
+       git symbolic-ref HEAD >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
+       test_must_fail git symbolic-ref HEAD foo
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref refuses non-branch for HEAD' '
+       test_must_fail git symbolic-ref HEAD refs/foo
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref refuses bare sha1' '
+       echo content >file && git add file && git commit -m one
+       test_must_fail git symbolic-ref HEAD `git rev-parse HEAD`
+'
+reset_to_sane
+
+test_done