Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 1 | #include "cache.h" |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 2 | #include "oidmap.h" |
Stefan Beller | d88f9fd | 2018-04-11 17:21:05 -0700 | [diff] [blame] | 3 | #include "object-store.h" |
| 4 | #include "replace-object.h" |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 5 | #include "refs.h" |
Stefan Beller | d88f9fd | 2018-04-11 17:21:05 -0700 | [diff] [blame] | 6 | #include "repository.h" |
Stephen Boyd | c2e86ad | 2011-03-22 00:51:05 -0700 | [diff] [blame] | 7 | #include "commit.h" |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 8 | |
Stefan Beller | 212e0f7 | 2018-08-20 18:24:19 +0000 | [diff] [blame] | 9 | static int register_replace_ref(struct repository *r, |
| 10 | const char *refname, |
Michael Haggerty | 0053083 | 2015-05-25 18:39:02 +0000 | [diff] [blame] | 11 | const struct object_id *oid, |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 12 | 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é Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 19 | if (get_oid_hex(hash, &repl_obj->original.oid)) { |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 20 | free(repl_obj); |
Nguyễn Thái Ngọc Duy | b73c6e3 | 2018-07-21 09:49:37 +0200 | [diff] [blame] | 21 | warning(_("bad replace ref name: %s"), refname); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 22 | return 0; |
| 23 | } |
| 24 | |
| 25 | /* Copy sha1 from the read ref */ |
brian m. carlson | 1731a1e | 2018-03-12 02:27:33 +0000 | [diff] [blame] | 26 | oidcpy(&repl_obj->replacement, oid); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 27 | |
| 28 | /* Register new object */ |
Stefan Beller | 212e0f7 | 2018-08-20 18:24:19 +0000 | [diff] [blame] | 29 | if (oidmap_put(r->objects->replace_map, repl_obj)) |
Nguyễn Thái Ngọc Duy | b73c6e3 | 2018-07-21 09:49:37 +0200 | [diff] [blame] | 30 | die(_("duplicate replace ref: %s"), refname); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 31 | |
| 32 | return 0; |
| 33 | } |
| 34 | |
Derrick Stolee | d653824 | 2018-08-20 18:24:27 +0000 | [diff] [blame] | 35 | void prepare_replace_object(struct repository *r) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 36 | { |
Matheus Tavares | b1fc9da | 2020-01-15 23:39:52 -0300 | [diff] [blame] | 37 | if (r->objects->replace_map_initialized) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 38 | return; |
| 39 | |
Matheus Tavares | b1fc9da | 2020-01-15 23:39:52 -0300 | [diff] [blame] | 40 | pthread_mutex_lock(&r->objects->replace_mutex); |
| 41 | if (r->objects->replace_map_initialized) { |
| 42 | pthread_mutex_unlock(&r->objects->replace_mutex); |
| 43 | return; |
| 44 | } |
| 45 | |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 46 | r->objects->replace_map = |
Stefan Beller | 74fd070 | 2018-05-09 16:40:59 -0700 | [diff] [blame] | 47 | xmalloc(sizeof(*r->objects->replace_map)); |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 48 | oidmap_init(r->objects->replace_map, 0); |
Stefan Beller | c127449 | 2018-04-11 17:21:07 -0700 | [diff] [blame] | 49 | |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 50 | for_each_replace_ref(r, register_replace_ref, NULL); |
Matheus Tavares | b1fc9da | 2020-01-15 23:39:52 -0300 | [diff] [blame] | 51 | r->objects->replace_map_initialized = 1; |
| 52 | |
| 53 | pthread_mutex_unlock(&r->objects->replace_mutex); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | /* We allow "recursive" replacement. Only within reason, though */ |
| 57 | #define MAXREPLACEDEPTH 5 |
| 58 | |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 59 | /* |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 60 | * If a replacement for object oid has been set up, return the |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 61 | * replacement object's name (replaced recursively, if necessary). |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 62 | * The return value is either oid or a pointer to a |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 63 | * permanently-allocated value. This function always respects replace |
Jeff King | 6ebd1ca | 2018-07-18 16:45:20 -0400 | [diff] [blame] | 64 | * references, regardless of the value of read_replace_refs. |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 65 | */ |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 66 | const struct object_id *do_lookup_replace_object(struct repository *r, |
| 67 | const struct object_id *oid) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 68 | { |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 69 | int depth = MAXREPLACEDEPTH; |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 70 | const struct object_id *cur = oid; |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 71 | |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 72 | prepare_replace_object(r); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 73 | |
| 74 | /* Try to recursively replace the object */ |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 75 | while (depth-- > 0) { |
Stefan Beller | d88f9fd | 2018-04-11 17:21:05 -0700 | [diff] [blame] | 76 | struct replace_object *repl_obj = |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 77 | oidmap_get(r->objects->replace_map, cur); |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 78 | if (!repl_obj) |
| 79 | return cur; |
| 80 | cur = &repl_obj->replacement; |
| 81 | } |
Nguyễn Thái Ngọc Duy | b73c6e3 | 2018-07-21 09:49:37 +0200 | [diff] [blame] | 82 | die(_("replace depth too high for object %s"), oid_to_hex(oid)); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 83 | } |