Merge branch 'ab/object-file-api-updates'
Object-file API shuffling. * ab/object-file-api-updates: object-file API: pass an enum to read_object_with_reference() object-file.c: add a literal version of write_object_file_prepare() object-file API: have hash_object_file() take "enum object_type" object API: rename hash_object_file_literally() to write_*() object-file API: split up and simplify check_object_signature() object API users + docs: check <0, not !0 with check_object_signature() object API docs: move check_object_signature() docs to cache.h object API: correct "buf" v.s. "map" mismatch in *.c and *.h object-file API: have write_object_file() take "enum object_type" object-file API: add a format_object_header() function object-file API: return "void", not "int" from hash_object_file() object-file.c: split up declaration of unrelated variables
This commit is contained in:
151
object-file.c
151
object-file.c
@ -1049,35 +1049,50 @@ void *xmmap(void *start, size_t length,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* With an in-core object data in "map", rehash it to make sure the
|
||||
* object name actually matches "oid" to detect object corruption.
|
||||
* With "map" == NULL, try reading the object named with "oid" using
|
||||
* the streaming interface and rehash it to do the same.
|
||||
*/
|
||||
int check_object_signature(struct repository *r, const struct object_id *oid,
|
||||
void *map, unsigned long size, const char *type,
|
||||
struct object_id *real_oidp)
|
||||
static int format_object_header_literally(char *str, size_t size,
|
||||
const char *type, size_t objsize)
|
||||
{
|
||||
struct object_id tmp;
|
||||
struct object_id *real_oid = real_oidp ? real_oidp : &tmp;
|
||||
return xsnprintf(str, size, "%s %"PRIuMAX, type, (uintmax_t)objsize) + 1;
|
||||
}
|
||||
|
||||
int format_object_header(char *str, size_t size, enum object_type type,
|
||||
size_t objsize)
|
||||
{
|
||||
const char *name = type_name(type);
|
||||
|
||||
if (!name)
|
||||
BUG("could not get a type name for 'enum object_type' value %d", type);
|
||||
|
||||
return format_object_header_literally(str, size, name, objsize);
|
||||
}
|
||||
|
||||
int check_object_signature(struct repository *r, const struct object_id *oid,
|
||||
void *buf, unsigned long size,
|
||||
enum object_type type)
|
||||
{
|
||||
struct object_id real_oid;
|
||||
|
||||
hash_object_file(r->hash_algo, buf, size, type, &real_oid);
|
||||
|
||||
return !oideq(oid, &real_oid) ? -1 : 0;
|
||||
}
|
||||
|
||||
int stream_object_signature(struct repository *r, const struct object_id *oid)
|
||||
{
|
||||
struct object_id real_oid;
|
||||
unsigned long size;
|
||||
enum object_type obj_type;
|
||||
struct git_istream *st;
|
||||
git_hash_ctx c;
|
||||
char hdr[MAX_HEADER_LEN];
|
||||
int hdrlen;
|
||||
|
||||
if (map) {
|
||||
hash_object_file(r->hash_algo, map, size, type, real_oid);
|
||||
return !oideq(oid, real_oid) ? -1 : 0;
|
||||
}
|
||||
|
||||
st = open_istream(r, oid, &obj_type, &size, NULL);
|
||||
if (!st)
|
||||
return -1;
|
||||
|
||||
/* Generate the header */
|
||||
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1;
|
||||
hdrlen = format_object_header(hdr, sizeof(hdr), obj_type, size);
|
||||
|
||||
/* Sha1.. */
|
||||
r->hash_algo->init_fn(&c);
|
||||
@ -1094,9 +1109,9 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
|
||||
break;
|
||||
r->hash_algo->update_fn(&c, buf, readlen);
|
||||
}
|
||||
r->hash_algo->final_oid_fn(real_oid, &c);
|
||||
r->hash_algo->final_oid_fn(&real_oid, &c);
|
||||
close_istream(st);
|
||||
return !oideq(oid, real_oid) ? -1 : 0;
|
||||
return !oideq(oid, &real_oid) ? -1 : 0;
|
||||
}
|
||||
|
||||
int git_open_cloexec(const char *name, int flags)
|
||||
@ -1662,7 +1677,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
|
||||
{
|
||||
struct cached_object *co;
|
||||
|
||||
hash_object_file(the_hash_algo, buf, len, type_name(type), oid);
|
||||
hash_object_file(the_hash_algo, buf, len, type, oid);
|
||||
if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) ||
|
||||
find_cached_object(oid))
|
||||
return 0;
|
||||
@ -1722,16 +1737,15 @@ void *read_object_file_extended(struct repository *r,
|
||||
|
||||
void *read_object_with_reference(struct repository *r,
|
||||
const struct object_id *oid,
|
||||
const char *required_type_name,
|
||||
enum object_type required_type,
|
||||
unsigned long *size,
|
||||
struct object_id *actual_oid_return)
|
||||
{
|
||||
enum object_type type, required_type;
|
||||
enum object_type type;
|
||||
void *buffer;
|
||||
unsigned long isize;
|
||||
struct object_id actual_oid;
|
||||
|
||||
required_type = type_from_string(required_type_name);
|
||||
oidcpy(&actual_oid, oid);
|
||||
while (1) {
|
||||
int ref_length = -1;
|
||||
@ -1769,21 +1783,40 @@ void *read_object_with_reference(struct repository *r,
|
||||
}
|
||||
}
|
||||
|
||||
static void hash_object_body(const struct git_hash_algo *algo, git_hash_ctx *c,
|
||||
const void *buf, unsigned long len,
|
||||
struct object_id *oid,
|
||||
char *hdr, int *hdrlen)
|
||||
{
|
||||
algo->init_fn(c);
|
||||
algo->update_fn(c, hdr, *hdrlen);
|
||||
algo->update_fn(c, buf, len);
|
||||
algo->final_oid_fn(oid, c);
|
||||
}
|
||||
|
||||
static void write_object_file_prepare(const struct git_hash_algo *algo,
|
||||
const void *buf, unsigned long len,
|
||||
enum object_type type, struct object_id *oid,
|
||||
char *hdr, int *hdrlen)
|
||||
{
|
||||
git_hash_ctx c;
|
||||
|
||||
/* Generate the header */
|
||||
*hdrlen = format_object_header(hdr, *hdrlen, type, len);
|
||||
|
||||
/* Sha1.. */
|
||||
hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
|
||||
}
|
||||
|
||||
static void write_object_file_prepare_literally(const struct git_hash_algo *algo,
|
||||
const void *buf, unsigned long len,
|
||||
const char *type, struct object_id *oid,
|
||||
char *hdr, int *hdrlen)
|
||||
{
|
||||
git_hash_ctx c;
|
||||
|
||||
/* Generate the header */
|
||||
*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
|
||||
|
||||
/* Sha1.. */
|
||||
algo->init_fn(&c);
|
||||
algo->update_fn(&c, hdr, *hdrlen);
|
||||
algo->update_fn(&c, buf, len);
|
||||
algo->final_oid_fn(oid, &c);
|
||||
*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
|
||||
hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1836,14 +1869,21 @@ static int write_buffer(int fd, const void *buf, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hash_object_file(const struct git_hash_algo *algo, const void *buf,
|
||||
unsigned long len, const char *type,
|
||||
struct object_id *oid)
|
||||
static void hash_object_file_literally(const struct git_hash_algo *algo,
|
||||
const void *buf, unsigned long len,
|
||||
const char *type, struct object_id *oid)
|
||||
{
|
||||
char hdr[MAX_HEADER_LEN];
|
||||
int hdrlen = sizeof(hdr);
|
||||
write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
|
||||
return 0;
|
||||
|
||||
write_object_file_prepare_literally(algo, buf, len, type, oid, hdr, &hdrlen);
|
||||
}
|
||||
|
||||
void hash_object_file(const struct git_hash_algo *algo, const void *buf,
|
||||
unsigned long len, enum object_type type,
|
||||
struct object_id *oid)
|
||||
{
|
||||
hash_object_file_literally(algo, buf, len, type_name(type), oid);
|
||||
}
|
||||
|
||||
/* Finalize a file on disk, and close it. */
|
||||
@ -1998,7 +2038,7 @@ static int freshen_packed_object(const struct object_id *oid)
|
||||
}
|
||||
|
||||
int write_object_file_flags(const void *buf, unsigned long len,
|
||||
const char *type, struct object_id *oid,
|
||||
enum object_type type, struct object_id *oid,
|
||||
unsigned flags)
|
||||
{
|
||||
char hdr[MAX_HEADER_LEN];
|
||||
@ -2014,9 +2054,9 @@ int write_object_file_flags(const void *buf, unsigned long len,
|
||||
return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
|
||||
}
|
||||
|
||||
int hash_object_file_literally(const void *buf, unsigned long len,
|
||||
const char *type, struct object_id *oid,
|
||||
unsigned flags)
|
||||
int write_object_file_literally(const void *buf, unsigned long len,
|
||||
const char *type, struct object_id *oid,
|
||||
unsigned flags)
|
||||
{
|
||||
char *header;
|
||||
int hdrlen, status = 0;
|
||||
@ -2024,8 +2064,8 @@ int hash_object_file_literally(const void *buf, unsigned long len,
|
||||
/* type string, SP, %lu of the length plus NUL must fit this */
|
||||
hdrlen = strlen(type) + MAX_HEADER_LEN;
|
||||
header = xmalloc(hdrlen);
|
||||
write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
|
||||
&hdrlen);
|
||||
write_object_file_prepare_literally(the_hash_algo, buf, len, type,
|
||||
oid, header, &hdrlen);
|
||||
|
||||
if (!(flags & HASH_WRITE_OBJECT))
|
||||
goto cleanup;
|
||||
@ -2052,7 +2092,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
|
||||
buf = read_object(the_repository, oid, &type, &len);
|
||||
if (!buf)
|
||||
return error(_("cannot read object for %s"), oid_to_hex(oid));
|
||||
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
|
||||
hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
|
||||
ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0);
|
||||
free(buf);
|
||||
|
||||
@ -2118,7 +2158,8 @@ static int index_mem(struct index_state *istate,
|
||||
enum object_type type,
|
||||
const char *path, unsigned flags)
|
||||
{
|
||||
int ret, re_allocated = 0;
|
||||
int ret = 0;
|
||||
int re_allocated = 0;
|
||||
int write_object = flags & HASH_WRITE_OBJECT;
|
||||
|
||||
if (!type)
|
||||
@ -2145,10 +2186,9 @@ static int index_mem(struct index_state *istate,
|
||||
}
|
||||
|
||||
if (write_object)
|
||||
ret = write_object_file(buf, size, type_name(type), oid);
|
||||
ret = write_object_file(buf, size, type, oid);
|
||||
else
|
||||
ret = hash_object_file(the_hash_algo, buf, size,
|
||||
type_name(type), oid);
|
||||
hash_object_file(the_hash_algo, buf, size, type, oid);
|
||||
if (re_allocated)
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -2160,7 +2200,7 @@ static int index_stream_convert_blob(struct index_state *istate,
|
||||
const char *path,
|
||||
unsigned flags)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
const int write_object = flags & HASH_WRITE_OBJECT;
|
||||
struct strbuf sbuf = STRBUF_INIT;
|
||||
|
||||
@ -2171,11 +2211,11 @@ static int index_stream_convert_blob(struct index_state *istate,
|
||||
get_conv_flags(flags));
|
||||
|
||||
if (write_object)
|
||||
ret = write_object_file(sbuf.buf, sbuf.len, type_name(OBJ_BLOB),
|
||||
ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB,
|
||||
oid);
|
||||
else
|
||||
ret = hash_object_file(the_hash_algo, sbuf.buf, sbuf.len,
|
||||
type_name(OBJ_BLOB), oid);
|
||||
hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB,
|
||||
oid);
|
||||
strbuf_release(&sbuf);
|
||||
return ret;
|
||||
}
|
||||
@ -2294,8 +2334,8 @@ int index_path(struct index_state *istate, struct object_id *oid,
|
||||
return error_errno("readlink(\"%s\")", path);
|
||||
if (!(flags & HASH_WRITE_OBJECT))
|
||||
hash_object_file(the_hash_algo, sb.buf, sb.len,
|
||||
blob_type, oid);
|
||||
else if (write_object_file(sb.buf, sb.len, blob_type, oid))
|
||||
OBJ_BLOB, oid);
|
||||
else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid))
|
||||
rc = error(_("%s: failed to insert into database"), path);
|
||||
strbuf_release(&sb);
|
||||
break;
|
||||
@ -2599,9 +2639,10 @@ int read_loose_object(const char *path,
|
||||
git_inflate_end(&stream);
|
||||
goto out;
|
||||
}
|
||||
if (check_object_signature(the_repository, expected_oid,
|
||||
hash_object_file_literally(the_repository->hash_algo,
|
||||
*contents, *size,
|
||||
oi->type_name->buf, real_oid))
|
||||
oi->type_name->buf, real_oid);
|
||||
if (!oideq(expected_oid, real_oid))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user