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 | |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 9 | static int register_replace_ref(const char *refname, |
Michael Haggerty | 0053083 | 2015-05-25 18:39:02 +0000 | [diff] [blame] | 10 | const struct object_id *oid, |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 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 | |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 18 | if (get_oid_hex(hash, &repl_obj->original.oid)) { |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 19 | 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. carlson | 1731a1e | 2018-03-12 02:27:33 +0000 | [diff] [blame] | 25 | oidcpy(&repl_obj->replacement, oid); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 26 | |
| 27 | /* Register new object */ |
Stefan Beller | c127449 | 2018-04-11 17:21:07 -0700 | [diff] [blame] | 28 | if (oidmap_put(the_repository->objects->replace_map, repl_obj)) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 29 | die("duplicate replace ref: %s", refname); |
| 30 | |
| 31 | return 0; |
| 32 | } |
| 33 | |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 34 | static void prepare_replace_object(struct repository *r) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 35 | { |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 36 | if (r->objects->replace_map) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 37 | return; |
| 38 | |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 39 | r->objects->replace_map = |
Stefan Beller | 74fd070 | 2018-05-09 16:40:59 -0700 | [diff] [blame] | 40 | xmalloc(sizeof(*r->objects->replace_map)); |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 41 | oidmap_init(r->objects->replace_map, 0); |
Stefan Beller | c127449 | 2018-04-11 17:21:07 -0700 | [diff] [blame] | 42 | |
Stefan Beller | 5982da9 | 2018-04-11 17:21:16 -0700 | [diff] [blame] | 43 | for_each_replace_ref(r, register_replace_ref, NULL); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | /* We allow "recursive" replacement. Only within reason, though */ |
| 47 | #define MAXREPLACEDEPTH 5 |
| 48 | |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 49 | /* |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 50 | * If a replacement for object oid has been set up, return the |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 51 | * replacement object's name (replaced recursively, if necessary). |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 52 | * The return value is either oid or a pointer to a |
Michael Haggerty | 1f91e79 | 2014-02-28 17:29:16 +0100 | [diff] [blame] | 53 | * permanently-allocated value. This function always respects replace |
| 54 | * references, regardless of the value of check_replace_refs. |
| 55 | */ |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 56 | const struct object_id *do_lookup_replace_object(struct repository *r, |
| 57 | const struct object_id *oid) |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 58 | { |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 59 | int depth = MAXREPLACEDEPTH; |
brian m. carlson | b383a13 | 2018-03-12 02:27:54 +0000 | [diff] [blame] | 60 | const struct object_id *cur = oid; |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 61 | |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 62 | prepare_replace_object(r); |
Christian Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 63 | |
| 64 | /* Try to recursively replace the object */ |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 65 | while (depth-- > 0) { |
Stefan Beller | d88f9fd | 2018-04-11 17:21:05 -0700 | [diff] [blame] | 66 | struct replace_object *repl_obj = |
Stefan Beller | 5643557 | 2018-04-11 17:21:17 -0700 | [diff] [blame] | 67 | oidmap_get(r->objects->replace_map, cur); |
René Scharfe | f37b9bc | 2018-04-11 17:21:04 -0700 | [diff] [blame] | 68 | 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 Couder | 6809557 | 2009-01-23 10:06:53 +0100 | [diff] [blame] | 73 | } |