blob: e295e87943102c2a1ad903aea1a634d34bf603a0 [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
Stefan Beller212e0f72018-08-20 18:24:19 +00009static int register_replace_ref(struct repository *r,
10 const char *refname,
Michael Haggerty00530832015-05-25 18:39:02 +000011 const struct object_id *oid,
Christian Couder68095572009-01-23 10:06:53 +010012 int flag, void *cb_data)
13{
14 /* Get sha1 from refname */
15 const char *slash = strrchr(refname, '/');
16 const char *hash = slash ? slash + 1 : refname;
17 struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
18
René Scharfef37b9bc2018-04-11 17:21:04 -070019 if (get_oid_hex(hash, &repl_obj->original.oid)) {
Christian Couder68095572009-01-23 10:06:53 +010020 free(repl_obj);
Nguyễn Thái Ngọc Duyb73c6e32018-07-21 09:49:37 +020021 warning(_("bad replace ref name: %s"), refname);
Christian Couder68095572009-01-23 10:06:53 +010022 return 0;
23 }
24
25 /* Copy sha1 from the read ref */
brian m. carlson1731a1e2018-03-12 02:27:33 +000026 oidcpy(&repl_obj->replacement, oid);
Christian Couder68095572009-01-23 10:06:53 +010027
28 /* Register new object */
Stefan Beller212e0f72018-08-20 18:24:19 +000029 if (oidmap_put(r->objects->replace_map, repl_obj))
Nguyễn Thái Ngọc Duyb73c6e32018-07-21 09:49:37 +020030 die(_("duplicate replace ref: %s"), refname);
Christian Couder68095572009-01-23 10:06:53 +010031
32 return 0;
33}
34
Derrick Stoleed6538242018-08-20 18:24:27 +000035void prepare_replace_object(struct repository *r)
Christian Couder68095572009-01-23 10:06:53 +010036{
Stefan Beller5982da92018-04-11 17:21:16 -070037 if (r->objects->replace_map)
Christian Couder68095572009-01-23 10:06:53 +010038 return;
39
Stefan Beller5982da92018-04-11 17:21:16 -070040 r->objects->replace_map =
Stefan Beller74fd0702018-05-09 16:40:59 -070041 xmalloc(sizeof(*r->objects->replace_map));
Stefan Beller5982da92018-04-11 17:21:16 -070042 oidmap_init(r->objects->replace_map, 0);
Stefan Bellerc1274492018-04-11 17:21:07 -070043
Stefan Beller5982da92018-04-11 17:21:16 -070044 for_each_replace_ref(r, register_replace_ref, NULL);
Christian Couder68095572009-01-23 10:06:53 +010045}
46
47/* We allow "recursive" replacement. Only within reason, though */
48#define MAXREPLACEDEPTH 5
49
Michael Haggerty1f91e792014-02-28 17:29:16 +010050/*
brian m. carlsonb383a132018-03-12 02:27:54 +000051 * If a replacement for object oid has been set up, return the
Michael Haggerty1f91e792014-02-28 17:29:16 +010052 * replacement object's name (replaced recursively, if necessary).
brian m. carlsonb383a132018-03-12 02:27:54 +000053 * The return value is either oid or a pointer to a
Michael Haggerty1f91e792014-02-28 17:29:16 +010054 * permanently-allocated value. This function always respects replace
Jeff King6ebd1ca2018-07-18 16:45:20 -040055 * references, regardless of the value of read_replace_refs.
Michael Haggerty1f91e792014-02-28 17:29:16 +010056 */
Stefan Beller56435572018-04-11 17:21:17 -070057const struct object_id *do_lookup_replace_object(struct repository *r,
58 const struct object_id *oid)
Christian Couder68095572009-01-23 10:06:53 +010059{
René Scharfef37b9bc2018-04-11 17:21:04 -070060 int depth = MAXREPLACEDEPTH;
brian m. carlsonb383a132018-03-12 02:27:54 +000061 const struct object_id *cur = oid;
Christian Couder68095572009-01-23 10:06:53 +010062
Stefan Beller56435572018-04-11 17:21:17 -070063 prepare_replace_object(r);
Christian Couder68095572009-01-23 10:06:53 +010064
65 /* Try to recursively replace the object */
René Scharfef37b9bc2018-04-11 17:21:04 -070066 while (depth-- > 0) {
Stefan Bellerd88f9fd2018-04-11 17:21:05 -070067 struct replace_object *repl_obj =
Stefan Beller56435572018-04-11 17:21:17 -070068 oidmap_get(r->objects->replace_map, cur);
René Scharfef37b9bc2018-04-11 17:21:04 -070069 if (!repl_obj)
70 return cur;
71 cur = &repl_obj->replacement;
72 }
Nguyễn Thái Ngọc Duyb73c6e32018-07-21 09:49:37 +020073 die(_("replace depth too high for object %s"), oid_to_hex(oid));
Christian Couder68095572009-01-23 10:06:53 +010074}