aboutsummaryrefslogtreecommitdiffstats
path: root/fsck-cache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-03 10:40:38 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-03 10:40:38 -0700
commitc33303839c76c41c9f85e5bd3f7b04fab60c38ca (patch)
tree38f671a7da0a9bd9886f437ef45fe269ee7767b4 /fsck-cache.c
parent6da4016aea2dc5bf311fea160bd8ef96ca82b999 (diff)
downloadgit-c33303839c76c41c9f85e5bd3f7b04fab60c38ca.tar.gz
Make git-fsck-cache check HEAD integrity
In particular, check that it's a symlink, and points to refs/heads/. We depend on that these days not only for "git checkout", but also because fsck and others only check for references in the .git/refs/ subdirectory, not things like HEAD itself.
Diffstat (limited to 'fsck-cache.c')
-rw-r--r--fsck-cache.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/fsck-cache.c b/fsck-cache.c
index 9867fa658b..e42264e6ce 100644
--- a/fsck-cache.c
+++ b/fsck-cache.c
@@ -342,6 +342,31 @@ static void fsck_object_dir(const char *path)
fsck_sha1_list();
}
+static int fsck_head_link(void)
+{
+ int fd, count;
+ char hex[40];
+ unsigned char sha1[20];
+ static char path[PATH_MAX], link[PATH_MAX];
+ const char *git_dir = gitenv(GIT_DIR_ENVIRONMENT) ? : DEFAULT_GIT_DIR_ENVIRONMENT;
+
+ snprintf(path, sizeof(path), "%s/HEAD", git_dir);
+ if (readlink(path, link, sizeof(link)) < 0)
+ return error("HEAD is not a symlink");
+ if (strncmp("refs/heads/", link, 11))
+ return error("HEAD points to something strange (%s)", link);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return error("HEAD: %s", strerror(errno));
+ count = read(fd, hex, sizeof(hex));
+ close(fd);
+ if (count < 0)
+ return error("HEAD: %s", strerror(errno));
+ if (count < 40 || get_sha1_hex(hex, sha1))
+ return error("HEAD: not a valid git pointer");
+ return 0;
+}
+
int main(int argc, char **argv)
{
int i, heads;
@@ -382,6 +407,7 @@ int main(int argc, char **argv)
if (standalone)
unsetenv("GIT_ALTERNATE_OBJECT_DIRECTORIES");
+ fsck_head_link();
fsck_object_dir(get_object_directory());
if (check_full) {
int j;