mirror of
https://github.com/git/git
synced 2024-08-24 10:15:51 +00:00
Merge fighting fsck-cache updates from Junio
It's just easier to let git help out with the merge than it is to try to fix up the diffs.
This commit is contained in:
commit
fead2836a1
|
@ -9,7 +9,7 @@ git-fsck-cache - Verifies the connectivity and validity of the objects in the da
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-fsck-cache' [--tags] [--root] [--unreachable] [--cache] [<object>*]
|
||||
'git-fsck-cache' [--tags] [--root] [--unreachable] [--cache] [--standalone | --full] [<object>*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -37,6 +37,22 @@ OPTIONS
|
|||
Consider any object recorded in the cache also as a head node for
|
||||
an unreachability trace.
|
||||
|
||||
--standalone::
|
||||
Limit checks to the contents of GIT_OBJECT_DIRECTORY
|
||||
(.git/objects), making sure that it is consistent and
|
||||
complete without referring to objects found in alternate
|
||||
object pools listed in GIT_ALTERNATE_OBJECT_DIRECTORIES,
|
||||
nor packed GIT archives found in .git/objects/pack;
|
||||
cannot be used with --full.
|
||||
|
||||
--full::
|
||||
Check not just objects in GIT_OBJECT_DIRECTORY
|
||||
(.git/objects), but also the ones found in alternate
|
||||
object pools listed in GIT_ALTERNATE_OBJECT_DIRECTORIES,
|
||||
and in packed GIT archives found in .git/objects/pack
|
||||
and corresponding pack subdirectories in alternate
|
||||
object pools; cannot be used with --standalone.
|
||||
|
||||
It tests SHA1 and general object sanity, and it does full tracking of
|
||||
the resulting reachability and everything else. It prints out any
|
||||
corruption it finds (missing or bad objects), and if you use the
|
||||
|
|
19
cache.h
19
cache.h
|
@ -233,4 +233,23 @@ struct checkout {
|
|||
|
||||
extern int checkout_entry(struct cache_entry *ce, struct checkout *state);
|
||||
|
||||
extern struct alternate_object_database {
|
||||
char *base;
|
||||
char *name;
|
||||
} *alt_odb;
|
||||
extern void prepare_alt_odb(void);
|
||||
|
||||
extern struct packed_git {
|
||||
struct packed_git *next;
|
||||
unsigned long index_size;
|
||||
unsigned long pack_size;
|
||||
unsigned int *index_base;
|
||||
void *pack_base;
|
||||
unsigned int pack_last_used;
|
||||
char pack_name[0]; /* something like ".git/objects/pack/xxxxx.pack" */
|
||||
} *packed_git;
|
||||
extern void prepare_packed_git(void);
|
||||
extern int num_packed_objects(const struct packed_git *p);
|
||||
extern int nth_packed_object_sha1(const struct packed_git *, int, unsigned char*);
|
||||
|
||||
#endif /* CACHE_H */
|
||||
|
|
51
fsck-cache.c
51
fsck-cache.c
|
@ -13,6 +13,7 @@ static int show_root = 0;
|
|||
static int show_tags = 0;
|
||||
static int show_unreachable = 0;
|
||||
static int standalone = 0;
|
||||
static int check_full = 0;
|
||||
static int keep_cache_objects = 0;
|
||||
static unsigned char head_sha1[20];
|
||||
|
||||
|
@ -374,10 +375,20 @@ static void get_default_heads(void)
|
|||
die("No default references");
|
||||
}
|
||||
|
||||
static void fsck_object_dir(const char *path)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
static char dir[4096];
|
||||
sprintf(dir, "%s/%02x", path, i);
|
||||
fsck_dir(i, dir);
|
||||
}
|
||||
fsck_sha1_list();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, heads;
|
||||
char *sha1_dir;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
|
@ -402,17 +413,41 @@ int main(int argc, char **argv)
|
|||
standalone = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--full")) {
|
||||
check_full = 1;
|
||||
continue;
|
||||
}
|
||||
if (*arg == '-')
|
||||
usage("git-fsck-cache [--tags] [[--unreachable] [--cache] <head-sha1>*]");
|
||||
usage("git-fsck-cache [--tags] [[--unreachable] [--cache] [--standalone | --full] <head-sha1>*]");
|
||||
}
|
||||
|
||||
sha1_dir = get_object_directory();
|
||||
for (i = 0; i < 256; i++) {
|
||||
static char dir[4096];
|
||||
sprintf(dir, "%s/%02x", sha1_dir, i);
|
||||
fsck_dir(i, dir);
|
||||
if (standalone && check_full)
|
||||
die("Only one of --standalone or --full can be used.");
|
||||
if (standalone)
|
||||
unsetenv("GIT_ALTERNATE_OBJECT_DIRECTORIES");
|
||||
|
||||
fsck_object_dir(get_object_directory());
|
||||
if (check_full) {
|
||||
int j;
|
||||
struct packed_git *p;
|
||||
prepare_alt_odb();
|
||||
for (j = 0; alt_odb[j].base; j++) {
|
||||
alt_odb[j].name[-1] = 0; /* was slash */
|
||||
fsck_object_dir(alt_odb[j].base);
|
||||
alt_odb[j].name[-1] = '/';
|
||||
}
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
int num = num_packed_objects(p);
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned char sha1[20];
|
||||
nth_packed_object_sha1(p, i, sha1);
|
||||
if (fsck_sha1(sha1) < 0)
|
||||
fprintf(stderr, "bad sha1 entry '%s'\n", sha1_to_hex(sha1));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
fsck_sha1_list();
|
||||
|
||||
heads = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
|
|
43
sha1_file.c
43
sha1_file.c
|
@ -185,10 +185,7 @@ char *sha1_file_name(const unsigned char *sha1)
|
|||
return base;
|
||||
}
|
||||
|
||||
static struct alternate_object_database {
|
||||
char *base;
|
||||
char *name;
|
||||
} *alt_odb;
|
||||
struct alternate_object_database *alt_odb;
|
||||
|
||||
/*
|
||||
* Prepare alternate object database registry.
|
||||
|
@ -206,13 +203,15 @@ static struct alternate_object_database {
|
|||
* pointed by base fields of the array elements with one xmalloc();
|
||||
* the string pool immediately follows the array.
|
||||
*/
|
||||
static void prepare_alt_odb(void)
|
||||
void prepare_alt_odb(void)
|
||||
{
|
||||
int pass, totlen, i;
|
||||
const char *cp, *last;
|
||||
char *op = NULL;
|
||||
const char *alt = gitenv(ALTERNATE_DB_ENVIRONMENT) ? : "";
|
||||
|
||||
if (alt_odb)
|
||||
return;
|
||||
/* The first pass counts how large an area to allocate to
|
||||
* hold the entire alt_odb structure, including array of
|
||||
* structs and path buffers for them. The second pass fills
|
||||
|
@ -259,8 +258,7 @@ static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
|
|||
|
||||
if (!stat(name, st))
|
||||
return name;
|
||||
if (!alt_odb)
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb();
|
||||
for (i = 0; (name = alt_odb[i].name) != NULL; i++) {
|
||||
fill_sha1_path(name, sha1);
|
||||
if (!stat(alt_odb[i].base, st))
|
||||
|
@ -272,15 +270,7 @@ static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
|
|||
#define PACK_MAX_SZ (1<<26)
|
||||
static int pack_used_ctr;
|
||||
static unsigned long pack_mapped;
|
||||
static struct packed_git {
|
||||
struct packed_git *next;
|
||||
unsigned long index_size;
|
||||
unsigned long pack_size;
|
||||
unsigned int *index_base;
|
||||
void *pack_base;
|
||||
unsigned int pack_last_used;
|
||||
char pack_name[0]; /* something like ".git/objects/pack/xxxxx.pack" */
|
||||
} *packed_git;
|
||||
struct packed_git *packed_git;
|
||||
|
||||
struct pack_entry {
|
||||
unsigned int offset;
|
||||
|
@ -431,7 +421,7 @@ static void prepare_packed_git_one(char *objdir)
|
|||
}
|
||||
}
|
||||
|
||||
static void prepare_packed_git(void)
|
||||
void prepare_packed_git(void)
|
||||
{
|
||||
int i;
|
||||
static int run_once = 0;
|
||||
|
@ -440,8 +430,7 @@ static void prepare_packed_git(void)
|
|||
return;
|
||||
|
||||
prepare_packed_git_one(get_object_directory());
|
||||
if (!alt_odb)
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb();
|
||||
for (i = 0; alt_odb[i].base != NULL; i++) {
|
||||
alt_odb[i].name[0] = 0;
|
||||
prepare_packed_git_one(alt_odb[i].base);
|
||||
|
@ -842,6 +831,22 @@ static void *unpack_entry(struct pack_entry *entry,
|
|||
return unpack_non_delta_entry(pack, size, left);
|
||||
}
|
||||
|
||||
int num_packed_objects(const struct packed_git *p)
|
||||
{
|
||||
/* See check_packed_git_idx and pack-objects.c */
|
||||
return (p->index_size - 20 - 20 - 4*256) / 24;
|
||||
}
|
||||
|
||||
int nth_packed_object_sha1(const struct packed_git *p, int n,
|
||||
unsigned char* sha1)
|
||||
{
|
||||
void *index = p->index_base + 256;
|
||||
if (n < 0 || num_packed_objects(p) <= n)
|
||||
return -1;
|
||||
memcpy(sha1, (index + 24 * n + 4), 20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_pack_entry_1(const unsigned char *sha1,
|
||||
struct pack_entry *e, struct packed_git *p)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue