summaryrefslogtreecommitdiff
path: root/sha1_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/sha1_file.c b/sha1_file.c
index 6628f06da3..59a4ed2ed3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -277,31 +277,26 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
return buf->buf;
}
-/*
- * Return the name of the pack or index file with the specified sha1
- * in its filename. *base and *name are scratch space that must be
- * provided by the caller. which should be "pack" or "idx".
- */
-static char *sha1_get_pack_name(const unsigned char *sha1,
- struct strbuf *buf,
- const char *which)
+ char *odb_pack_name(struct strbuf *buf,
+ const unsigned char *sha1,
+ const char *ext)
{
strbuf_reset(buf);
strbuf_addf(buf, "%s/pack/pack-%s.%s", get_object_directory(),
- sha1_to_hex(sha1), which);
+ sha1_to_hex(sha1), ext);
return buf->buf;
}
char *sha1_pack_name(const unsigned char *sha1)
{
static struct strbuf buf = STRBUF_INIT;
- return sha1_get_pack_name(sha1, &buf, "pack");
+ return odb_pack_name(&buf, sha1, "pack");
}
char *sha1_pack_index_name(const unsigned char *sha1)
{
static struct strbuf buf = STRBUF_INIT;
- return sha1_get_pack_name(sha1, &buf, "idx");
+ return odb_pack_name(&buf, sha1, "idx");
}
struct alternate_object_database *alt_odb_list;
@@ -667,7 +662,7 @@ static int freshen_file(const char *fn)
* either does not exist on disk, or has a stale mtime and may be subject to
* pruning).
*/
-static int check_and_freshen_file(const char *fn, int freshen)
+int check_and_freshen_file(const char *fn, int freshen)
{
if (access(fn, F_OK))
return 0;
@@ -1611,7 +1606,7 @@ static void mark_bad_packed_object(struct packed_git *p,
if (!hashcmp(sha1, p->bad_object_sha1 + GIT_SHA1_RAWSZ * i))
return;
p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
- st_mult(GIT_SHA1_RAWSZ,
+ st_mult(GIT_MAX_RAWSZ,
st_add(p->num_bad_objects, 1)));
hashcpy(p->bad_object_sha1 + GIT_SHA1_RAWSZ * p->num_bad_objects, sha1);
p->num_bad_objects++;
@@ -2606,6 +2601,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
while (delta_stack_nr) {
void *delta_data;
void *base = data;
+ void *external_base = NULL;
unsigned long delta_size, base_size = size;
int i;
@@ -2632,6 +2628,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
p->pack_name);
mark_bad_packed_object(p, base_sha1);
base = read_object(base_sha1, &type, &base_size);
+ external_base = base;
}
}
@@ -2650,6 +2647,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
"at offset %"PRIuMAX" from %s",
(uintmax_t)curpos, p->pack_name);
data = NULL;
+ free(external_base);
continue;
}
@@ -2669,6 +2667,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
error("failed to apply delta");
free(delta_data);
+ free(external_base);
}
*final_type = type;
@@ -2702,6 +2701,17 @@ const unsigned char *nth_packed_object_sha1(struct packed_git *p,
}
}
+const struct object_id *nth_packed_object_oid(struct object_id *oid,
+ struct packed_git *p,
+ uint32_t n)
+{
+ const unsigned char *hash = nth_packed_object_sha1(p, n);
+ if (!hash)
+ return NULL;
+ hashcpy(oid->hash, hash);
+ return oid;
+}
+
void check_pack_index_ptr(const struct packed_git *p, const void *vptr)
{
const unsigned char *ptr = vptr;
@@ -2942,7 +2952,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
if (status && oi->typep)
*oi->typep = status;
strbuf_release(&hdrbuf);
- return 0;
+ return (status < 0) ? status : 0;
}
int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags)
@@ -3471,6 +3481,8 @@ int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
{
struct pack_entry e;
+ if (!startup_info->have_repository)
+ return 0;
if (find_pack_entry(sha1, &e))
return 1;
if (has_loose_object(sha1))
@@ -3748,15 +3760,15 @@ static int for_each_file_in_obj_subdir(int subdir_nr,
strbuf_setlen(path, baselen);
strbuf_addf(path, "/%s", de->d_name);
- if (strlen(de->d_name) == 38) {
- char hex[41];
- unsigned char sha1[20];
+ if (strlen(de->d_name) == GIT_SHA1_HEXSZ - 2) {
+ char hex[GIT_MAX_HEXSZ+1];
+ struct object_id oid;
- snprintf(hex, sizeof(hex), "%02x%s",
- subdir_nr, de->d_name);
- if (!get_sha1_hex(hex, sha1)) {
+ xsnprintf(hex, sizeof(hex), "%02x%s",
+ subdir_nr, de->d_name);
+ if (!get_oid_hex(hex, &oid)) {
if (obj_cb) {
- r = obj_cb(sha1, path->buf, data);
+ r = obj_cb(&oid, path->buf, data);
if (r)
break;
}
@@ -3862,13 +3874,13 @@ static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn c
int r = 0;
for (i = 0; i < p->num_objects; i++) {
- const unsigned char *sha1 = nth_packed_object_sha1(p, i);
+ struct object_id oid;
- if (!sha1)
+ if (!nth_packed_object_oid(&oid, p, i))
return error("unable to get sha1 of object %u in %s",
i, p->pack_name);
- r = cb(sha1, p, i, data);
+ r = cb(&oid, p, i, data);
if (r)
break;
}
@@ -3903,7 +3915,7 @@ static int check_stream_sha1(git_zstream *stream,
const unsigned char *expected_sha1)
{
git_SHA_CTX c;
- unsigned char real_sha1[GIT_SHA1_RAWSZ];
+ unsigned char real_sha1[GIT_MAX_RAWSZ];
unsigned char buf[4096];
unsigned long total_read;
int status = Z_OK;
@@ -3960,7 +3972,6 @@ int read_loose_object(const char *path,
void **contents)
{
int ret = -1;
- int fd = -1;
void *map = NULL;
unsigned long mapsize;
git_zstream stream;
@@ -4010,7 +4021,5 @@ int read_loose_object(const char *path,
out:
if (map)
munmap(map, mapsize);
- if (fd >= 0)
- close(fd);
return ret;
}