diff options
Diffstat (limited to 'commit.c')
-rw-r--r-- | commit.c | 169 |
1 files changed, 100 insertions, 69 deletions
@@ -2,6 +2,8 @@ #include "tag.h" #include "commit.h" #include "commit-graph.h" +#include "repository.h" +#include "object-store.h" #include "pkt-line.h" #include "utf8.h" #include "diff.h" @@ -22,24 +24,26 @@ int save_commit_buffer = 1; const char *commit_type = "commit"; -struct commit *lookup_commit_reference_gently(const struct object_id *oid, - int quiet) +struct commit *lookup_commit_reference_gently(struct repository *r, + const struct object_id *oid, int quiet) { - struct object *obj = deref_tag(parse_object(oid), NULL, 0); + struct object *obj = deref_tag(r, + parse_object(r, oid), + NULL, 0); if (!obj) return NULL; - return object_as_type(obj, OBJ_COMMIT, quiet); + return object_as_type(r, obj, OBJ_COMMIT, quiet); } -struct commit *lookup_commit_reference(const struct object_id *oid) +struct commit *lookup_commit_reference(struct repository *r, const struct object_id *oid) { - return lookup_commit_reference_gently(oid, 0); + return lookup_commit_reference_gently(r, oid, 0); } struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref_name) { - struct commit *c = lookup_commit_reference(oid); + struct commit *c = lookup_commit_reference(the_repository, oid); if (!c) die(_("could not parse %s"), ref_name); if (oidcmp(oid, &c->object.oid)) { @@ -49,13 +53,13 @@ struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref return c; } -struct commit *lookup_commit(const struct object_id *oid) +struct commit *lookup_commit(struct repository *r, const struct object_id *oid) { - struct object *obj = lookup_object(oid->hash); + struct object *obj = lookup_object(r, oid->hash); if (!obj) - return create_object(the_repository, oid->hash, - alloc_commit_node(the_repository)); - return object_as_type(obj, OBJ_COMMIT, 0); + return create_object(r, oid->hash, + alloc_commit_node(r)); + return object_as_type(r, obj, OBJ_COMMIT, 0); } struct commit *lookup_commit_reference_by_name(const char *name) @@ -65,7 +69,7 @@ struct commit *lookup_commit_reference_by_name(const char *name) if (get_oid_committish(name, &oid)) return NULL; - commit = lookup_commit_reference(&oid); + commit = lookup_commit_reference(the_repository, &oid); if (parse_commit(commit)) return NULL; return commit; @@ -98,41 +102,44 @@ static timestamp_t parse_commit_date(const char *buf, const char *tail) return parse_timestamp(dateptr, NULL, 10); } -static struct commit_graft **commit_graft; -static int commit_graft_alloc, commit_graft_nr; - static const unsigned char *commit_graft_sha1_access(size_t index, void *table) { struct commit_graft **commit_graft_table = table; return commit_graft_table[index]->oid.hash; } -static int commit_graft_pos(const unsigned char *sha1) +static int commit_graft_pos(struct repository *r, const unsigned char *sha1) { - return sha1_pos(sha1, commit_graft, commit_graft_nr, + return sha1_pos(sha1, r->parsed_objects->grafts, + r->parsed_objects->grafts_nr, commit_graft_sha1_access); } -int register_commit_graft(struct commit_graft *graft, int ignore_dups) +int register_commit_graft(struct repository *r, struct commit_graft *graft, + int ignore_dups) { - int pos = commit_graft_pos(graft->oid.hash); + int pos = commit_graft_pos(r, graft->oid.hash); if (0 <= pos) { if (ignore_dups) free(graft); else { - free(commit_graft[pos]); - commit_graft[pos] = graft; + free(r->parsed_objects->grafts[pos]); + r->parsed_objects->grafts[pos] = graft; } return 1; } pos = -pos - 1; - ALLOC_GROW(commit_graft, commit_graft_nr + 1, commit_graft_alloc); - commit_graft_nr++; - if (pos < commit_graft_nr) - MOVE_ARRAY(commit_graft + pos + 1, commit_graft + pos, - commit_graft_nr - pos - 1); - commit_graft[pos] = graft; + ALLOC_GROW(r->parsed_objects->grafts, + r->parsed_objects->grafts_nr + 1, + r->parsed_objects->grafts_alloc); + r->parsed_objects->grafts_nr++; + if (pos < r->parsed_objects->grafts_nr) + memmove(r->parsed_objects->grafts + pos + 1, + r->parsed_objects->grafts + pos, + (r->parsed_objects->grafts_nr - pos - 1) * + sizeof(*r->parsed_objects->grafts)); + r->parsed_objects->grafts[pos] = graft; return 0; } @@ -174,7 +181,7 @@ bad_graft_data: return NULL; } -static int read_graft_file(const char *graft_file) +static int read_graft_file(struct repository *r, const char *graft_file) { FILE *fp = fopen_or_warn(graft_file, "r"); struct strbuf buf = STRBUF_INIT; @@ -194,7 +201,7 @@ static int read_graft_file(const char *graft_file) struct commit_graft *graft = read_graft_line(&buf); if (!graft) continue; - if (register_commit_graft(graft, 1)) + if (register_commit_graft(r, graft, 1)) error("duplicate graft data: %s", buf.buf); } fclose(fp); @@ -202,50 +209,50 @@ static int read_graft_file(const char *graft_file) return 0; } -static void prepare_commit_graft(void) +static void prepare_commit_graft(struct repository *r) { - static int commit_graft_prepared; char *graft_file; - if (commit_graft_prepared) + if (r->parsed_objects->commit_graft_prepared) return; if (!startup_info->have_repository) return; - graft_file = get_graft_file(); - read_graft_file(graft_file); + graft_file = get_graft_file(r); + read_graft_file(r, graft_file); /* make sure shallows are read */ - is_repository_shallow(); - commit_graft_prepared = 1; + is_repository_shallow(r); + r->parsed_objects->commit_graft_prepared = 1; } -struct commit_graft *lookup_commit_graft(const struct object_id *oid) +struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid) { int pos; - prepare_commit_graft(); - pos = commit_graft_pos(oid->hash); + prepare_commit_graft(r); + pos = commit_graft_pos(r, oid->hash); if (pos < 0) return NULL; - return commit_graft[pos]; + return r->parsed_objects->grafts[pos]; } int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data) { int i, ret; - for (i = ret = 0; i < commit_graft_nr && !ret; i++) - ret = fn(commit_graft[i], cb_data); + for (i = ret = 0; i < the_repository->parsed_objects->grafts_nr && !ret; i++) + ret = fn(the_repository->parsed_objects->grafts[i], cb_data); return ret; } int unregister_shallow(const struct object_id *oid) { - int pos = commit_graft_pos(oid->hash); + int pos = commit_graft_pos(the_repository, oid->hash); if (pos < 0) return -1; - if (pos + 1 < commit_graft_nr) - MOVE_ARRAY(commit_graft + pos, commit_graft + pos + 1, - commit_graft_nr - pos - 1); - commit_graft_nr--; + if (pos + 1 < the_repository->parsed_objects->grafts_nr) + MOVE_ARRAY(the_repository->parsed_objects->grafts + pos, + the_repository->parsed_objects->grafts + pos + 1, + the_repository->parsed_objects->grafts_nr - pos - 1); + the_repository->parsed_objects->grafts_nr--; return 0; } @@ -254,18 +261,32 @@ struct commit_buffer { unsigned long size; }; define_commit_slab(buffer_slab, struct commit_buffer); -static struct buffer_slab buffer_slab = COMMIT_SLAB_INIT(1, buffer_slab); -void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size) +struct buffer_slab *allocate_commit_buffer_slab(void) +{ + struct buffer_slab *bs = xmalloc(sizeof(*bs)); + init_buffer_slab(bs); + return bs; +} + +void free_commit_buffer_slab(struct buffer_slab *bs) +{ + clear_buffer_slab(bs); + free(bs); +} + +void set_commit_buffer(struct repository *r, struct commit *commit, void *buffer, unsigned long size) { - struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit); + struct commit_buffer *v = buffer_slab_at( + r->parsed_objects->buffer_slab, commit); v->buffer = buffer; v->size = size; } -const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep) +const void *get_cached_commit_buffer(struct repository *r, const struct commit *commit, unsigned long *sizep) { - struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); + struct commit_buffer *v = buffer_slab_peek( + r->parsed_objects->buffer_slab, commit); if (!v) { if (sizep) *sizep = 0; @@ -278,7 +299,7 @@ const void *get_cached_commit_buffer(const struct commit *commit, unsigned long const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep) { - const void *ret = get_cached_commit_buffer(commit, sizep); + const void *ret = get_cached_commit_buffer(the_repository, commit, sizep); if (!ret) { enum object_type type; unsigned long size; @@ -297,14 +318,16 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep) void unuse_commit_buffer(const struct commit *commit, const void *buffer) { - struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); + struct commit_buffer *v = buffer_slab_peek( + the_repository->parsed_objects->buffer_slab, commit); if (!(v && v->buffer == buffer)) free((void *)buffer); } void free_commit_buffer(struct commit *commit) { - struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); + struct commit_buffer *v = buffer_slab_peek( + the_repository->parsed_objects->buffer_slab, commit); if (v) { FREE_AND_NULL(v->buffer); v->size = 0; @@ -340,7 +363,8 @@ void release_commit_memory(struct commit *c) const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep) { - struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit); + struct commit_buffer *v = buffer_slab_peek( + the_repository->parsed_objects->buffer_slab, commit); void *ret; if (!v) { @@ -357,15 +381,15 @@ const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep) return ret; } -int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size, int check_graph) +int parse_commit_buffer(struct repository *r, struct commit *item, const void *buffer, unsigned long size, int check_graph) { const char *tail = buffer; const char *bufptr = buffer; struct object_id parent; struct commit_list **pptr; struct commit_graft *graft; - const int tree_entry_len = GIT_SHA1_HEXSZ + 5; - const int parent_entry_len = GIT_SHA1_HEXSZ + 7; + const int tree_entry_len = the_hash_algo->hexsz + 5; + const int parent_entry_len = the_hash_algo->hexsz + 7; if (item->object.parsed) return 0; @@ -377,11 +401,11 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s if (get_oid_hex(bufptr + 5, &parent) < 0) return error("bad tree pointer in commit %s", oid_to_hex(&item->object.oid)); - item->maybe_tree = lookup_tree(&parent); + item->maybe_tree = lookup_tree(r, &parent); bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */ pptr = &item->parents; - graft = lookup_commit_graft(&item->object.oid); + graft = lookup_commit_graft(r, &item->object.oid); while (bufptr + parent_entry_len < tail && !memcmp(bufptr, "parent ", 7)) { struct commit *new_parent; @@ -396,7 +420,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s */ if (graft && (graft->nr_parent < 0 || grafts_replace_parents)) continue; - new_parent = lookup_commit(&parent); + new_parent = lookup_commit(r, &parent); if (new_parent) pptr = &commit_list_insert(new_parent, pptr)->next; } @@ -404,7 +428,8 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s int i; struct commit *new_parent; for (i = 0; i < graft->nr_parent; i++) { - new_parent = lookup_commit(&graft->parent[i]); + new_parent = lookup_commit(r, + &graft->parent[i]); if (!new_parent) continue; pptr = &commit_list_insert(new_parent, pptr)->next; @@ -418,7 +443,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s return 0; } -int parse_commit_gently(struct commit *item, int quiet_on_missing) +int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_commit_graph) { enum object_type type; void *buffer; @@ -429,7 +454,7 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing) return -1; if (item->object.parsed) return 0; - if (parse_commit_in_graph(item)) + if (use_commit_graph && parse_commit_in_graph(item)) return 0; buffer = read_object_file(&item->object.oid, &type, &size); if (!buffer) @@ -441,15 +466,21 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing) return error("Object %s not a commit", oid_to_hex(&item->object.oid)); } - ret = parse_commit_buffer(item, buffer, size, 0); + + ret = parse_commit_buffer(the_repository, item, buffer, size, 0); if (save_commit_buffer && !ret) { - set_commit_buffer(item, buffer, size); + set_commit_buffer(the_repository, item, buffer, size); return 0; } free(buffer); return ret; } +int parse_commit_gently(struct commit *item, int quiet_on_missing) +{ + return parse_commit_internal(item, quiet_on_missing, 1); +} + void parse_commit_or_die(struct commit *item) { if (parse_commit(item)) @@ -1687,7 +1718,7 @@ struct commit *get_merge_parent(const char *name) struct object_id oid; if (get_oid(name, &oid)) return NULL; - obj = parse_object(&oid); + obj = parse_object(the_repository, &oid); commit = (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT); if (commit && !merge_remote_util(commit)) set_merge_remote_desc(commit, name, obj); |