X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sha1_file.c;h=12fc767ee57103739e568a959981ca559417ecf4;hb=d11ddaff021be8006e71b43a5205c48f2dac7f18;hp=1670e913af0586e4bd3777d8d99952f2b358978e;hpb=86d72443215612f66f77dfc57ec9613c8153617c;p=git.git diff --git a/sha1_file.c b/sha1_file.c index 1670e913a..12fc767ee 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -385,7 +385,7 @@ static void read_info_alternates(const char * relative_base, int depth) void add_to_alternates_file(const char *reference) { struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); - int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), 1); + int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR); char *alt = mkpath("%s/objects\n", reference); write_or_die(fd, alt, strlen(alt)); if (commit_lock_file(lock)) @@ -990,6 +990,7 @@ void prepare_packed_git(void) void reprepare_packed_git(void) { + discard_revindex(); prepare_packed_git_run_once = 0; prepare_packed_git(); } @@ -1006,6 +1007,18 @@ static void mark_bad_packed_object(struct packed_git *p, p->num_bad_objects++; } +static int has_packed_and_bad(const unsigned char *sha1) +{ + struct packed_git *p; + unsigned i; + + for (p = packed_git; p; p = p->next) + for (i = 0; i < p->num_bad_objects; i++) + if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) + return 1; + return 0; +} + int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type) { unsigned char real_sha1[20]; @@ -1630,6 +1643,7 @@ static void *unpack_delta_entry(struct packed_git *p, (uintmax_t)curpos, p->pack_name); return NULL; } + unuse_pack(w_curs); base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0); if (!base) { /* @@ -1646,7 +1660,7 @@ static void *unpack_delta_entry(struct packed_git *p, sha1_to_hex(base_sha1), (uintmax_t)base_offset, p->pack_name); mark_bad_packed_object(p, base_sha1); - base = read_sha1_file(base_sha1, type, &base_size); + base = read_object(base_sha1, type, &base_size); if (!base) return NULL; } @@ -1916,11 +1930,18 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size int sha1_object_info(const unsigned char *sha1, unsigned long *sizep) { struct pack_entry e; + int status; if (!find_pack_entry(sha1, &e, NULL)) { + /* Most likely it's a loose object. */ + status = sha1_loose_object_info(sha1, sizep); + if (status >= 0) + return status; + + /* Not a loose object; someone else may have just packed it. */ reprepare_packed_git(); if (!find_pack_entry(sha1, &e, NULL)) - return sha1_loose_object_info(sha1, sizep); + return status; } return packed_object_info(e.p, e.offset, sizep); } @@ -1944,7 +1965,7 @@ static void *read_packed_sha1(const unsigned char *sha1, error("failed to read object %s at offset %"PRIuMAX" from %s", sha1_to_hex(sha1), (uintmax_t)e.offset, e.p->pack_name); mark_bad_packed_object(e.p, sha1); - data = read_sha1_file(sha1, type, size); + data = read_object(sha1, type, size); } return data; } @@ -2009,8 +2030,8 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type, return 0; } -void *read_sha1_file(const unsigned char *sha1, enum object_type *type, - unsigned long *size) +void *read_object(const unsigned char *sha1, enum object_type *type, + unsigned long *size) { unsigned long mapsize; void *map, *buf; @@ -2036,6 +2057,16 @@ void *read_sha1_file(const unsigned char *sha1, enum object_type *type, return read_packed_sha1(sha1, type, size); } +void *read_sha1_file(const unsigned char *sha1, enum object_type *type, + unsigned long *size) +{ + void *data = read_object(sha1, type, size); + /* legacy behavior is to die on corrupted objects */ + if (!data && (has_loose_object(sha1) || has_packed_and_bad(sha1))) + die("object %s is corrupted", sha1_to_hex(sha1)); + return data; +} + void *read_object_with_reference(const unsigned char *sha1, const char *required_type_name, unsigned long *size, @@ -2105,7 +2136,9 @@ static void write_sha1_file_prepare(const void *buf, unsigned long len, */ int move_temp_to_file(const char *tmpfile, const char *filename) { - int ret = link(tmpfile, filename); + int ret = 0; + if (link(tmpfile, filename)) + ret = errno; /* * Coda hack - coda doesn't like cross-directory links, @@ -2289,6 +2322,7 @@ int force_object_loose(const unsigned char *sha1, time_t mtime) enum object_type type; char hdr[32]; int hdrlen; + int ret; if (has_loose_object(sha1)) return 0; @@ -2296,7 +2330,10 @@ int force_object_loose(const unsigned char *sha1, time_t mtime) if (!buf) return error("cannot read sha1_file for %s", sha1_to_hex(sha1)); hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1; - return write_loose_object(sha1, hdr, hdrlen, buf, len, mtime); + ret = write_loose_object(sha1, hdr, hdrlen, buf, len, mtime); + free(buf); + + return ret; } int has_pack_index(const unsigned char *sha1)