replace-object.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "cache.h"
  2. #include "oidmap.h"
  3. #include "object-store.h"
  4. #include "replace-object.h"
  5. #include "refs.h"
  6. #include "repository.h"
  7. #include "commit.h"
  8. static int register_replace_ref(struct repository *r,
  9. const char *refname,
  10. const struct object_id *oid,
  11. int flag, void *cb_data)
  12. {
  13. /* Get sha1 from refname */
  14. const char *slash = strrchr(refname, '/');
  15. const char *hash = slash ? slash + 1 : refname;
  16. struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
  17. if (get_oid_hex(hash, &repl_obj->original.oid)) {
  18. free(repl_obj);
  19. warning(_("bad replace ref name: %s"), refname);
  20. return 0;
  21. }
  22. /* Copy sha1 from the read ref */
  23. oidcpy(&repl_obj->replacement, oid);
  24. /* Register new object */
  25. if (oidmap_put(r->objects->replace_map, repl_obj))
  26. die(_("duplicate replace ref: %s"), refname);
  27. return 0;
  28. }
  29. void prepare_replace_object(struct repository *r)
  30. {
  31. if (r->objects->replace_map_initialized)
  32. return;
  33. pthread_mutex_lock(&r->objects->replace_mutex);
  34. if (r->objects->replace_map_initialized) {
  35. pthread_mutex_unlock(&r->objects->replace_mutex);
  36. return;
  37. }
  38. r->objects->replace_map =
  39. xmalloc(sizeof(*r->objects->replace_map));
  40. oidmap_init(r->objects->replace_map, 0);
  41. for_each_replace_ref(r, register_replace_ref, NULL);
  42. r->objects->replace_map_initialized = 1;
  43. pthread_mutex_unlock(&r->objects->replace_mutex);
  44. }
  45. /* We allow "recursive" replacement. Only within reason, though */
  46. #define MAXREPLACEDEPTH 5
  47. /*
  48. * If a replacement for object oid has been set up, return the
  49. * replacement object's name (replaced recursively, if necessary).
  50. * The return value is either oid or a pointer to a
  51. * permanently-allocated value. This function always respects replace
  52. * references, regardless of the value of read_replace_refs.
  53. */
  54. const struct object_id *do_lookup_replace_object(struct repository *r,
  55. const struct object_id *oid)
  56. {
  57. int depth = MAXREPLACEDEPTH;
  58. const struct object_id *cur = oid;
  59. prepare_replace_object(r);
  60. /* Try to recursively replace the object */
  61. while (depth-- > 0) {
  62. struct replace_object *repl_obj =
  63. oidmap_get(r->objects->replace_map, cur);
  64. if (!repl_obj)
  65. return cur;
  66. cur = &repl_obj->replacement;
  67. }
  68. die(_("replace depth too high for object %s"), oid_to_hex(oid));
  69. }