blob: 801b5c16789f5ac7d87a4409d8218311a52db0aa [file] [log] [blame]
Christian Couder68095572009-01-23 10:06:53 +01001#include "cache.h"
René Scharfef37b9bc2018-04-11 17:21:04 -07002#include "oidmap.h"
Stefan Bellerd88f9fd2018-04-11 17:21:05 -07003#include "object-store.h"
4#include "replace-object.h"
Christian Couder68095572009-01-23 10:06:53 +01005#include "refs.h"
Stefan Bellerd88f9fd2018-04-11 17:21:05 -07006#include "repository.h"
Stephen Boydc2e86ad2011-03-22 00:51:05 -07007#include "commit.h"
Christian Couder68095572009-01-23 10:06:53 +01008
Christian Couder68095572009-01-23 10:06:53 +01009static int register_replace_ref(const char *refname,
Michael Haggerty00530832015-05-25 18:39:02 +000010 const struct object_id *oid,
Christian Couder68095572009-01-23 10:06:53 +010011 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
René Scharfef37b9bc2018-04-11 17:21:04 -070018 if (get_oid_hex(hash, &repl_obj->original.oid)) {
Christian Couder68095572009-01-23 10:06:53 +010019 free(repl_obj);
20 warning("bad replace ref name: %s", refname);
21 return 0;
22 }
23
24 /* Copy sha1 from the read ref */
brian m. carlson1731a1e2018-03-12 02:27:33 +000025 oidcpy(&repl_obj->replacement, oid);
Christian Couder68095572009-01-23 10:06:53 +010026
27 /* Register new object */
Stefan Bellerc1274492018-04-11 17:21:07 -070028 if (oidmap_put(the_repository->objects->replace_map, repl_obj))
Christian Couder68095572009-01-23 10:06:53 +010029 die("duplicate replace ref: %s", refname);
30
31 return 0;
32}
33
Stefan Beller5982da92018-04-11 17:21:16 -070034static void prepare_replace_object(struct repository *r)
Christian Couder68095572009-01-23 10:06:53 +010035{
Stefan Beller5982da92018-04-11 17:21:16 -070036 if (r->objects->replace_map)
Christian Couder68095572009-01-23 10:06:53 +010037 return;
38
Stefan Beller5982da92018-04-11 17:21:16 -070039 r->objects->replace_map =
Stefan Beller74fd0702018-05-09 16:40:59 -070040 xmalloc(sizeof(*r->objects->replace_map));
Stefan Beller5982da92018-04-11 17:21:16 -070041 oidmap_init(r->objects->replace_map, 0);
Stefan Bellerc1274492018-04-11 17:21:07 -070042
Stefan Beller5982da92018-04-11 17:21:16 -070043 for_each_replace_ref(r, register_replace_ref, NULL);
Christian Couder68095572009-01-23 10:06:53 +010044}
45
46/* We allow "recursive" replacement. Only within reason, though */
47#define MAXREPLACEDEPTH 5
48
Michael Haggerty1f91e792014-02-28 17:29:16 +010049/*
brian m. carlsonb383a132018-03-12 02:27:54 +000050 * If a replacement for object oid has been set up, return the
Michael Haggerty1f91e792014-02-28 17:29:16 +010051 * replacement object's name (replaced recursively, if necessary).
brian m. carlsonb383a132018-03-12 02:27:54 +000052 * The return value is either oid or a pointer to a
Michael Haggerty1f91e792014-02-28 17:29:16 +010053 * permanently-allocated value. This function always respects replace
54 * references, regardless of the value of check_replace_refs.
55 */
Stefan Beller56435572018-04-11 17:21:17 -070056const struct object_id *do_lookup_replace_object(struct repository *r,
57 const struct object_id *oid)
Christian Couder68095572009-01-23 10:06:53 +010058{
René Scharfef37b9bc2018-04-11 17:21:04 -070059 int depth = MAXREPLACEDEPTH;
brian m. carlsonb383a132018-03-12 02:27:54 +000060 const struct object_id *cur = oid;
Christian Couder68095572009-01-23 10:06:53 +010061
Stefan Beller56435572018-04-11 17:21:17 -070062 prepare_replace_object(r);
Christian Couder68095572009-01-23 10:06:53 +010063
64 /* Try to recursively replace the object */
René Scharfef37b9bc2018-04-11 17:21:04 -070065 while (depth-- > 0) {
Stefan Bellerd88f9fd2018-04-11 17:21:05 -070066 struct replace_object *repl_obj =
Stefan Beller56435572018-04-11 17:21:17 -070067 oidmap_get(r->objects->replace_map, cur);
René Scharfef37b9bc2018-04-11 17:21:04 -070068 if (!repl_obj)
69 return cur;
70 cur = &repl_obj->replacement;
71 }
72 die("replace depth too high for object %s", oid_to_hex(oid));
Christian Couder68095572009-01-23 10:06:53 +010073}