Merge branch 'jc/fsck' (early part)

* 'jc/fsck' (early part):
  fsck: check loose objects from alternate object stores by default
  fsck: HEAD is part of refs
maint
Junio C Hamano 2009-02-04 16:40:15 -08:00
commit 88ccb9f974
2 changed files with 51 additions and 14 deletions

View File

@ -23,6 +23,7 @@ static int check_full;
static int check_strict; static int check_strict;
static int keep_cache_objects; static int keep_cache_objects;
static unsigned char head_sha1[20]; static unsigned char head_sha1[20];
static const char *head_points_at;
static int errors_found; static int errors_found;
static int write_lost_and_found; static int write_lost_and_found;
static int verbose; 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) 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); for_each_ref(fsck_handle_ref, NULL);
if (include_reflogs) if (include_reflogs)
for_each_reflog(fsck_handle_reflog, NULL); 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) static int fsck_head_link(void)
{ {
unsigned char sha1[20];
int flag; int flag;
int null_is_error = 0; int null_is_error = 0;
const char *head_points_at = resolve_ref("HEAD", sha1, 0, &flag);


if (verbose) if (verbose)
fprintf(stderr, "Checking HEAD link\n"); fprintf(stderr, "Checking HEAD link\n");


head_points_at = resolve_ref("HEAD", head_sha1, 0, &flag);
if (!head_points_at) if (!head_points_at)
return error("Invalid HEAD"); return error("Invalid HEAD");
if (!strcmp(head_points_at, "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/")) else if (prefixcmp(head_points_at, "refs/heads/"))
return error("HEAD points to something strange (%s)", return error("HEAD points to something strange (%s)",
head_points_at); head_points_at);
if (is_null_sha1(sha1)) { if (is_null_sha1(head_sha1)) {
if (null_is_error) if (null_is_error)
return error("HEAD: detached HEAD points at nothing"); return error("HEAD: detached HEAD points at nothing");
fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n", fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
@ -584,6 +586,7 @@ static struct option fsck_opts[] = {
int cmd_fsck(int argc, const char **argv, const char *prefix) int cmd_fsck(int argc, const char **argv, const char *prefix)
{ {
int i, heads; int i, heads;
struct alternate_object_database *alt;


errors_found = 0; errors_found = 0;


@ -595,9 +598,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)


fsck_head_link(); fsck_head_link();
fsck_object_dir(get_object_directory()); fsck_object_dir(get_object_directory());
if (check_full) {
struct alternate_object_database *alt;
struct packed_git *p;
prepare_alt_odb(); prepare_alt_odb();
for (alt = alt_odb_list; alt; alt = alt->next) { for (alt = alt_odb_list; alt; alt = alt->next) {
char namebuf[PATH_MAX]; char namebuf[PATH_MAX];
@ -606,6 +607,10 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
namebuf[namelen - 1] = 0; namebuf[namelen - 1] = 0;
fsck_object_dir(namebuf); fsck_object_dir(namebuf);
} }

if (check_full) {
struct packed_git *p;

prepare_packed_git(); prepare_packed_git();
for (p = packed_git; p; p = p->next) for (p = packed_git; p; p = p->next)
/* verify gives error messages itself */ /* verify gives error messages itself */
@ -624,8 +629,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
heads = 0; heads = 0;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
if (!get_sha1(arg, head_sha1)) { unsigned char sha1[20];
struct object *obj = lookup_object(head_sha1); if (!get_sha1(arg, sha1)) {
struct object *obj = lookup_object(sha1);


/* Error is printed by lookup_object(). */ /* Error is printed by lookup_object(). */
if (!obj) if (!obj)

31
t/t1450-fsck.sh Executable file
View File

@ -0,0 +1,31 @@
#!/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_expect_success 'loose objects borrowed from alternate are not missing' '
mkdir another &&
(
cd another &&
git init &&
echo ../../../.git/objects >.git/objects/info/alternates &&
test_commit C fileC one &&
git fsck >out &&
! grep "missing blob" out
)
'

test_done