diff options
Diffstat (limited to 'object.c')
| -rw-r--r-- | object.c | 44 |
1 files changed, 42 insertions, 2 deletions
@@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "gettext.h" #include "hex.h" @@ -13,6 +15,7 @@ #include "alloc.h" #include "packfile.h" #include "commit-graph.h" +#include "loose.h" unsigned int get_max_object_index(void) { @@ -47,8 +50,7 @@ int type_from_string_gently(const char *str, ssize_t len, int gentle) len = strlen(str); for (i = 1; i < ARRAY_SIZE(object_type_strings); i++) - if (!strncmp(str, object_type_strings[i], len) && - object_type_strings[i][len] == '\0') + if (!xstrncmpz(object_type_strings[i], str, len)) return i; if (gentle) @@ -207,6 +209,29 @@ 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) +{ + struct object *o = lookup_unknown_object(r, name); + + if (o->type == OBJ_NONE) { + int type = oid_object_info(r, name, NULL); + if (type < 0 || !object_as_type(o, type, 0)) + return PEEL_INVALID; + } + + if (o->type != OBJ_TAG) + return PEEL_NON_TAG; + + o = deref_tag_noverify(r, o); + if (!o) + return PEEL_INVALID; + + oidcpy(oid, &o->oid); + return PEEL_PEELED; +} + 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; @@ -272,6 +297,7 @@ struct object *parse_object_with_flags(struct repository *r, enum parse_object_flags flags) { int skip_hash = !!(flags & PARSE_OBJECT_SKIP_HASH_CHECK); + int discard_tree = !!(flags & PARSE_OBJECT_DISCARD_TREE); unsigned long size; enum object_type type; int eaten; @@ -299,6 +325,17 @@ struct object *parse_object_with_flags(struct repository *r, return lookup_object(r, oid); } + /* + * If the caller does not care about the tree buffer and does not + * care about checking the hash, we can simply verify that we + * have the on-disk object with the correct type. + */ + if (skip_hash && discard_tree && + (!obj || obj->type == OBJ_TREE) && + oid_object_info(r, oid, NULL) == OBJ_TREE) { + return &lookup_tree(r, oid)->object; + } + buffer = repo_read_object_file(r, oid, &type, &size); if (buffer) { if (!skip_hash && @@ -312,6 +349,8 @@ struct object *parse_object_with_flags(struct repository *r, buffer, &eaten); if (!eaten) free(buffer); + if (discard_tree && type == OBJ_TREE) + free_tree_buffer((struct tree *)obj); return obj; } return NULL; @@ -540,6 +579,7 @@ void free_object_directory(struct object_directory *odb) { free(odb->path); odb_clear_loose_cache(odb); + loose_object_map_clear(&odb->loose_map); free(odb); } |
