mirror of
https://github.com/git/git.git
synced 2026-02-26 01:43:43 +00:00
Merge branch 'ps/receive-pack-shallow-optim' into jch
The code to accept shallow "git push" has been optimized. * ps/receive-pack-shallow-optim: commit: use commit graph in `lookup_commit_reference_gently()` commit: make `repo_parse_commit_no_graph()` more robust commit: avoid parsing non-commits in `lookup_commit_reference_gently()`
This commit is contained in:
32
commit.c
32
commit.c
@@ -42,13 +42,35 @@ const char *commit_type = "commit";
|
||||
struct commit *lookup_commit_reference_gently(struct repository *r,
|
||||
const struct object_id *oid, int quiet)
|
||||
{
|
||||
struct object *obj = deref_tag(r,
|
||||
parse_object(r, oid),
|
||||
NULL, 0);
|
||||
const struct object_id *maybe_peeled;
|
||||
struct object_id peeled_oid;
|
||||
struct commit *commit;
|
||||
enum object_type type;
|
||||
|
||||
if (!obj)
|
||||
switch (peel_object_ext(r, oid, &peeled_oid, 0, &type)) {
|
||||
case PEEL_NON_TAG:
|
||||
maybe_peeled = oid;
|
||||
break;
|
||||
case PEEL_PEELED:
|
||||
maybe_peeled = &peeled_oid;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
return object_as_type(obj, OBJ_COMMIT, quiet);
|
||||
}
|
||||
|
||||
if (type != OBJ_COMMIT) {
|
||||
if (!quiet)
|
||||
error(_("object %s is a %s, not a %s"),
|
||||
oid_to_hex(oid), type_name(type),
|
||||
type_name(OBJ_COMMIT));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
commit = lookup_commit(r, maybe_peeled);
|
||||
if (!commit || repo_parse_commit_gently(r, commit, quiet) < 0)
|
||||
return NULL;
|
||||
|
||||
return commit;
|
||||
}
|
||||
|
||||
struct commit *lookup_commit_reference(struct repository *r, const struct object_id *oid)
|
||||
|
||||
14
commit.h
14
commit.h
@@ -103,16 +103,26 @@ static inline int repo_parse_commit(struct repository *r, struct commit *item)
|
||||
return repo_parse_commit_gently(r, item, 0);
|
||||
}
|
||||
|
||||
void unparse_commit(struct repository *r, const struct object_id *oid);
|
||||
|
||||
static inline int repo_parse_commit_no_graph(struct repository *r,
|
||||
struct commit *commit)
|
||||
{
|
||||
/*
|
||||
* When the commit has been parsed but its tree wasn't populated then
|
||||
* this is an indicator that it has been parsed via the commit-graph.
|
||||
* We cannot read the tree via the commit-graph, as we're explicitly
|
||||
* told not to use it. We thus have to first un-parse the object so
|
||||
* that we can re-parse it without the graph.
|
||||
*/
|
||||
if (commit->object.parsed && !commit->maybe_tree)
|
||||
unparse_commit(r, &commit->object.oid);
|
||||
|
||||
return repo_parse_commit_internal(r, commit, 0, 0);
|
||||
}
|
||||
|
||||
void parse_commit_or_die(struct commit *item);
|
||||
|
||||
void unparse_commit(struct repository *r, const struct object_id *oid);
|
||||
|
||||
struct buffer_slab;
|
||||
struct buffer_slab *allocate_commit_buffer_slab(void);
|
||||
void free_commit_buffer_slab(struct buffer_slab *bs);
|
||||
|
||||
@@ -26,7 +26,7 @@ expression s;
|
||||
// repo_get_commit_tree() on the LHS.
|
||||
@@
|
||||
identifier f != { repo_get_commit_tree, get_commit_tree_in_graph_one,
|
||||
load_tree_for_commit, set_commit_tree };
|
||||
load_tree_for_commit, set_commit_tree, repo_parse_commit_no_graph };
|
||||
expression c;
|
||||
@@
|
||||
f(...) {<...
|
||||
|
||||
23
object.c
23
object.c
@@ -207,10 +207,11 @@ struct object *lookup_object_by_type(struct repository *r,
|
||||
}
|
||||
}
|
||||
|
||||
enum peel_status peel_object(struct repository *r,
|
||||
const struct object_id *name,
|
||||
struct object_id *oid,
|
||||
unsigned flags)
|
||||
enum peel_status peel_object_ext(struct repository *r,
|
||||
const struct object_id *name,
|
||||
struct object_id *oid,
|
||||
unsigned flags,
|
||||
enum object_type *typep)
|
||||
{
|
||||
struct object *o = lookup_unknown_object(r, name);
|
||||
|
||||
@@ -220,8 +221,10 @@ enum peel_status peel_object(struct repository *r,
|
||||
return PEEL_INVALID;
|
||||
}
|
||||
|
||||
if (o->type != OBJ_TAG)
|
||||
if (o->type != OBJ_TAG) {
|
||||
*typep = o->type;
|
||||
return PEEL_NON_TAG;
|
||||
}
|
||||
|
||||
while (o && o->type == OBJ_TAG) {
|
||||
o = parse_object(r, &o->oid);
|
||||
@@ -241,9 +244,19 @@ enum peel_status peel_object(struct repository *r,
|
||||
return PEEL_INVALID;
|
||||
|
||||
oidcpy(oid, &o->oid);
|
||||
*typep = o->type;
|
||||
return PEEL_PEELED;
|
||||
}
|
||||
|
||||
enum peel_status peel_object(struct repository *r,
|
||||
const struct object_id *name,
|
||||
struct object_id *oid,
|
||||
unsigned flags)
|
||||
{
|
||||
enum object_type dummy;
|
||||
return peel_object_ext(r, name, oid, flags, &dummy);
|
||||
}
|
||||
|
||||
struct object *parse_object_buffer(struct repository *r, const struct object_id *oid, enum object_type type, unsigned long size, void *buffer, int *eaten_p)
|
||||
{
|
||||
struct object *obj;
|
||||
|
||||
5
object.h
5
object.h
@@ -309,6 +309,11 @@ enum peel_status peel_object(struct repository *r,
|
||||
const struct object_id *name,
|
||||
struct object_id *oid,
|
||||
unsigned flags);
|
||||
enum peel_status peel_object_ext(struct repository *r,
|
||||
const struct object_id *name,
|
||||
struct object_id *oid,
|
||||
unsigned flags,
|
||||
enum object_type *typep);
|
||||
|
||||
struct object_list *object_list_insert(struct object *item,
|
||||
struct object_list **list_p);
|
||||
|
||||
Reference in New Issue
Block a user