fsck: HEAD is part of refs
authorJunio C Hamano <gitster@pobox.com>
Fri, 30 Jan 2009 08:33:00 +0000 (00:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 31 Jan 2009 03:23:22 +0000 (19:23 -0800)
By default we looked at all refs but not HEAD.  The only thing that made
fsck not lose sight of commits that are only reachable from a detached
HEAD was the reflog for the HEAD.

This fixes it, with a new test.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-fsck.c
t/t1450-fsck.sh [new file with mode: 0755]

index aecc8280a0aedb37437ccce446f3382ccba08829..2cfff43f3392d9207362506524a1a28fa0c44b1f 100644 (file)
@@ -23,6 +23,7 @@ static int check_full;
 static int check_strict;
 static int keep_cache_objects;
 static unsigned char head_sha1[20];
+static const char *head_points_at;
 static int errors_found;
 static int write_lost_and_found;
 static int verbose;
@@ -473,6 +474,8 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
 
 static void get_default_heads(void)
 {
+       if (head_points_at && !is_null_sha1(head_sha1))
+               fsck_handle_ref("HEAD", head_sha1, 0, NULL);
        for_each_ref(fsck_handle_ref, NULL);
        if (include_reflogs)
                for_each_reflog(fsck_handle_reflog, NULL);
@@ -512,14 +515,13 @@ static void fsck_object_dir(const char *path)
 
 static int fsck_head_link(void)
 {
-       unsigned char sha1[20];
        int flag;
        int null_is_error = 0;
-       const char *head_points_at = resolve_ref("HEAD", sha1, 0, &flag);
 
        if (verbose)
                fprintf(stderr, "Checking HEAD link\n");
 
+       head_points_at = resolve_ref("HEAD", head_sha1, 0, &flag);
        if (!head_points_at)
                return error("Invalid HEAD");
        if (!strcmp(head_points_at, "HEAD"))
@@ -528,7 +530,7 @@ static int fsck_head_link(void)
        else if (prefixcmp(head_points_at, "refs/heads/"))
                return error("HEAD points to something strange (%s)",
                             head_points_at);
-       if (is_null_sha1(sha1)) {
+       if (is_null_sha1(head_sha1)) {
                if (null_is_error)
                        return error("HEAD: detached HEAD points at nothing");
                fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
@@ -624,8 +626,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
        heads = 0;
        for (i = 0; i < argc; i++) {
                const char *arg = argv[i];
-               if (!get_sha1(arg, head_sha1)) {
-                       struct object *obj = lookup_object(head_sha1);
+               unsigned char sha1[20];
+               if (!get_sha1(arg, sha1)) {
+                       struct object *obj = lookup_object(sha1);
 
                        /* Error is printed by lookup_object(). */
                        if (!obj)
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
new file mode 100755 (executable)
index 0000000..d3a17b4
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+test_description='git fsck random collection of tests'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+       test_commit A fileA one &&
+       git checkout HEAD^0 &&
+       test_commit B fileB two &&
+       git tag -d A B &&
+       git reflog expire --expire=now --all
+'
+
+test_expect_success 'HEAD is part of refs' '
+       test 0 = $(git fsck | wc -l)
+'
+
+test_done