diff options
author | Junio C Hamano <gitster@pobox.com> | 2019-12-01 09:04:28 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-12-01 09:04:28 -0800 |
commit | 0e07c1cd83535cf3a20d3d961a41bb4a627ce4e5 (patch) | |
tree | 32ac0fa81e02d0f56c583eda414d14aa89111a65 /commit.c | |
parent | The first batch post 2.24 cycle (diff) | |
parent | fsck: accept an oid instead of a "struct tree" for fsck_tree() (diff) | |
download | tgif-0e07c1cd83535cf3a20d3d961a41bb4a627ce4e5.tar.xz |
Merge branch 'jk/cleanup-object-parsing-and-fsck'
Crufty code and logic accumulated over time around the object
parsing and low-level object access used in "git fsck" have been
cleaned up.
* jk/cleanup-object-parsing-and-fsck: (23 commits)
fsck: accept an oid instead of a "struct tree" for fsck_tree()
fsck: accept an oid instead of a "struct commit" for fsck_commit()
fsck: accept an oid instead of a "struct tag" for fsck_tag()
fsck: rename vague "oid" local variables
fsck: don't require an object struct in verify_headers()
fsck: don't require an object struct for fsck_ident()
fsck: drop blob struct from fsck_finish()
fsck: accept an oid instead of a "struct blob" for fsck_blob()
fsck: don't require an object struct for report()
fsck: only require an oid for skiplist functions
fsck: only provide oid/type in fsck_error callback
fsck: don't require object structs for display functions
fsck: use oids rather than objects for object_name API
fsck_describe_object(): build on our get_object_name() primitive
fsck: unify object-name code
fsck: require an actual buffer for non-blobs
fsck: stop checking tag->tagged
fsck: stop checking commit->parent counts
fsck: stop checking commit->tree value
commit, tag: don't set parsed bit for parse failures
...
Diffstat (limited to 'commit.c')
-rw-r--r-- | commit.c | 33 |
1 files changed, 28 insertions, 5 deletions
@@ -402,10 +402,22 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b struct commit_graft *graft; const int tree_entry_len = the_hash_algo->hexsz + 5; const int parent_entry_len = the_hash_algo->hexsz + 7; + struct tree *tree; if (item->object.parsed) return 0; - item->object.parsed = 1; + + if (item->parents) { + /* + * Presumably this is leftover from an earlier failed parse; + * clear it out in preparation for us re-parsing (we'll hit the + * same error, but that's good, since it lets our caller know + * the result cannot be trusted. + */ + free_commit_list(item->parents); + item->parents = NULL; + } + tail += size; if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) || bufptr[tree_entry_len] != '\n') @@ -413,7 +425,12 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b if (get_oid_hex(bufptr + 5, &parent) < 0) return error("bad tree pointer in commit %s", oid_to_hex(&item->object.oid)); - set_commit_tree(item, lookup_tree(r, &parent)); + tree = lookup_tree(r, &parent); + if (!tree) + return error("bad tree pointer %s in commit %s", + oid_to_hex(&parent), + oid_to_hex(&item->object.oid)); + set_commit_tree(item, tree); bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */ pptr = &item->parents; @@ -433,8 +450,11 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b if (graft && (graft->nr_parent < 0 || grafts_replace_parents)) continue; new_parent = lookup_commit(r, &parent); - if (new_parent) - pptr = &commit_list_insert(new_parent, pptr)->next; + if (!new_parent) + return error("bad parent %s in commit %s", + oid_to_hex(&parent), + oid_to_hex(&item->object.oid)); + pptr = &commit_list_insert(new_parent, pptr)->next; } if (graft) { int i; @@ -443,7 +463,9 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b new_parent = lookup_commit(r, &graft->parent[i]); if (!new_parent) - continue; + return error("bad graft parent %s in commit %s", + oid_to_hex(&graft->parent[i]), + oid_to_hex(&item->object.oid)); pptr = &commit_list_insert(new_parent, pptr)->next; } } @@ -452,6 +474,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b if (check_graph) load_commit_graph_info(r, item); + item->object.parsed = 1; return 0; } |