convert object type handling from a string to a number

We currently have two parallel notation for dealing with object types
in the code: a string and a numerical value.  One of them is obviously
redundent, and the most used one requires more stack space and a bunch
of strcmp() all over the place.

This is an initial step for the removal of the version using a char array
found in object reading code paths.  The patch is unfortunately large but
there is no sane way to split it in smaller parts without breaking the
system.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Nicolas Pitre 2007-02-26 14:55:59 -05:00 committed by Junio C Hamano
parent df8436622f
commit 21666f1aae
37 changed files with 265 additions and 289 deletions

View file

@ -262,7 +262,7 @@ static int write_tar_entry(const unsigned char *sha1,
static struct strbuf path; static struct strbuf path;
int filenamelen = strlen(filename); int filenamelen = strlen(filename);
void *buffer; void *buffer;
char type[20]; enum object_type type;
unsigned long size; unsigned long size;
if (!path.alloc) { if (!path.alloc) {
@ -283,7 +283,7 @@ static int write_tar_entry(const unsigned char *sha1,
buffer = NULL; buffer = NULL;
size = 0; size = 0;
} else { } else {
buffer = read_sha1_file(sha1, type, &size); buffer = read_sha1_file(sha1, &type, &size);
if (!buffer) if (!buffer)
die("cannot read %s", sha1_to_hex(sha1)); die("cannot read %s", sha1_to_hex(sha1));
} }

View file

@ -167,7 +167,7 @@ static int write_zip_entry(const unsigned char *sha1,
int pathlen; int pathlen;
unsigned char *out; unsigned char *out;
char *path; char *path;
char type[20]; enum object_type type;
void *buffer = NULL; void *buffer = NULL;
void *deflated = NULL; void *deflated = NULL;
@ -195,7 +195,7 @@ static int write_zip_entry(const unsigned char *sha1,
if (S_ISREG(mode) && zlib_compression_level != 0) if (S_ISREG(mode) && zlib_compression_level != 0)
method = 8; method = 8;
result = 0; result = 0;
buffer = read_sha1_file(sha1, type, &size); buffer = read_sha1_file(sha1, &type, &size);
if (!buffer) if (!buffer)
die("cannot read %s", sha1_to_hex(sha1)); die("cannot read %s", sha1_to_hex(sha1));
crc = crc32(crc, buffer, size); crc = crc32(crc, buffer, size);

6
blob.c
View file

@ -30,18 +30,18 @@ int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
int parse_blob(struct blob *item) int parse_blob(struct blob *item)
{ {
char type[20]; enum object_type type;
void *buffer; void *buffer;
unsigned long size; unsigned long size;
int ret; int ret;
if (item->object.parsed) if (item->object.parsed)
return 0; return 0;
buffer = read_sha1_file(item->object.sha1, type, &size); buffer = read_sha1_file(item->object.sha1, &type, &size);
if (!buffer) if (!buffer)
return error("Could not read %s", return error("Could not read %s",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
if (strcmp(type, blob_type)) if (type != OBJ_BLOB)
return error("Object %s not a blob", return error("Object %s not a blob",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
ret = parse_blob_buffer(item, buffer, size); ret = parse_blob_buffer(item, buffer, size);

View file

@ -1912,11 +1912,11 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch)
if (has_sha1_file(sha1)) { if (has_sha1_file(sha1)) {
/* We already have the postimage */ /* We already have the postimage */
char type[10]; enum object_type type;
unsigned long size; unsigned long size;
free(desc->buffer); free(desc->buffer);
desc->buffer = read_sha1_file(sha1, type, &size); desc->buffer = read_sha1_file(sha1, &type, &size);
if (!desc->buffer) if (!desc->buffer)
return error("the necessary postimage %s for " return error("the necessary postimage %s for "
"'%s' cannot be read", "'%s' cannot be read",
@ -1972,8 +1972,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
buf = NULL; buf = NULL;
if (cached) { if (cached) {
if (ce) { if (ce) {
char type[20]; enum object_type type;
buf = read_sha1_file(ce->sha1, type, &size); buf = read_sha1_file(ce->sha1, &type, &size);
if (!buf) if (!buf)
return error("read of %s failed", return error("read of %s failed",
patch->old_name); patch->old_name);

View file

@ -87,9 +87,9 @@ struct origin {
static char *fill_origin_blob(struct origin *o, mmfile_t *file) static char *fill_origin_blob(struct origin *o, mmfile_t *file)
{ {
if (!o->file.ptr) { if (!o->file.ptr) {
char type[10]; enum object_type type;
num_read_blob++; num_read_blob++;
file->ptr = read_sha1_file(o->blob_sha1, type, file->ptr = read_sha1_file(o->blob_sha1, &type,
(unsigned long *)(&(file->size))); (unsigned long *)(&(file->size)));
o->file = *file; o->file = *file;
} }
@ -263,7 +263,6 @@ static struct origin *get_origin(struct scoreboard *sb,
static int fill_blob_sha1(struct origin *origin) static int fill_blob_sha1(struct origin *origin)
{ {
unsigned mode; unsigned mode;
char type[10];
if (!is_null_sha1(origin->blob_sha1)) if (!is_null_sha1(origin->blob_sha1))
return 0; return 0;
@ -271,8 +270,7 @@ static int fill_blob_sha1(struct origin *origin)
origin->path, origin->path,
origin->blob_sha1, &mode)) origin->blob_sha1, &mode))
goto error_out; goto error_out;
if (sha1_object_info(origin->blob_sha1, type, NULL) || if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB)
strcmp(type, blob_type))
goto error_out; goto error_out;
return 0; return 0;
error_out: error_out:
@ -1322,10 +1320,10 @@ static void get_commit_info(struct commit *commit,
* we now need to populate them for output. * we now need to populate them for output.
*/ */
if (!commit->buffer) { if (!commit->buffer) {
char type[20]; enum object_type type;
unsigned long size; unsigned long size;
commit->buffer = commit->buffer =
read_sha1_file(commit->object.sha1, type, &size); read_sha1_file(commit->object.sha1, &type, &size);
} }
ret->author = author_buf; ret->author = author_buf;
get_ac_line(commit->buffer, "\nauthor ", get_ac_line(commit->buffer, "\nauthor ",
@ -2006,7 +2004,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
buf[fin_size] = 0; buf[fin_size] = 0;
origin->file.ptr = buf; origin->file.ptr = buf;
origin->file.size = fin_size; origin->file.size = fin_size;
pretend_sha1_file(buf, fin_size, blob_type, origin->blob_sha1); pretend_sha1_file(buf, fin_size, OBJ_BLOB, origin->blob_sha1);
commit->util = origin; commit->util = origin;
/* /*
@ -2068,7 +2066,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
int show_stats = 0; int show_stats = 0;
const char *revs_file = NULL; const char *revs_file = NULL;
const char *final_commit_name = NULL; const char *final_commit_name = NULL;
char type[10]; enum object_type type;
const char *bottomtop = NULL; const char *bottomtop = NULL;
const char *contents_from = NULL; const char *contents_from = NULL;
@ -2302,7 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
if (fill_blob_sha1(o)) if (fill_blob_sha1(o))
die("no such path %s in %s", path, final_commit_name); die("no such path %s in %s", path, final_commit_name);
sb.final_buf = read_sha1_file(o->blob_sha1, type, sb.final_buf = read_sha1_file(o->blob_sha1, &type,
&sb.final_buf_size); &sb.final_buf_size);
} }
num_read_blob++; num_read_blob++;

View file

@ -79,7 +79,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
int cmd_cat_file(int argc, const char **argv, const char *prefix) int cmd_cat_file(int argc, const char **argv, const char *prefix)
{ {
unsigned char sha1[20]; unsigned char sha1[20];
char type[20]; enum object_type type;
void *buf; void *buf;
unsigned long size; unsigned long size;
int opt; int opt;
@ -100,14 +100,16 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
buf = NULL; buf = NULL;
switch (opt) { switch (opt) {
case 't': case 't':
if (!sha1_object_info(sha1, type, NULL)) { type = sha1_object_info(sha1, NULL);
printf("%s\n", type); if (type > 0) {
printf("%s\n", typename(type));
return 0; return 0;
} }
break; break;
case 's': case 's':
if (!sha1_object_info(sha1, type, &size)) { type = sha1_object_info(sha1, &size);
if (type > 0) {
printf("%lu\n", size); printf("%lu\n", size);
return 0; return 0;
} }
@ -117,17 +119,18 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
return !has_sha1_file(sha1); return !has_sha1_file(sha1);
case 'p': case 'p':
if (sha1_object_info(sha1, type, NULL)) type = sha1_object_info(sha1, NULL);
if (type < 0)
die("Not a valid object name %s", argv[2]); die("Not a valid object name %s", argv[2]);
/* custom pretty-print here */ /* custom pretty-print here */
if (!strcmp(type, tree_type)) if (type == OBJ_TREE)
return cmd_ls_tree(2, argv + 1, NULL); return cmd_ls_tree(2, argv + 1, NULL);
buf = read_sha1_file(sha1, type, &size); buf = read_sha1_file(sha1, &type, &size);
if (!buf) if (!buf)
die("Cannot read object %s", argv[2]); die("Cannot read object %s", argv[2]);
if (!strcmp(type, tag_type)) { if (type == OBJ_TAG) {
pprint_tag(sha1, buf, size); pprint_tag(sha1, buf, size);
return 0; return 0;
} }

View file

@ -47,11 +47,10 @@ static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
static void check_valid(unsigned char *sha1, const char *expect) static void check_valid(unsigned char *sha1, const char *expect)
{ {
char type[20]; enum object_type type = sha1_object_info(sha1, NULL);
if (type < 0)
if (sha1_object_info(sha1, type, NULL))
die("%s is not a valid object", sha1_to_hex(sha1)); die("%s is not a valid object", sha1_to_hex(sha1));
if (expect && strcmp(type, expect)) if (expect && type != type_from_string(expect))
die("%s is not a valid '%s' object", sha1_to_hex(sha1), die("%s is not a valid '%s' object", sha1_to_hex(sha1),
expect); expect);
} }

View file

@ -173,8 +173,8 @@ static void verify_format(const char *format)
*/ */
static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten) static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned long *sz, int *eaten)
{ {
char type[20]; enum object_type type;
void *buf = read_sha1_file(sha1, type, sz); void *buf = read_sha1_file(sha1, &type, sz);
if (buf) if (buf)
*obj = parse_object_buffer(sha1, type, *sz, buf, eaten); *obj = parse_object_buffer(sha1, type, *sz, buf, eaten);

View file

@ -84,11 +84,11 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char
{ {
unsigned long size; unsigned long size;
char *data; char *data;
char type[20]; enum object_type type;
char *to_free = NULL; char *to_free = NULL;
int hit; int hit;
data = read_sha1_file(sha1, type, &size); data = read_sha1_file(sha1, &type, &size);
if (!data) { if (!data) {
error("'%s': unable to read %s", name, sha1_to_hex(sha1)); error("'%s': unable to read %s", name, sha1_to_hex(sha1));
return 0; return 0;
@ -380,10 +380,10 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
else if (S_ISREG(entry.mode)) else if (S_ISREG(entry.mode))
hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len); hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len);
else if (S_ISDIR(entry.mode)) { else if (S_ISDIR(entry.mode)) {
char type[20]; enum object_type type;
struct tree_desc sub; struct tree_desc sub;
void *data; void *data;
data = read_sha1_file(entry.sha1, type, &sub.size); data = read_sha1_file(entry.sha1, &type, &sub.size);
if (!data) if (!data)
die("unable to read tree (%s)", die("unable to read tree (%s)",
sha1_to_hex(entry.sha1)); sha1_to_hex(entry.sha1));

View file

@ -89,8 +89,8 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
static int show_object(const unsigned char *sha1, int suppress_header) static int show_object(const unsigned char *sha1, int suppress_header)
{ {
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
char *buf = read_sha1_file(sha1, type, &size); char *buf = read_sha1_file(sha1, &type, &size);
int offset = 0; int offset = 0;
if (!buf) if (!buf)

View file

@ -230,8 +230,8 @@ static unsigned char *find_packed_object_name(struct packed_git *p,
static void *delta_against(void *buf, unsigned long size, struct object_entry *entry) static void *delta_against(void *buf, unsigned long size, struct object_entry *entry)
{ {
unsigned long othersize, delta_size; unsigned long othersize, delta_size;
char type[10]; enum object_type type;
void *otherbuf = read_sha1_file(entry->delta->sha1, type, &othersize); void *otherbuf = read_sha1_file(entry->delta->sha1, &type, &othersize);
void *delta_buf; void *delta_buf;
if (!otherbuf) if (!otherbuf)
@ -375,7 +375,7 @@ static unsigned long write_object(struct sha1file *f,
struct object_entry *entry) struct object_entry *entry)
{ {
unsigned long size; unsigned long size;
char type[10]; enum object_type type;
void *buf; void *buf;
unsigned char header[10]; unsigned char header[10];
unsigned hdrlen, datalen; unsigned hdrlen, datalen;
@ -416,7 +416,7 @@ static unsigned long write_object(struct sha1file *f,
} }
if (!to_reuse) { if (!to_reuse) {
buf = read_sha1_file(entry->sha1, type, &size); buf = read_sha1_file(entry->sha1, &type, &size);
if (!buf) if (!buf)
die("unable to read %s", sha1_to_hex(entry->sha1)); die("unable to read %s", sha1_to_hex(entry->sha1));
if (size != entry->size) if (size != entry->size)
@ -765,7 +765,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
struct pbase_tree_cache *ent, *nent; struct pbase_tree_cache *ent, *nent;
void *data; void *data;
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
int neigh; int neigh;
int my_ix = pbase_tree_cache_ix(sha1); int my_ix = pbase_tree_cache_ix(sha1);
int available_ix = -1; int available_ix = -1;
@ -792,10 +792,10 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
/* Did not find one. Either we got a bogus request or /* Did not find one. Either we got a bogus request or
* we need to read and perhaps cache. * we need to read and perhaps cache.
*/ */
data = read_sha1_file(sha1, type, &size); data = read_sha1_file(sha1, &type, &size);
if (!data) if (!data)
return NULL; return NULL;
if (strcmp(type, tree_type)) { if (type != OBJ_TREE) {
free(data); free(data);
return NULL; return NULL;
} }
@ -854,19 +854,19 @@ static void add_pbase_object(struct tree_desc *tree,
while (tree_entry(tree,&entry)) { while (tree_entry(tree,&entry)) {
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
if (entry.pathlen != cmplen || if (entry.pathlen != cmplen ||
memcmp(entry.path, name, cmplen) || memcmp(entry.path, name, cmplen) ||
!has_sha1_file(entry.sha1) || !has_sha1_file(entry.sha1) ||
sha1_object_info(entry.sha1, type, &size)) (type = sha1_object_info(entry.sha1, &size)) < 0)
continue; continue;
if (name[cmplen] != '/') { if (name[cmplen] != '/') {
unsigned hash = name_hash(fullname); unsigned hash = name_hash(fullname);
add_object_entry(entry.sha1, hash, 1); add_object_entry(entry.sha1, hash, 1);
return; return;
} }
if (!strcmp(type, tree_type)) { if (type == OBJ_TREE) {
struct tree_desc sub; struct tree_desc sub;
struct pbase_tree_cache *tree; struct pbase_tree_cache *tree;
const char *down = name+cmplen+1; const char *down = name+cmplen+1;
@ -978,8 +978,6 @@ static void add_preferred_base(unsigned char *sha1)
static void check_object(struct object_entry *entry) static void check_object(struct object_entry *entry)
{ {
char type[20];
if (entry->in_pack && !entry->preferred_base) { if (entry->in_pack && !entry->preferred_base) {
struct packed_git *p = entry->in_pack; struct packed_git *p = entry->in_pack;
struct pack_window *w_curs = NULL; struct pack_window *w_curs = NULL;
@ -1062,10 +1060,10 @@ static void check_object(struct object_entry *entry)
/* Otherwise we would do the usual */ /* Otherwise we would do the usual */
} }
if (sha1_object_info(entry->sha1, type, &entry->size)) entry->type = sha1_object_info(entry->sha1, &entry->size);
if (entry->type < 0)
die("unable to get type of object %s", die("unable to get type of object %s",
sha1_to_hex(entry->sha1)); sha1_to_hex(entry->sha1));
entry->type = type_from_string(type);
} }
static unsigned int check_delta_limit(struct object_entry *me, unsigned int n) static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
@ -1195,7 +1193,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
struct object_entry *trg_entry = trg->entry; struct object_entry *trg_entry = trg->entry;
struct object_entry *src_entry = src->entry; struct object_entry *src_entry = src->entry;
unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz; unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz;
char type[10]; enum object_type type;
void *delta_buf; void *delta_buf;
/* Don't bother doing diffs between different types */ /* Don't bother doing diffs between different types */
@ -1246,13 +1244,13 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
/* Load data if not already done */ /* Load data if not already done */
if (!trg->data) { if (!trg->data) {
trg->data = read_sha1_file(trg_entry->sha1, type, &sz); trg->data = read_sha1_file(trg_entry->sha1, &type, &sz);
if (sz != trg_size) if (sz != trg_size)
die("object %s inconsistent object length (%lu vs %lu)", die("object %s inconsistent object length (%lu vs %lu)",
sha1_to_hex(trg_entry->sha1), sz, trg_size); sha1_to_hex(trg_entry->sha1), sz, trg_size);
} }
if (!src->data) { if (!src->data) {
src->data = read_sha1_file(src_entry->sha1, type, &sz); src->data = read_sha1_file(src_entry->sha1, &type, &sz);
if (sz != src_size) if (sz != src_size)
die("object %s inconsistent object length (%lu vs %lu)", die("object %s inconsistent object length (%lu vs %lu)",
sha1_to_hex(src_entry->sha1), sz, src_size); sha1_to_hex(src_entry->sha1), sz, src_size);

View file

@ -10,15 +10,10 @@ static int show_only;
static int prune_object(char *path, const char *filename, const unsigned char *sha1) static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{ {
char buf[20];
const char *type;
if (show_only) { if (show_only) {
if (sha1_object_info(sha1, buf, NULL)) enum object_type type = sha1_object_info(sha1, NULL);
type = "unknown"; printf("%s %s\n", sha1_to_hex(sha1),
else (type > 0) ? typename(type) : "unknown");
type = buf;
printf("%s %s\n", sha1_to_hex(sha1), type);
return 0; return 0;
} }
unlink(mkpath("%s/%s", path, filename)); unlink(mkpath("%s/%s", path, filename));

View file

@ -55,8 +55,8 @@ static int tree_is_complete(const unsigned char *sha1)
desc.buf = tree->buffer; desc.buf = tree->buffer;
desc.size = tree->size; desc.size = tree->size;
if (!desc.buf) { if (!desc.buf) {
char type[20]; enum object_type type;
void *data = read_sha1_file(sha1, type, &desc.size); void *data = read_sha1_file(sha1, &type, &desc.size);
if (!data) { if (!data) {
tree->object.flags |= INCOMPLETE; tree->object.flags |= INCOMPLETE;
return 0; return 0;

View file

@ -119,18 +119,18 @@ struct obj_info {
static struct obj_info *obj_list; static struct obj_info *obj_list;
static void added_object(unsigned nr, const char *type, void *data, static void added_object(unsigned nr, enum object_type type,
unsigned long size); void *data, unsigned long size);
static void write_object(unsigned nr, void *buf, unsigned long size, static void write_object(unsigned nr, enum object_type type,
const char *type) void *buf, unsigned long size)
{ {
if (write_sha1_file(buf, size, type, obj_list[nr].sha1) < 0) if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
die("failed to write object"); die("failed to write object");
added_object(nr, type, buf, size); added_object(nr, type, buf, size);
} }
static void resolve_delta(unsigned nr, const char *type, static void resolve_delta(unsigned nr, enum object_type type,
void *base, unsigned long base_size, void *base, unsigned long base_size,
void *delta, unsigned long delta_size) void *delta, unsigned long delta_size)
{ {
@ -143,12 +143,12 @@ static void resolve_delta(unsigned nr, const char *type,
if (!result) if (!result)
die("failed to apply delta"); die("failed to apply delta");
free(delta); free(delta);
write_object(nr, result, result_size, type); write_object(nr, type, result, result_size);
free(result); free(result);
} }
static void added_object(unsigned nr, const char *type, void *data, static void added_object(unsigned nr, enum object_type type,
unsigned long size) void *data, unsigned long size)
{ {
struct delta_info **p = &delta_list; struct delta_info **p = &delta_list;
struct delta_info *info; struct delta_info *info;
@ -167,33 +167,24 @@ static void added_object(unsigned nr, const char *type, void *data,
} }
} }
static void unpack_non_delta_entry(enum object_type kind, unsigned long size, static void unpack_non_delta_entry(enum object_type type, unsigned long size,
unsigned nr) unsigned nr)
{ {
void *buf = get_data(size); void *buf = get_data(size);
const char *type;
switch (kind) {
case OBJ_COMMIT: type = commit_type; break;
case OBJ_TREE: type = tree_type; break;
case OBJ_BLOB: type = blob_type; break;
case OBJ_TAG: type = tag_type; break;
default: die("bad type %d", kind);
}
if (!dry_run && buf) if (!dry_run && buf)
write_object(nr, buf, size, type); write_object(nr, type, buf, size);
free(buf); free(buf);
} }
static void unpack_delta_entry(enum object_type kind, unsigned long delta_size, static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
unsigned nr) unsigned nr)
{ {
void *delta_data, *base; void *delta_data, *base;
unsigned long base_size; unsigned long base_size;
char type[20];
unsigned char base_sha1[20]; unsigned char base_sha1[20];
if (kind == OBJ_REF_DELTA) { if (type == OBJ_REF_DELTA) {
hashcpy(base_sha1, fill(20)); hashcpy(base_sha1, fill(20));
use(20); use(20);
delta_data = get_data(delta_size); delta_data = get_data(delta_size);
@ -255,7 +246,7 @@ static void unpack_delta_entry(enum object_type kind, unsigned long delta_size,
} }
} }
base = read_sha1_file(base_sha1, type, &base_size); base = read_sha1_file(base_sha1, &type, &base_size);
if (!base) { if (!base) {
error("failed to read delta-pack base object %s", error("failed to read delta-pack base object %s",
sha1_to_hex(base_sha1)); sha1_to_hex(base_sha1));

36
cache.h
View file

@ -262,13 +262,25 @@ int adjust_shared_perm(const char *path);
int safe_create_leading_directories(char *path); int safe_create_leading_directories(char *path);
char *enter_repo(char *path, int strict); char *enter_repo(char *path, int strict);
enum object_type {
OBJ_NONE = 0,
OBJ_COMMIT = 1,
OBJ_TREE = 2,
OBJ_BLOB = 3,
OBJ_TAG = 4,
/* 5 for future expansion */
OBJ_OFS_DELTA = 6,
OBJ_REF_DELTA = 7,
OBJ_BAD,
};
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */ /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, char *, unsigned long *); extern int sha1_object_info(const unsigned char *, unsigned long *);
extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size); extern void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size);
extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); extern void * read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size);
extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1); extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
extern int pretend_sha1_file(void *, unsigned long, const char *, unsigned char *); extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
@ -285,18 +297,6 @@ extern int legacy_loose_object(unsigned char *);
extern int has_pack_file(const unsigned char *sha1); extern int has_pack_file(const unsigned char *sha1);
extern int has_pack_index(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1);
enum object_type {
OBJ_NONE = 0,
OBJ_COMMIT = 1,
OBJ_TREE = 2,
OBJ_BLOB = 3,
OBJ_TAG = 4,
/* 5 for future expansion */
OBJ_OFS_DELTA = 6,
OBJ_REF_DELTA = 7,
OBJ_BAD,
};
extern signed char hexval_table[256]; extern signed char hexval_table[256];
static inline unsigned int hexval(unsigned int c) static inline unsigned int hexval(unsigned int c)
{ {
@ -422,9 +422,9 @@ extern struct packed_git *add_packed_git(char *, int, int);
extern int num_packed_objects(const struct packed_git *p); extern int num_packed_objects(const struct packed_git *p);
extern int nth_packed_object_sha1(const struct packed_git *, int, unsigned char*); extern int nth_packed_object_sha1(const struct packed_git *, int, unsigned char*);
extern unsigned long find_pack_entry_one(const unsigned char *, struct packed_git *); extern unsigned long find_pack_entry_one(const unsigned char *, struct packed_git *);
extern void *unpack_entry(struct packed_git *, unsigned long, char *, unsigned long *); extern void *unpack_entry(struct packed_git *, unsigned long, enum object_type *, unsigned long *);
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
extern void packed_object_info_detail(struct packed_git *, unsigned long, char *, unsigned long *, unsigned long *, unsigned int *, unsigned char *); extern const char *packed_object_info_detail(struct packed_git *, unsigned long, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
/* Dumb servers support */ /* Dumb servers support */
extern int update_server_info(int); extern int update_server_info(int);

View file

@ -92,14 +92,14 @@ struct sline {
static char *grab_blob(const unsigned char *sha1, unsigned long *size) static char *grab_blob(const unsigned char *sha1, unsigned long *size)
{ {
char *blob; char *blob;
char type[20]; enum object_type type;
if (is_null_sha1(sha1)) { if (is_null_sha1(sha1)) {
/* deleted blob */ /* deleted blob */
*size = 0; *size = 0;
return xcalloc(1, 1); return xcalloc(1, 1);
} }
blob = read_sha1_file(sha1, type, size); blob = read_sha1_file(sha1, &type, size);
if (strcmp(type, blob_type)) if (type != OBJ_BLOB)
die("object '%s' is not a blob!", sha1_to_hex(sha1)); die("object '%s' is not a blob!", sha1_to_hex(sha1));
return blob; return blob;
} }

View file

@ -342,18 +342,18 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
int parse_commit(struct commit *item) int parse_commit(struct commit *item)
{ {
char type[20]; enum object_type type;
void *buffer; void *buffer;
unsigned long size; unsigned long size;
int ret; int ret;
if (item->object.parsed) if (item->object.parsed)
return 0; return 0;
buffer = read_sha1_file(item->object.sha1, type, &size); buffer = read_sha1_file(item->object.sha1, &type, &size);
if (!buffer) if (!buffer)
return error("Could not read %s", return error("Could not read %s",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
if (strcmp(type, commit_type)) { if (type != OBJ_COMMIT) {
free(buffer); free(buffer);
return error("Object %s not a commit", return error("Object %s not a commit",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));

View file

@ -284,27 +284,27 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu
static struct entry * convert_entry(unsigned char *sha1) static struct entry * convert_entry(unsigned char *sha1)
{ {
struct entry *entry = lookup_entry(sha1); struct entry *entry = lookup_entry(sha1);
char type[20]; enum object_type type;
void *buffer, *data; void *buffer, *data;
unsigned long size; unsigned long size;
if (entry->converted) if (entry->converted)
return entry; return entry;
data = read_sha1_file(sha1, type, &size); data = read_sha1_file(sha1, &type, &size);
if (!data) if (!data)
die("unable to read object %s", sha1_to_hex(sha1)); die("unable to read object %s", sha1_to_hex(sha1));
buffer = xmalloc(size); buffer = xmalloc(size);
memcpy(buffer, data, size); memcpy(buffer, data, size);
if (!strcmp(type, blob_type)) { if (type == OBJ_BLOB) {
write_sha1_file(buffer, size, blob_type, entry->new_sha1); write_sha1_file(buffer, size, blob_type, entry->new_sha1);
} else if (!strcmp(type, tree_type)) } else if (type == OBJ_TREE)
convert_tree(buffer, size, entry->new_sha1); convert_tree(buffer, size, entry->new_sha1);
else if (!strcmp(type, commit_type)) else if (type == OBJ_COMMIT)
convert_commit(buffer, size, entry->new_sha1); convert_commit(buffer, size, entry->new_sha1);
else else
die("unknown object type '%s' in %s", type, sha1_to_hex(sha1)); die("unknown object type %d in %s", type, sha1_to_hex(sha1));
entry->converted = 1; entry->converted = 1;
free(buffer); free(buffer);
free(data); free(data);

7
diff.c
View file

@ -1430,7 +1430,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
} }
} }
else { else {
char type[20]; enum object_type type;
struct sha1_size_cache *e; struct sha1_size_cache *e;
if (size_only) { if (size_only) {
@ -1439,11 +1439,12 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
s->size = e->size; s->size = e->size;
return 0; return 0;
} }
if (!sha1_object_info(s->sha1, type, &s->size)) type = sha1_object_info(s->sha1, &s->size);
if (type < 0)
locate_size_cache(s->sha1, 0, s->size); locate_size_cache(s->sha1, 0, s->size);
} }
else { else {
s->data = read_sha1_file(s->sha1, type, &s->size); s->data = read_sha1_file(s->sha1, &type, &s->size);
s->should_free = 1; s->should_free = 1;
} }
} }

View file

@ -68,10 +68,10 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
void *new; void *new;
unsigned long size; unsigned long size;
long wrote; long wrote;
char type[20]; enum object_type type;
new = read_sha1_file(ce->sha1, type, &size); new = read_sha1_file(ce->sha1, &type, &size);
if (!new || strcmp(type, blob_type)) { if (!new || type != OBJ_BLOB) {
if (new) if (new)
free(new); free(new);
return error("git-checkout-index: unable to read sha1 file of %s (%s)", return error("git-checkout-index: unable to read sha1 file of %s (%s)",

View file

@ -1008,11 +1008,11 @@ static void *gfi_unpack_entry(
struct object_entry *oe, struct object_entry *oe,
unsigned long *sizep) unsigned long *sizep)
{ {
static char type[20]; enum object_type type;
struct packed_git *p = all_packs[oe->pack_id]; struct packed_git *p = all_packs[oe->pack_id];
if (p == pack_data) if (p == pack_data)
p->pack_size = pack_size + 20; p->pack_size = pack_size + 20;
return unpack_entry(p, oe->offset, type, sizep); return unpack_entry(p, oe->offset, &type, sizep);
} }
static const char *get_mode(const char *str, uint16_t *modep) static const char *get_mode(const char *str, uint16_t *modep)
@ -1049,9 +1049,9 @@ static void load_tree(struct tree_entry *root)
t->delta_depth = 0; t->delta_depth = 0;
buf = gfi_unpack_entry(myoe, &size); buf = gfi_unpack_entry(myoe, &size);
} else { } else {
char type[20]; enum object_type type;
buf = read_sha1_file(sha1, type, &size); buf = read_sha1_file(sha1, &type, &size);
if (!buf || strcmp(type, tree_type)) if (!buf || type != OBJ_TREE)
die("Can't load tree %s", sha1_to_hex(sha1)); die("Can't load tree %s", sha1_to_hex(sha1));
} }
@ -1573,7 +1573,6 @@ static void file_change_m(struct branch *b)
struct object_entry *oe = oe; struct object_entry *oe = oe;
unsigned char sha1[20]; unsigned char sha1[20];
uint16_t mode, inline_data = 0; uint16_t mode, inline_data = 0;
char type[20];
p = get_mode(p, &mode); p = get_mode(p, &mode);
if (!p) if (!p)
@ -1628,11 +1627,12 @@ static void file_change_m(struct branch *b)
die("Not a blob (actually a %s): %s", die("Not a blob (actually a %s): %s",
command_buf.buf, typename(oe->type)); command_buf.buf, typename(oe->type));
} else { } else {
if (sha1_object_info(sha1, type, NULL)) enum object_type type = sha1_object_info(sha1, NULL);
if (type < 0)
die("Blob not found: %s", command_buf.buf); die("Blob not found: %s", command_buf.buf);
if (strcmp(blob_type, type)) if (type != OBJ_BLOB)
die("Not a blob (actually a %s): %s", die("Not a blob (actually a %s): %s",
command_buf.buf, type); typename(type), command_buf.buf);
} }
tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode); tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode);

View file

@ -479,7 +479,7 @@ static void start_put(struct transfer_request *request)
char *hex = sha1_to_hex(request->obj->sha1); char *hex = sha1_to_hex(request->obj->sha1);
struct active_request_slot *slot; struct active_request_slot *slot;
char *posn; char *posn;
char type[20]; enum object_type type;
char hdr[50]; char hdr[50];
void *unpacked; void *unpacked;
unsigned long len; unsigned long len;
@ -487,8 +487,8 @@ static void start_put(struct transfer_request *request)
ssize_t size; ssize_t size;
z_stream stream; z_stream stream;
unpacked = read_sha1_file(request->obj->sha1, type, &len); unpacked = read_sha1_file(request->obj->sha1, &type, &len);
hdrlen = sprintf(hdr, "%s %lu", type, len) + 1; hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
/* Set it up */ /* Set it up */
memset(&stream, 0, sizeof(stream)); memset(&stream, 0, sizeof(stream));

View file

@ -595,25 +595,23 @@ static void fix_unresolved_deltas(int nr_unresolved)
struct delta_entry *d = sorted_by_pos[i]; struct delta_entry *d = sorted_by_pos[i];
void *data; void *data;
unsigned long size; unsigned long size;
char type[10]; enum object_type type;
enum object_type obj_type;
int j, first, last; int j, first, last;
if (objects[d->obj_no].real_type != OBJ_REF_DELTA) if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
continue; continue;
data = read_sha1_file(d->base.sha1, type, &size); data = read_sha1_file(d->base.sha1, &type, &size);
if (!data) if (!data)
continue; continue;
obj_type = type_from_string(type);
find_delta_children(&d->base, &first, &last); find_delta_children(&d->base, &first, &last);
for (j = first; j <= last; j++) { for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no; struct object_entry *child = objects + deltas[j].obj_no;
if (child->real_type == OBJ_REF_DELTA) if (child->real_type == OBJ_REF_DELTA)
resolve_delta(child, data, size, obj_type); resolve_delta(child, data, size, type);
} }
append_obj_to_pack(data, size, obj_type); append_obj_to_pack(data, size, type);
free(data); free(data);
if (verbose) if (verbose)
percent = display_progress(nr_resolved_deltas, percent = display_progress(nr_resolved_deltas,

View file

@ -7,12 +7,12 @@ static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
{ {
void *buf; void *buf;
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
buf = read_sha1_file(obj->object.sha1, type, &size); buf = read_sha1_file(obj->object.sha1, &type, &size);
if (!buf) if (!buf)
return -1; return -1;
if (strcmp(type, blob_type)) if (type != OBJ_BLOB)
return -1; return -1;
f->ptr = buf; f->ptr = buf;
f->size = size; f->size = size;
@ -86,12 +86,12 @@ void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsign
* modified in the other branch! * modified in the other branch!
*/ */
if (!our || !their) { if (!our || !their) {
char type[20]; enum object_type type;
if (base) if (base)
return NULL; return NULL;
if (!our) if (!our)
our = their; our = their;
return read_sha1_file(our->object.sha1, type, size); return read_sha1_file(our->object.sha1, &type, size);
} }
if (fill_mmfile_blob(&f1, our) < 0) if (fill_mmfile_blob(&f1, our) < 0)

View file

@ -560,14 +560,14 @@ static void update_file_flags(const unsigned char *sha,
update_wd = 0; update_wd = 0;
if (update_wd) { if (update_wd) {
char type[20]; enum object_type type;
void *buf; void *buf;
unsigned long size; unsigned long size;
buf = read_sha1_file(sha, type, &size); buf = read_sha1_file(sha, &type, &size);
if (!buf) if (!buf)
die("cannot read object %s '%s'", sha1_to_hex(sha), path); die("cannot read object %s '%s'", sha1_to_hex(sha), path);
if (strcmp(type, blob_type) != 0) if (type != OBJ_BLOB)
die("blob expected for %s '%s'", sha1_to_hex(sha), path); die("blob expected for %s '%s'", sha1_to_hex(sha), path);
if (S_ISREG(mode)) { if (S_ISREG(mode)) {
@ -620,7 +620,7 @@ struct merge_file_info
static void fill_mm(const unsigned char *sha1, mmfile_t *mm) static void fill_mm(const unsigned char *sha1, mmfile_t *mm)
{ {
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
if (!hashcmp(sha1, null_sha1)) { if (!hashcmp(sha1, null_sha1)) {
mm->ptr = xstrdup(""); mm->ptr = xstrdup("");
@ -628,8 +628,8 @@ static void fill_mm(const unsigned char *sha1, mmfile_t *mm)
return; return;
} }
mm->ptr = read_sha1_file(sha1, type, &size); mm->ptr = read_sha1_file(sha1, &type, &size);
if (!mm->ptr || strcmp(type, blob_type)) if (!mm->ptr || type != OBJ_BLOB)
die("unable to read blob object %s", sha1_to_hex(sha1)); die("unable to read blob object %s", sha1_to_hex(sha1));
mm->size = size; mm->size = size;
} }
@ -1213,7 +1213,7 @@ static int merge(struct commit *h1,
tree->object.parsed = 1; tree->object.parsed = 1;
tree->object.type = OBJ_TREE; tree->object.type = OBJ_TREE;
pretend_sha1_file(NULL, 0, tree_type, tree->object.sha1); pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
merged_common_ancestors = make_virtual_commit(tree, "ancestor"); merged_common_ancestors = make_virtual_commit(tree, "ancestor");
} }

View file

@ -57,11 +57,11 @@ extern void *merge_file(struct blob *, struct blob *, struct blob *, unsigned lo
static void *result(struct merge_list *entry, unsigned long *size) static void *result(struct merge_list *entry, unsigned long *size)
{ {
char type[20]; enum object_type type;
struct blob *base, *our, *their; struct blob *base, *our, *their;
if (!entry->stage) if (!entry->stage)
return read_sha1_file(entry->blob->object.sha1, type, size); return read_sha1_file(entry->blob->object.sha1, &type, size);
base = NULL; base = NULL;
if (entry->stage == 1) { if (entry->stage == 1) {
base = entry->blob; base = entry->blob;
@ -80,10 +80,10 @@ static void *result(struct merge_list *entry, unsigned long *size)
static void *origin(struct merge_list *entry, unsigned long *size) static void *origin(struct merge_list *entry, unsigned long *size)
{ {
char type[20]; enum object_type type;
while (entry) { while (entry) {
if (entry->stage == 2) if (entry->stage == 2)
return read_sha1_file(entry->blob->object.sha1, type, size); return read_sha1_file(entry->blob->object.sha1, &type, size);
entry = entry->link; entry = entry->link;
} }
return NULL; return NULL;

View file

@ -27,13 +27,13 @@
static int verify_object(unsigned char *sha1, const char *expected_type) static int verify_object(unsigned char *sha1, const char *expected_type)
{ {
int ret = -1; int ret = -1;
char type[100]; enum object_type type;
unsigned long size; unsigned long size;
void *buffer = read_sha1_file(sha1, type, &size); void *buffer = read_sha1_file(sha1, &type, &size);
if (buffer) { if (buffer) {
if (!strcmp(type, expected_type)) if (type == type_from_string(expected_type))
ret = check_sha1_signature(sha1, buffer, size, type); ret = check_sha1_signature(sha1, buffer, size, expected_type);
free(buffer); free(buffer);
} }
return ret; return ret;

View file

@ -95,7 +95,7 @@ int main(int ac, char **av)
int len; int len;
char *ptr, *ntr; char *ptr, *ntr;
unsigned mode; unsigned mode;
char type[20]; enum object_type type;
char *path; char *path;
read_line(&sb, stdin, line_termination); read_line(&sb, stdin, line_termination);
@ -115,11 +115,12 @@ int main(int ac, char **av)
ntr[41] != '\t' || ntr[41] != '\t' ||
get_sha1_hex(ntr + 1, sha1)) get_sha1_hex(ntr + 1, sha1))
die("input format error: %s", sb.buf); die("input format error: %s", sb.buf);
if (sha1_object_info(sha1, type, NULL)) type = sha1_object_info(sha1, NULL);
if (type < 0)
die("object %s unavailable", sha1_to_hex(sha1)); die("object %s unavailable", sha1_to_hex(sha1));
*ntr++ = 0; /* now at the beginning of SHA1 */ *ntr++ = 0; /* now at the beginning of SHA1 */
if (strcmp(ptr, type)) if (type != type_from_string(ptr))
die("object type %s mismatch (%s)", ptr, type); die("object type %s mismatch (%s)", ptr, typename(type));
ntr += 41; /* at the beginning of name */ ntr += 41; /* at the beginning of name */
if (line_termination && ntr[0] == '"') if (line_termination && ntr[0] == '"')
path = unquote_c_style(ntr, NULL); path = unquote_c_style(ntr, NULL);

View file

@ -158,23 +158,23 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
return obj; return obj;
} }
struct object *parse_object_buffer(const unsigned char *sha1, const char *type, unsigned long size, void *buffer, int *eaten_p) struct object *parse_object_buffer(const unsigned char *sha1, enum object_type type, unsigned long size, void *buffer, int *eaten_p)
{ {
struct object *obj; struct object *obj;
int eaten = 0; int eaten = 0;
if (!strcmp(type, blob_type)) { if (type == OBJ_BLOB) {
struct blob *blob = lookup_blob(sha1); struct blob *blob = lookup_blob(sha1);
parse_blob_buffer(blob, buffer, size); parse_blob_buffer(blob, buffer, size);
obj = &blob->object; obj = &blob->object;
} else if (!strcmp(type, tree_type)) { } else if (type == OBJ_TREE) {
struct tree *tree = lookup_tree(sha1); struct tree *tree = lookup_tree(sha1);
obj = &tree->object; obj = &tree->object;
if (!tree->object.parsed) { if (!tree->object.parsed) {
parse_tree_buffer(tree, buffer, size); parse_tree_buffer(tree, buffer, size);
eaten = 1; eaten = 1;
} }
} else if (!strcmp(type, commit_type)) { } else if (type == OBJ_COMMIT) {
struct commit *commit = lookup_commit(sha1); struct commit *commit = lookup_commit(sha1);
parse_commit_buffer(commit, buffer, size); parse_commit_buffer(commit, buffer, size);
if (!commit->buffer) { if (!commit->buffer) {
@ -182,7 +182,7 @@ struct object *parse_object_buffer(const unsigned char *sha1, const char *type,
eaten = 1; eaten = 1;
} }
obj = &commit->object; obj = &commit->object;
} else if (!strcmp(type, tag_type)) { } else if (type == OBJ_TAG) {
struct tag *tag = lookup_tag(sha1); struct tag *tag = lookup_tag(sha1);
parse_tag_buffer(tag, buffer, size); parse_tag_buffer(tag, buffer, size);
obj = &tag->object; obj = &tag->object;
@ -196,13 +196,13 @@ struct object *parse_object_buffer(const unsigned char *sha1, const char *type,
struct object *parse_object(const unsigned char *sha1) struct object *parse_object(const unsigned char *sha1)
{ {
unsigned long size; unsigned long size;
char type[20]; enum object_type type;
int eaten; int eaten;
void *buffer = read_sha1_file(sha1, type, &size); void *buffer = read_sha1_file(sha1, &type, &size);
if (buffer) { if (buffer) {
struct object *obj; struct object *obj;
if (check_sha1_signature(sha1, buffer, size, type) < 0) if (check_sha1_signature(sha1, buffer, size, typename(type)) < 0)
printf("sha1 mismatch %s\n", sha1_to_hex(sha1)); printf("sha1 mismatch %s\n", sha1_to_hex(sha1));
obj = parse_object_buffer(sha1, type, size, buffer, &eaten); obj = parse_object_buffer(sha1, type, size, buffer, &eaten);

View file

@ -59,7 +59,7 @@ struct object *parse_object(const unsigned char *sha1);
* parsing it. eaten_p indicates if the object has a borrowed copy * parsing it. eaten_p indicates if the object has a borrowed copy
* of buffer and the caller should not free() it. * of buffer and the caller should not free() it.
*/ */
struct object *parse_object_buffer(const unsigned char *sha1, const char *type, unsigned long size, void *buffer, int *eaten_p); struct object *parse_object_buffer(const unsigned char *sha1, enum object_type type, unsigned long size, void *buffer, int *eaten_p);
/** Returns the object, with potentially excess memory allocated. **/ /** Returns the object, with potentially excess memory allocated. **/
struct object *lookup_unknown_object(const unsigned char *sha1); struct object *lookup_unknown_object(const unsigned char *sha1);

View file

@ -43,7 +43,7 @@ static int verify_packfile(struct packed_git *p,
for (i = err = 0; i < nr_objects; i++) { for (i = err = 0; i < nr_objects; i++) {
unsigned char sha1[20]; unsigned char sha1[20];
void *data; void *data;
char type[20]; enum object_type type;
unsigned long size, offset; unsigned long size, offset;
if (nth_packed_object_sha1(p, i, sha1)) if (nth_packed_object_sha1(p, i, sha1))
@ -51,13 +51,13 @@ static int verify_packfile(struct packed_git *p,
offset = find_pack_entry_one(sha1, p); offset = find_pack_entry_one(sha1, p);
if (!offset) if (!offset)
die("internal error pack-check find-pack-entry-one"); die("internal error pack-check find-pack-entry-one");
data = unpack_entry(p, offset, type, &size); data = unpack_entry(p, offset, &type, &size);
if (!data) { if (!data) {
err = error("cannot unpack %s from %s", err = error("cannot unpack %s from %s",
sha1_to_hex(sha1), p->pack_name); sha1_to_hex(sha1), p->pack_name);
continue; continue;
} }
if (check_sha1_signature(sha1, data, size, type)) { if (check_sha1_signature(sha1, data, size, typename(type))) {
err = error("packed %s from %s is corrupt", err = error("packed %s from %s is corrupt",
sha1_to_hex(sha1), p->pack_name); sha1_to_hex(sha1), p->pack_name);
free(data); free(data);
@ -82,7 +82,7 @@ static void show_pack_info(struct packed_git *p)
for (i = 0; i < nr_objects; i++) { for (i = 0; i < nr_objects; i++) {
unsigned char sha1[20], base_sha1[20]; unsigned char sha1[20], base_sha1[20];
char type[20]; const char *type;
unsigned long size; unsigned long size;
unsigned long store_size; unsigned long store_size;
unsigned long offset; unsigned long offset;
@ -94,9 +94,9 @@ static void show_pack_info(struct packed_git *p)
if (!offset) if (!offset)
die("internal error pack-check find-pack-entry-one"); die("internal error pack-check find-pack-entry-one");
packed_object_info_detail(p, offset, type, &size, &store_size, type = packed_object_info_detail(p, offset, &size, &store_size,
&delta_chain_length, &delta_chain_length,
base_sha1); base_sha1);
printf("%s ", sha1_to_hex(sha1)); printf("%s ", sha1_to_hex(sha1));
if (!delta_chain_length) if (!delta_chain_length)
printf("%-6s %lu %lu\n", type, size, offset); printf("%-6s %lu %lu\n", type, size, offset);

View file

@ -72,7 +72,7 @@ static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size)
char *target; char *target;
void *buffer; void *buffer;
unsigned long size; unsigned long size;
char type[10]; enum object_type type;
int len; int len;
target = xmalloc(expected_size); target = xmalloc(expected_size);
@ -81,7 +81,7 @@ static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size)
free(target); free(target);
return -1; return -1;
} }
buffer = read_sha1_file(ce->sha1, type, &size); buffer = read_sha1_file(ce->sha1, &type, &size);
if (!buffer) { if (!buffer) {
free(target); free(target);
return -1; return -1;

View file

@ -983,26 +983,27 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size
* too permissive for what we want to check. So do an anal * too permissive for what we want to check. So do an anal
* object header parse by hand. * object header parse by hand.
*/ */
static int parse_sha1_header(char *hdr, char *type, unsigned long *sizep) static int parse_sha1_header(const char *hdr, unsigned long *sizep)
{ {
char type[10];
int i; int i;
unsigned long size; unsigned long size;
/* /*
* The type can be at most ten bytes (including the * The type can be at most ten bytes (including the
* terminating '\0' that we add), and is followed by * terminating '\0' that we add), and is followed by
* a space. * a space.
*/ */
i = 10; i = 0;
for (;;) { for (;;) {
char c = *hdr++; char c = *hdr++;
if (c == ' ') if (c == ' ')
break; break;
if (!--i) type[i++] = c;
if (i >= sizeof(type))
return -1; return -1;
*type++ = c;
} }
*type = 0; type[i] = 0;
/* /*
* The length must follow immediately, and be in canonical * The length must follow immediately, and be in canonical
@ -1025,17 +1026,17 @@ static int parse_sha1_header(char *hdr, char *type, unsigned long *sizep)
/* /*
* The length must be followed by a zero byte * The length must be followed by a zero byte
*/ */
return *hdr ? -1 : 0; return *hdr ? -1 : type_from_string(type);
} }
void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size) void * unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size)
{ {
int ret; int ret;
z_stream stream; z_stream stream;
char hdr[8192]; char hdr[8192];
ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)); ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
if (ret < Z_OK || parse_sha1_header(hdr, type, size) < 0) if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)
return NULL; return NULL;
return unpack_sha1_rest(&stream, hdr, *size); return unpack_sha1_rest(&stream, hdr, *size);
@ -1044,7 +1045,7 @@ void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned l
static unsigned long get_delta_base(struct packed_git *p, static unsigned long get_delta_base(struct packed_git *p,
struct pack_window **w_curs, struct pack_window **w_curs,
unsigned long *curpos, unsigned long *curpos,
enum object_type kind, enum object_type type,
unsigned long delta_obj_offset) unsigned long delta_obj_offset)
{ {
unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL); unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL);
@ -1056,7 +1057,7 @@ static unsigned long get_delta_base(struct packed_git *p,
* that is assured. An OFS_DELTA longer than the hash size * that is assured. An OFS_DELTA longer than the hash size
* is stupid, as then a REF_DELTA would be smaller to store. * is stupid, as then a REF_DELTA would be smaller to store.
*/ */
if (kind == OBJ_OFS_DELTA) { if (type == OBJ_OFS_DELTA) {
unsigned used = 0; unsigned used = 0;
unsigned char c = base_info[used++]; unsigned char c = base_info[used++];
base_offset = c & 127; base_offset = c & 127;
@ -1071,7 +1072,7 @@ static unsigned long get_delta_base(struct packed_git *p,
if (base_offset >= delta_obj_offset) if (base_offset >= delta_obj_offset)
die("delta base offset out of bound"); die("delta base offset out of bound");
*curpos += used; *curpos += used;
} else if (kind == OBJ_REF_DELTA) { } else if (type == OBJ_REF_DELTA) {
/* The base entry _must_ be in the same pack */ /* The base entry _must_ be in the same pack */
base_offset = find_pack_entry_one(base_info, p); base_offset = find_pack_entry_one(base_info, p);
if (!base_offset) if (!base_offset)
@ -1085,28 +1086,25 @@ static unsigned long get_delta_base(struct packed_git *p,
/* forward declaration for a mutually recursive function */ /* forward declaration for a mutually recursive function */
static int packed_object_info(struct packed_git *p, unsigned long offset, static int packed_object_info(struct packed_git *p, unsigned long offset,
char *type, unsigned long *sizep); unsigned long *sizep);
static int packed_delta_info(struct packed_git *p, static int packed_delta_info(struct packed_git *p,
struct pack_window **w_curs, struct pack_window **w_curs,
unsigned long curpos, unsigned long curpos,
enum object_type kind, enum object_type type,
unsigned long obj_offset, unsigned long obj_offset,
char *type,
unsigned long *sizep) unsigned long *sizep)
{ {
unsigned long base_offset; unsigned long base_offset;
base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
type = packed_object_info(p, base_offset, NULL);
/* We choose to only get the type of the base object and /* We choose to only get the type of the base object and
* ignore potentially corrupt pack file that expects the delta * ignore potentially corrupt pack file that expects the delta
* based on a base with a wrong size. This saves tons of * based on a base with a wrong size. This saves tons of
* inflate() calls. * inflate() calls.
*/ */
if (packed_object_info(p, base_offset, type, NULL))
die("cannot get info for delta-pack base");
if (sizep) { if (sizep) {
const unsigned char *data; const unsigned char *data;
unsigned char delta_head[20], *in; unsigned char delta_head[20], *in;
@ -1141,7 +1139,8 @@ static int packed_delta_info(struct packed_git *p,
/* Read the result size */ /* Read the result size */
*sizep = get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); *sizep = get_delta_hdr_size(&data, delta_head+sizeof(delta_head));
} }
return 0;
return type;
} }
static int unpack_object_header(struct packed_git *p, static int unpack_object_header(struct packed_git *p,
@ -1169,38 +1168,36 @@ static int unpack_object_header(struct packed_git *p,
return type; return type;
} }
void packed_object_info_detail(struct packed_git *p, const char *packed_object_info_detail(struct packed_git *p,
unsigned long obj_offset, unsigned long obj_offset,
char *type, unsigned long *size,
unsigned long *size, unsigned long *store_size,
unsigned long *store_size, unsigned int *delta_chain_length,
unsigned int *delta_chain_length, unsigned char *base_sha1)
unsigned char *base_sha1)
{ {
struct pack_window *w_curs = NULL; struct pack_window *w_curs = NULL;
unsigned long curpos, dummy; unsigned long curpos, dummy;
unsigned char *next_sha1; unsigned char *next_sha1;
enum object_type kind; enum object_type type;
*delta_chain_length = 0; *delta_chain_length = 0;
curpos = obj_offset; curpos = obj_offset;
kind = unpack_object_header(p, &w_curs, &curpos, size); type = unpack_object_header(p, &w_curs, &curpos, size);
for (;;) { for (;;) {
switch (kind) { switch (type) {
default: default:
die("pack %s contains unknown object type %d", die("pack %s contains unknown object type %d",
p->pack_name, kind); p->pack_name, type);
case OBJ_COMMIT: case OBJ_COMMIT:
case OBJ_TREE: case OBJ_TREE:
case OBJ_BLOB: case OBJ_BLOB:
case OBJ_TAG: case OBJ_TAG:
strcpy(type, typename(kind));
*store_size = 0; /* notyet */ *store_size = 0; /* notyet */
unuse_pack(&w_curs); unuse_pack(&w_curs);
return; return typename(type);
case OBJ_OFS_DELTA: case OBJ_OFS_DELTA:
obj_offset = get_delta_base(p, &w_curs, &curpos, kind, obj_offset); obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
if (*delta_chain_length == 0) { if (*delta_chain_length == 0) {
/* TODO: find base_sha1 as pointed by curpos */ /* TODO: find base_sha1 as pointed by curpos */
} }
@ -1214,39 +1211,38 @@ void packed_object_info_detail(struct packed_git *p,
} }
(*delta_chain_length)++; (*delta_chain_length)++;
curpos = obj_offset; curpos = obj_offset;
kind = unpack_object_header(p, &w_curs, &curpos, &dummy); type = unpack_object_header(p, &w_curs, &curpos, &dummy);
} }
} }
static int packed_object_info(struct packed_git *p, unsigned long obj_offset, static int packed_object_info(struct packed_git *p, unsigned long obj_offset,
char *type, unsigned long *sizep) unsigned long *sizep)
{ {
struct pack_window *w_curs = NULL; struct pack_window *w_curs = NULL;
unsigned long size, curpos = obj_offset; unsigned long size, curpos = obj_offset;
enum object_type kind; enum object_type type;
kind = unpack_object_header(p, &w_curs, &curpos, &size); type = unpack_object_header(p, &w_curs, &curpos, &size);
switch (kind) { switch (type) {
case OBJ_OFS_DELTA: case OBJ_OFS_DELTA:
case OBJ_REF_DELTA: case OBJ_REF_DELTA:
packed_delta_info(p, &w_curs, curpos, kind, type = packed_delta_info(p, &w_curs, curpos,
obj_offset, type, sizep); type, obj_offset, sizep);
break; break;
case OBJ_COMMIT: case OBJ_COMMIT:
case OBJ_TREE: case OBJ_TREE:
case OBJ_BLOB: case OBJ_BLOB:
case OBJ_TAG: case OBJ_TAG:
strcpy(type, typename(kind));
if (sizep) if (sizep)
*sizep = size; *sizep = size;
break; break;
default: default:
die("pack %s contains unknown object type %d", die("pack %s contains unknown object type %d",
p->pack_name, kind); p->pack_name, type);
} }
unuse_pack(&w_curs); unuse_pack(&w_curs);
return 0; return type;
} }
static void *unpack_compressed_entry(struct packed_git *p, static void *unpack_compressed_entry(struct packed_git *p,
@ -1284,15 +1280,14 @@ static void *unpack_delta_entry(struct packed_git *p,
struct pack_window **w_curs, struct pack_window **w_curs,
unsigned long curpos, unsigned long curpos,
unsigned long delta_size, unsigned long delta_size,
enum object_type kind,
unsigned long obj_offset, unsigned long obj_offset,
char *type, enum object_type *type,
unsigned long *sizep) unsigned long *sizep)
{ {
void *delta_data, *result, *base; void *delta_data, *result, *base;
unsigned long result_size, base_size, base_offset; unsigned long base_size, base_offset;
base_offset = get_delta_base(p, w_curs, &curpos, kind, obj_offset); base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset);
base = unpack_entry(p, base_offset, type, &base_size); base = unpack_entry(p, base_offset, type, &base_size);
if (!base) if (!base)
die("failed to read delta base object at %lu from %s", die("failed to read delta base object at %lu from %s",
@ -1301,43 +1296,39 @@ static void *unpack_delta_entry(struct packed_git *p,
delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size); delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
result = patch_delta(base, base_size, result = patch_delta(base, base_size,
delta_data, delta_size, delta_data, delta_size,
&result_size); sizep);
if (!result) if (!result)
die("failed to apply delta"); die("failed to apply delta");
free(delta_data); free(delta_data);
free(base); free(base);
*sizep = result_size;
return result; return result;
} }
void *unpack_entry(struct packed_git *p, unsigned long obj_offset, void *unpack_entry(struct packed_git *p, unsigned long obj_offset,
char *type, unsigned long *sizep) enum object_type *type, unsigned long *sizep)
{ {
struct pack_window *w_curs = NULL; struct pack_window *w_curs = NULL;
unsigned long size, curpos = obj_offset; unsigned long curpos = obj_offset;
enum object_type kind; void *data;
void *retval;
kind = unpack_object_header(p, &w_curs, &curpos, &size); *type = unpack_object_header(p, &w_curs, &curpos, sizep);
switch (kind) { switch (*type) {
case OBJ_OFS_DELTA: case OBJ_OFS_DELTA:
case OBJ_REF_DELTA: case OBJ_REF_DELTA:
retval = unpack_delta_entry(p, &w_curs, curpos, size, data = unpack_delta_entry(p, &w_curs, curpos, *sizep,
kind, obj_offset, type, sizep); obj_offset, type, sizep);
break; break;
case OBJ_COMMIT: case OBJ_COMMIT:
case OBJ_TREE: case OBJ_TREE:
case OBJ_BLOB: case OBJ_BLOB:
case OBJ_TAG: case OBJ_TAG:
strcpy(type, typename(kind)); data = unpack_compressed_entry(p, &w_curs, curpos, *sizep);
*sizep = size;
retval = unpack_compressed_entry(p, &w_curs, curpos, size);
break; break;
default: default:
die("unknown object type %i in %s", kind, p->pack_name); die("unknown object type %i in %s", *type, p->pack_name);
} }
unuse_pack(&w_curs); unuse_pack(&w_curs);
return retval; return data;
} }
int num_packed_objects(const struct packed_git *p) int num_packed_objects(const struct packed_git *p)
@ -1444,10 +1435,10 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1,
return p; return p;
} }
return NULL; return NULL;
} }
static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep)
{ {
int status; int status;
unsigned long mapsize, size; unsigned long mapsize, size;
@ -1461,31 +1452,29 @@ static int sha1_loose_object_info(const unsigned char *sha1, char *type, unsigne
if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0) if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
status = error("unable to unpack %s header", status = error("unable to unpack %s header",
sha1_to_hex(sha1)); sha1_to_hex(sha1));
else if (parse_sha1_header(hdr, type, &size) < 0) else if ((status = parse_sha1_header(hdr, &size)) < 0)
status = error("unable to parse %s header", sha1_to_hex(sha1)); status = error("unable to parse %s header", sha1_to_hex(sha1));
else { else if (sizep)
status = 0; *sizep = size;
if (sizep)
*sizep = size;
}
inflateEnd(&stream); inflateEnd(&stream);
munmap(map, mapsize); munmap(map, mapsize);
return status; return status;
} }
int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep) int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
{ {
struct pack_entry e; struct pack_entry e;
if (!find_pack_entry(sha1, &e, NULL)) { if (!find_pack_entry(sha1, &e, NULL)) {
reprepare_packed_git(); reprepare_packed_git();
if (!find_pack_entry(sha1, &e, NULL)) if (!find_pack_entry(sha1, &e, NULL))
return sha1_loose_object_info(sha1, type, sizep); return sha1_loose_object_info(sha1, sizep);
} }
return packed_object_info(e.p, e.offset, type, sizep); return packed_object_info(e.p, e.offset, sizep);
} }
static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned long *size) static void *read_packed_sha1(const unsigned char *sha1,
enum object_type *type, unsigned long *size)
{ {
struct pack_entry e; struct pack_entry e;
@ -1503,7 +1492,7 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
*/ */
static struct cached_object { static struct cached_object {
unsigned char sha1[20]; unsigned char sha1[20];
const char *type; enum object_type type;
void *buf; void *buf;
unsigned long size; unsigned long size;
} *cached_objects; } *cached_objects;
@ -1521,11 +1510,12 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)
return NULL; return NULL;
} }
int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1) int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
unsigned char *sha1)
{ {
struct cached_object *co; struct cached_object *co;
hash_sha1_file(buf, len, type, sha1); hash_sha1_file(buf, len, typename(type), sha1);
if (has_sha1_file(sha1) || find_cached_object(sha1)) if (has_sha1_file(sha1) || find_cached_object(sha1))
return 0; return 0;
if (cached_object_alloc <= cached_object_nr) { if (cached_object_alloc <= cached_object_nr) {
@ -1536,14 +1526,15 @@ int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned c
} }
co = &cached_objects[cached_object_nr++]; co = &cached_objects[cached_object_nr++];
co->size = len; co->size = len;
co->type = strdup(type); co->type = type;
co->buf = xmalloc(len); co->buf = xmalloc(len);
memcpy(co->buf, buf, len); memcpy(co->buf, buf, len);
hashcpy(co->sha1, sha1); hashcpy(co->sha1, sha1);
return 0; return 0;
} }
void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size) void *read_sha1_file(const unsigned char *sha1, enum object_type *type,
unsigned long *size)
{ {
unsigned long mapsize; unsigned long mapsize;
void *map, *buf; void *map, *buf;
@ -1554,7 +1545,7 @@ void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
buf = xmalloc(co->size + 1); buf = xmalloc(co->size + 1);
memcpy(buf, co->buf, co->size); memcpy(buf, co->buf, co->size);
((char*)buf)[co->size] = 0; ((char*)buf)[co->size] = 0;
strcpy(type, co->type); *type = co->type;
*size = co->size; *size = co->size;
return buf; return buf;
} }
@ -1573,33 +1564,34 @@ void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
} }
void *read_object_with_reference(const unsigned char *sha1, void *read_object_with_reference(const unsigned char *sha1,
const char *required_type, const char *required_type_name,
unsigned long *size, unsigned long *size,
unsigned char *actual_sha1_return) unsigned char *actual_sha1_return)
{ {
char type[20]; enum object_type type, required_type;
void *buffer; void *buffer;
unsigned long isize; unsigned long isize;
unsigned char actual_sha1[20]; unsigned char actual_sha1[20];
required_type = type_from_string(required_type_name);
hashcpy(actual_sha1, sha1); hashcpy(actual_sha1, sha1);
while (1) { while (1) {
int ref_length = -1; int ref_length = -1;
const char *ref_type = NULL; const char *ref_type = NULL;
buffer = read_sha1_file(actual_sha1, type, &isize); buffer = read_sha1_file(actual_sha1, &type, &isize);
if (!buffer) if (!buffer)
return NULL; return NULL;
if (!strcmp(type, required_type)) { if (type == required_type) {
*size = isize; *size = isize;
if (actual_sha1_return) if (actual_sha1_return)
hashcpy(actual_sha1_return, actual_sha1); hashcpy(actual_sha1_return, actual_sha1);
return buffer; return buffer;
} }
/* Handle references */ /* Handle references */
else if (!strcmp(type, commit_type)) else if (type == OBJ_COMMIT)
ref_type = "tree "; ref_type = "tree ";
else if (!strcmp(type, tag_type)) else if (type == OBJ_TAG)
ref_type = "object "; ref_type = "object ";
else { else {
free(buffer); free(buffer);
@ -1841,17 +1833,17 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
z_stream stream; z_stream stream;
unsigned char *unpacked; unsigned char *unpacked;
unsigned long len; unsigned long len;
char type[20]; enum object_type type;
char hdr[32]; char hdr[32];
int hdrlen; int hdrlen;
void *buf; void *buf;
/* need to unpack and recompress it by itself */ /* need to unpack and recompress it by itself */
unpacked = read_packed_sha1(sha1, type, &len); unpacked = read_packed_sha1(sha1, &type, &len);
if (!unpacked) if (!unpacked)
error("cannot read sha1_file for %s", sha1_to_hex(sha1)); error("cannot read sha1_file for %s", sha1_to_hex(sha1));
hdrlen = sprintf(hdr, "%s %lu", type, len) + 1; hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
/* Set it up */ /* Set it up */
memset(&stream, 0, sizeof(stream)); memset(&stream, 0, sizeof(stream));

6
tag.c
View file

@ -85,18 +85,18 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size)
int parse_tag(struct tag *item) int parse_tag(struct tag *item)
{ {
char type[20]; enum object_type type;
void *data; void *data;
unsigned long size; unsigned long size;
int ret; int ret;
if (item->object.parsed) if (item->object.parsed)
return 0; return 0;
data = read_sha1_file(item->object.sha1, type, &size); data = read_sha1_file(item->object.sha1, &type, &size);
if (!data) if (!data)
return error("Could not read %s", return error("Could not read %s",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
if (strcmp(type, tag_type)) { if (type != OBJ_TAG) {
free(data); free(data);
return error("Object %s not a tag", return error("Object %s not a tag",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));

View file

@ -139,13 +139,13 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
if (opt->recursive && S_ISDIR(mode)) { if (opt->recursive && S_ISDIR(mode)) {
char type[20]; enum object_type type;
char *newbase = malloc_base(base, path, strlen(path)); char *newbase = malloc_base(base, path, strlen(path));
struct tree_desc inner; struct tree_desc inner;
void *tree; void *tree;
tree = read_sha1_file(sha1, type, &inner.size); tree = read_sha1_file(sha1, &type, &inner.size);
if (!tree || strcmp(type, tree_type)) if (!tree || type != OBJ_TREE)
die("corrupt tree sha %s", sha1_to_hex(sha1)); die("corrupt tree sha %s", sha1_to_hex(sha1));
inner.buf = tree; inner.buf = tree;

6
tree.c
View file

@ -190,17 +190,17 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
int parse_tree(struct tree *item) int parse_tree(struct tree *item)
{ {
char type[20]; enum object_type type;
void *buffer; void *buffer;
unsigned long size; unsigned long size;
if (item->object.parsed) if (item->object.parsed)
return 0; return 0;
buffer = read_sha1_file(item->object.sha1, type, &size); buffer = read_sha1_file(item->object.sha1, &type, &size);
if (!buffer) if (!buffer)
return error("Could not read %s", return error("Could not read %s",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));
if (strcmp(type, tree_type)) { if (type != OBJ_TREE) {
free(buffer); free(buffer);
return error("Object %s not a tree", return error("Object %s not a tree",
sha1_to_hex(item->object.sha1)); sha1_to_hex(item->object.sha1));

View file

@ -5,12 +5,12 @@ static char *create_temp_file(unsigned char *sha1)
{ {
static char path[50]; static char path[50];
void *buf; void *buf;
char type[100]; enum object_type type;
unsigned long size; unsigned long size;
int fd; int fd;
buf = read_sha1_file(sha1, type, &size); buf = read_sha1_file(sha1, &type, &size);
if (!buf || strcmp(type, blob_type)) if (!buf || type != OBJ_BLOB)
die("unable to read blob object %s", sha1_to_hex(sha1)); die("unable to read blob object %s", sha1_to_hex(sha1));
strcpy(path, ".merge_file_XXXXXX"); strcpy(path, ".merge_file_XXXXXX");