123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- #include "cache.h"
- #include "oidmap.h"
- #include "object-store.h"
- #include "replace-object.h"
- #include "refs.h"
- #include "repository.h"
- #include "commit.h"
- static int register_replace_ref(struct repository *r,
- const char *refname,
- const struct object_id *oid,
- int flag, void *cb_data)
- {
- /* Get sha1 from refname */
- const char *slash = strrchr(refname, '/');
- const char *hash = slash ? slash + 1 : refname;
- struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
- if (get_oid_hex(hash, &repl_obj->original.oid)) {
- free(repl_obj);
- warning(_("bad replace ref name: %s"), refname);
- return 0;
- }
- /* Copy sha1 from the read ref */
- oidcpy(&repl_obj->replacement, oid);
- /* Register new object */
- if (oidmap_put(r->objects->replace_map, repl_obj))
- die(_("duplicate replace ref: %s"), refname);
- return 0;
- }
- void prepare_replace_object(struct repository *r)
- {
- if (r->objects->replace_map_initialized)
- return;
- pthread_mutex_lock(&r->objects->replace_mutex);
- if (r->objects->replace_map_initialized) {
- pthread_mutex_unlock(&r->objects->replace_mutex);
- return;
- }
- r->objects->replace_map =
- xmalloc(sizeof(*r->objects->replace_map));
- oidmap_init(r->objects->replace_map, 0);
- for_each_replace_ref(r, register_replace_ref, NULL);
- r->objects->replace_map_initialized = 1;
- pthread_mutex_unlock(&r->objects->replace_mutex);
- }
- /* We allow "recursive" replacement. Only within reason, though */
- #define MAXREPLACEDEPTH 5
- /*
- * If a replacement for object oid has been set up, return the
- * replacement object's name (replaced recursively, if necessary).
- * The return value is either oid or a pointer to a
- * permanently-allocated value. This function always respects replace
- * references, regardless of the value of read_replace_refs.
- */
- const struct object_id *do_lookup_replace_object(struct repository *r,
- const struct object_id *oid)
- {
- int depth = MAXREPLACEDEPTH;
- const struct object_id *cur = oid;
- prepare_replace_object(r);
- /* Try to recursively replace the object */
- while (depth-- > 0) {
- struct replace_object *repl_obj =
- oidmap_get(r->objects->replace_map, cur);
- if (!repl_obj)
- return cur;
- cur = &repl_obj->replacement;
- }
- die(_("replace depth too high for object %s"), oid_to_hex(oid));
- }
|