Git fork
at reftables-rust 582 lines 14 kB view raw
1#define DISABLE_SIGN_COMPARE_WARNINGS 2 3#include "git-compat-util.h" 4#include "gettext.h" 5#include "hex.h" 6#include "object.h" 7#include "replace-object.h" 8#include "object-file.h" 9#include "blob.h" 10#include "statinfo.h" 11#include "tree.h" 12#include "commit.h" 13#include "tag.h" 14#include "alloc.h" 15#include "commit-graph.h" 16 17unsigned int get_max_object_index(const struct repository *repo) 18{ 19 return repo->parsed_objects->obj_hash_size; 20} 21 22struct object *get_indexed_object(const struct repository *repo, 23 unsigned int idx) 24{ 25 return repo->parsed_objects->obj_hash[idx]; 26} 27 28static const char *object_type_strings[] = { 29 NULL, /* OBJ_NONE = 0 */ 30 "commit", /* OBJ_COMMIT = 1 */ 31 "tree", /* OBJ_TREE = 2 */ 32 "blob", /* OBJ_BLOB = 3 */ 33 "tag", /* OBJ_TAG = 4 */ 34}; 35 36const char *type_name(unsigned int type) 37{ 38 if (type >= ARRAY_SIZE(object_type_strings)) 39 return NULL; 40 return object_type_strings[type]; 41} 42 43int type_from_string_gently(const char *str, ssize_t len, int gentle) 44{ 45 int i; 46 47 if (len < 0) 48 len = strlen(str); 49 50 for (i = 1; i < ARRAY_SIZE(object_type_strings); i++) 51 if (!xstrncmpz(object_type_strings[i], str, len)) 52 return i; 53 54 if (gentle) 55 return -1; 56 57 die(_("invalid object type \"%s\""), str); 58} 59 60/* 61 * Return a numerical hash value between 0 and n-1 for the object with 62 * the specified sha1. n must be a power of 2. Please note that the 63 * return value is *not* consistent across computer architectures. 64 */ 65static unsigned int hash_obj(const struct object_id *oid, unsigned int n) 66{ 67 return oidhash(oid) & (n - 1); 68} 69 70/* 71 * Insert obj into the hash table hash, which has length size (which 72 * must be a power of 2). On collisions, simply overflow to the next 73 * empty bucket. 74 */ 75static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size) 76{ 77 unsigned int j = hash_obj(&obj->oid, size); 78 79 while (hash[j]) { 80 j++; 81 if (j >= size) 82 j = 0; 83 } 84 hash[j] = obj; 85} 86 87/* 88 * Look up the record for the given sha1 in the hash map stored in 89 * obj_hash. Return NULL if it was not found. 90 */ 91struct object *lookup_object(struct repository *r, const struct object_id *oid) 92{ 93 unsigned int i, first; 94 struct object *obj; 95 96 if (!r->parsed_objects->obj_hash) 97 return NULL; 98 99 first = i = hash_obj(oid, r->parsed_objects->obj_hash_size); 100 while ((obj = r->parsed_objects->obj_hash[i]) != NULL) { 101 if (oideq(oid, &obj->oid)) 102 break; 103 i++; 104 if (i == r->parsed_objects->obj_hash_size) 105 i = 0; 106 } 107 if (obj && i != first) { 108 /* 109 * Move object to where we started to look for it so 110 * that we do not need to walk the hash table the next 111 * time we look for it. 112 */ 113 SWAP(r->parsed_objects->obj_hash[i], 114 r->parsed_objects->obj_hash[first]); 115 } 116 return obj; 117} 118 119/* 120 * Increase the size of the hash map stored in obj_hash to the next 121 * power of 2 (but at least 32). Copy the existing values to the new 122 * hash map. 123 */ 124static void grow_object_hash(struct repository *r) 125{ 126 int i; 127 /* 128 * Note that this size must always be power-of-2 to match hash_obj 129 * above. 130 */ 131 int new_hash_size = r->parsed_objects->obj_hash_size < 32 ? 32 : 2 * r->parsed_objects->obj_hash_size; 132 struct object **new_hash; 133 134 CALLOC_ARRAY(new_hash, new_hash_size); 135 for (i = 0; i < r->parsed_objects->obj_hash_size; i++) { 136 struct object *obj = r->parsed_objects->obj_hash[i]; 137 138 if (!obj) 139 continue; 140 insert_obj_hash(obj, new_hash, new_hash_size); 141 } 142 free(r->parsed_objects->obj_hash); 143 r->parsed_objects->obj_hash = new_hash; 144 r->parsed_objects->obj_hash_size = new_hash_size; 145} 146 147void *create_object(struct repository *r, const struct object_id *oid, void *o) 148{ 149 struct object *obj = o; 150 151 obj->parsed = 0; 152 obj->flags = 0; 153 oidcpy(&obj->oid, oid); 154 155 if (r->parsed_objects->obj_hash_size - 1 <= r->parsed_objects->nr_objs * 2) 156 grow_object_hash(r); 157 158 insert_obj_hash(obj, r->parsed_objects->obj_hash, 159 r->parsed_objects->obj_hash_size); 160 r->parsed_objects->nr_objs++; 161 return obj; 162} 163 164void *object_as_type(struct object *obj, enum object_type type, int quiet) 165{ 166 if (obj->type == type) 167 return obj; 168 else if (obj->type == OBJ_NONE) { 169 if (type == OBJ_COMMIT) 170 init_commit_node((struct commit *) obj); 171 else 172 obj->type = type; 173 return obj; 174 } 175 else { 176 if (!quiet) 177 error(_("object %s is a %s, not a %s"), 178 oid_to_hex(&obj->oid), 179 type_name(obj->type), type_name(type)); 180 return NULL; 181 } 182} 183 184struct object *lookup_unknown_object(struct repository *r, const struct object_id *oid) 185{ 186 struct object *obj = lookup_object(r, oid); 187 if (!obj) 188 obj = create_object(r, oid, alloc_object_node(r)); 189 return obj; 190} 191 192struct object *lookup_object_by_type(struct repository *r, 193 const struct object_id *oid, 194 enum object_type type) 195{ 196 switch (type) { 197 case OBJ_COMMIT: 198 return (struct object *)lookup_commit(r, oid); 199 case OBJ_TREE: 200 return (struct object *)lookup_tree(r, oid); 201 case OBJ_TAG: 202 return (struct object *)lookup_tag(r, oid); 203 case OBJ_BLOB: 204 return (struct object *)lookup_blob(r, oid); 205 default: 206 BUG("unknown object type %d", type); 207 } 208} 209 210enum peel_status peel_object(struct repository *r, 211 const struct object_id *name, 212 struct object_id *oid) 213{ 214 struct object *o = lookup_unknown_object(r, name); 215 216 if (o->type == OBJ_NONE) { 217 int type = odb_read_object_info(r->objects, name, NULL); 218 if (type < 0 || !object_as_type(o, type, 0)) 219 return PEEL_INVALID; 220 } 221 222 if (o->type != OBJ_TAG) 223 return PEEL_NON_TAG; 224 225 o = deref_tag_noverify(r, o); 226 if (!o) 227 return PEEL_INVALID; 228 229 oidcpy(oid, &o->oid); 230 return PEEL_PEELED; 231} 232 233struct object *parse_object_buffer(struct repository *r, const struct object_id *oid, enum object_type type, unsigned long size, void *buffer, int *eaten_p) 234{ 235 struct object *obj; 236 *eaten_p = 0; 237 238 obj = NULL; 239 if (type == OBJ_BLOB) { 240 struct blob *blob = lookup_blob(r, oid); 241 if (blob) { 242 parse_blob_buffer(blob); 243 obj = &blob->object; 244 } 245 } else if (type == OBJ_TREE) { 246 struct tree *tree = lookup_tree(r, oid); 247 if (tree) { 248 obj = &tree->object; 249 if (!tree->buffer) 250 tree->object.parsed = 0; 251 if (!tree->object.parsed) { 252 if (parse_tree_buffer(tree, buffer, size)) 253 return NULL; 254 *eaten_p = 1; 255 } 256 } 257 } else if (type == OBJ_COMMIT) { 258 struct commit *commit = lookup_commit(r, oid); 259 if (commit) { 260 if (parse_commit_buffer(r, commit, buffer, size, 1)) 261 return NULL; 262 if (save_commit_buffer && 263 !get_cached_commit_buffer(r, commit, NULL)) { 264 set_commit_buffer(r, commit, buffer, size); 265 *eaten_p = 1; 266 } 267 obj = &commit->object; 268 } 269 } else if (type == OBJ_TAG) { 270 struct tag *tag = lookup_tag(r, oid); 271 if (tag) { 272 if (parse_tag_buffer(r, tag, buffer, size)) 273 return NULL; 274 obj = &tag->object; 275 } 276 } else { 277 warning(_("object %s has unknown type id %d"), oid_to_hex(oid), type); 278 obj = NULL; 279 } 280 return obj; 281} 282 283struct object *parse_object_or_die(struct repository *repo, 284 const struct object_id *oid, 285 const char *name) 286{ 287 struct object *o = parse_object(repo, oid); 288 if (o) 289 return o; 290 291 die(_("unable to parse object: %s"), name ? name : oid_to_hex(oid)); 292} 293 294struct object *parse_object_with_flags(struct repository *r, 295 const struct object_id *oid, 296 enum parse_object_flags flags) 297{ 298 int skip_hash = !!(flags & PARSE_OBJECT_SKIP_HASH_CHECK); 299 int discard_tree = !!(flags & PARSE_OBJECT_DISCARD_TREE); 300 unsigned long size; 301 enum object_type type; 302 int eaten; 303 const struct object_id *repl = lookup_replace_object(r, oid); 304 void *buffer; 305 struct object *obj; 306 307 obj = lookup_object(r, oid); 308 if (obj && obj->parsed) 309 return obj; 310 311 if (skip_hash) { 312 struct commit *commit = lookup_commit_in_graph(r, repl); 313 if (commit) 314 return &commit->object; 315 } 316 317 if ((!obj || obj->type == OBJ_BLOB) && 318 odb_read_object_info(r->objects, oid, NULL) == OBJ_BLOB) { 319 if (!skip_hash && stream_object_signature(r, repl) < 0) { 320 error(_("hash mismatch %s"), oid_to_hex(oid)); 321 return NULL; 322 } 323 parse_blob_buffer(lookup_blob(r, oid)); 324 return lookup_object(r, oid); 325 } 326 327 /* 328 * If the caller does not care about the tree buffer and does not 329 * care about checking the hash, we can simply verify that we 330 * have the on-disk object with the correct type. 331 */ 332 if (skip_hash && discard_tree && 333 (!obj || obj->type == OBJ_TREE) && 334 odb_read_object_info(r->objects, oid, NULL) == OBJ_TREE) { 335 return &lookup_tree(r, oid)->object; 336 } 337 338 buffer = odb_read_object(r->objects, oid, &type, &size); 339 if (buffer) { 340 if (!skip_hash && 341 check_object_signature(r, repl, buffer, size, type) < 0) { 342 free(buffer); 343 error(_("hash mismatch %s"), oid_to_hex(repl)); 344 return NULL; 345 } 346 347 obj = parse_object_buffer(r, oid, type, size, 348 buffer, &eaten); 349 if (!eaten) 350 free(buffer); 351 if (discard_tree && type == OBJ_TREE) 352 free_tree_buffer((struct tree *)obj); 353 return obj; 354 } 355 return NULL; 356} 357 358struct object *parse_object(struct repository *r, const struct object_id *oid) 359{ 360 return parse_object_with_flags(r, oid, 0); 361} 362 363struct object_list *object_list_insert(struct object *item, 364 struct object_list **list_p) 365{ 366 struct object_list *new_list = xmalloc(sizeof(struct object_list)); 367 new_list->item = item; 368 new_list->next = *list_p; 369 *list_p = new_list; 370 return new_list; 371} 372 373int object_list_contains(struct object_list *list, struct object *obj) 374{ 375 while (list) { 376 if (list->item == obj) 377 return 1; 378 list = list->next; 379 } 380 return 0; 381} 382 383void object_list_free(struct object_list **list) 384{ 385 while (*list) { 386 struct object_list *p = *list; 387 *list = p->next; 388 free(p); 389 } 390} 391 392/* 393 * A zero-length string to which object_array_entry::name can be 394 * initialized without requiring a malloc/free. 395 */ 396static char object_array_slopbuf[1]; 397 398void object_array_init(struct object_array *array) 399{ 400 struct object_array blank = OBJECT_ARRAY_INIT; 401 memcpy(array, &blank, sizeof(*array)); 402} 403 404void add_object_array_with_path(struct object *obj, const char *name, 405 struct object_array *array, 406 unsigned mode, const char *path) 407{ 408 unsigned nr = array->nr; 409 unsigned alloc = array->alloc; 410 struct object_array_entry *objects = array->objects; 411 struct object_array_entry *entry; 412 413 if (nr >= alloc) { 414 alloc = (alloc + 32) * 2; 415 REALLOC_ARRAY(objects, alloc); 416 array->alloc = alloc; 417 array->objects = objects; 418 } 419 entry = &objects[nr]; 420 entry->item = obj; 421 if (!name) 422 entry->name = NULL; 423 else if (!*name) 424 /* Use our own empty string instead of allocating one: */ 425 entry->name = object_array_slopbuf; 426 else 427 entry->name = xstrdup(name); 428 entry->mode = mode; 429 if (path) 430 entry->path = xstrdup(path); 431 else 432 entry->path = NULL; 433 array->nr = ++nr; 434} 435 436void add_object_array(struct object *obj, const char *name, struct object_array *array) 437{ 438 add_object_array_with_path(obj, name, array, S_IFINVALID, NULL); 439} 440 441/* 442 * Free all memory associated with an entry; the result is 443 * in an unspecified state and should not be examined. 444 */ 445static void object_array_release_entry(struct object_array_entry *ent) 446{ 447 if (ent->name != object_array_slopbuf) 448 free(ent->name); 449 free(ent->path); 450} 451 452struct object *object_array_pop(struct object_array *array) 453{ 454 struct object *ret; 455 456 if (!array->nr) 457 return NULL; 458 459 ret = array->objects[array->nr - 1].item; 460 object_array_release_entry(&array->objects[array->nr - 1]); 461 array->nr--; 462 return ret; 463} 464 465void object_array_filter(struct object_array *array, 466 object_array_each_func_t want, void *cb_data) 467{ 468 unsigned nr = array->nr, src, dst; 469 struct object_array_entry *objects = array->objects; 470 471 for (src = dst = 0; src < nr; src++) { 472 if (want(&objects[src], cb_data)) { 473 if (src != dst) 474 objects[dst] = objects[src]; 475 dst++; 476 } else { 477 object_array_release_entry(&objects[src]); 478 } 479 } 480 array->nr = dst; 481} 482 483void object_array_clear(struct object_array *array) 484{ 485 int i; 486 for (i = 0; i < array->nr; i++) 487 object_array_release_entry(&array->objects[i]); 488 FREE_AND_NULL(array->objects); 489 array->nr = array->alloc = 0; 490} 491 492void clear_object_flags(struct repository *repo, unsigned flags) 493{ 494 int i; 495 496 for (i = 0; i < repo->parsed_objects->obj_hash_size; i++) { 497 struct object *obj = repo->parsed_objects->obj_hash[i]; 498 if (obj) 499 obj->flags &= ~flags; 500 } 501} 502 503void repo_clear_commit_marks(struct repository *r, unsigned int flags) 504{ 505 int i; 506 507 for (i = 0; i < r->parsed_objects->obj_hash_size; i++) { 508 struct object *obj = r->parsed_objects->obj_hash[i]; 509 if (obj && obj->type == OBJ_COMMIT) 510 obj->flags &= ~flags; 511 } 512} 513 514struct parsed_object_pool *parsed_object_pool_new(struct repository *repo) 515{ 516 struct parsed_object_pool *o = xmalloc(sizeof(*o)); 517 memset(o, 0, sizeof(*o)); 518 519 o->repo = repo; 520 o->blob_state = alloc_state_alloc(); 521 o->tree_state = alloc_state_alloc(); 522 o->commit_state = alloc_state_alloc(); 523 o->tag_state = alloc_state_alloc(); 524 o->object_state = alloc_state_alloc(); 525 o->is_shallow = -1; 526 CALLOC_ARRAY(o->shallow_stat, 1); 527 528 o->buffer_slab = allocate_commit_buffer_slab(); 529 530 return o; 531} 532 533void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o) 534{ 535 for (int i = 0; i < o->grafts_nr; i++) { 536 unparse_commit(o->repo, &o->grafts[i]->oid); 537 free(o->grafts[i]); 538 } 539 o->grafts_nr = 0; 540 o->commit_graft_prepared = 0; 541} 542 543void parsed_object_pool_clear(struct parsed_object_pool *o) 544{ 545 /* 546 * As objects are allocated in slabs (see alloc.c), we do 547 * not need to free each object, but each slab instead. 548 * 549 * Before doing so, we need to free any additional memory 550 * the objects may hold. 551 */ 552 unsigned i; 553 554 for (i = 0; i < o->obj_hash_size; i++) { 555 struct object *obj = o->obj_hash[i]; 556 557 if (!obj) 558 continue; 559 560 if (obj->type == OBJ_TREE) 561 free_tree_buffer((struct tree*)obj); 562 else if (obj->type == OBJ_COMMIT) 563 release_commit_memory(o, (struct commit*)obj); 564 else if (obj->type == OBJ_TAG) 565 release_tag_memory((struct tag*)obj); 566 } 567 568 FREE_AND_NULL(o->obj_hash); 569 o->obj_hash_size = 0; 570 571 free_commit_buffer_slab(o->buffer_slab); 572 o->buffer_slab = NULL; 573 574 parsed_object_pool_reset_commit_grafts(o); 575 alloc_state_free_and_null(&o->blob_state); 576 alloc_state_free_and_null(&o->tree_state); 577 alloc_state_free_and_null(&o->commit_state); 578 alloc_state_free_and_null(&o->tag_state); 579 alloc_state_free_and_null(&o->object_state); 580 stat_validity_clear(o->shallow_stat); 581 FREE_AND_NULL(o->shallow_stat); 582}