]> git.ipfire.org Git - thirdparty/git.git/blame - replace-object.c
Start the 2.46 cycle
[thirdparty/git.git] / replace-object.c
CommitLineData
4f6728d5 1#include "git-compat-util.h"
f394e093 2#include "gettext.h"
41771fa4 3#include "hex.h"
f37b9bc0 4#include "oidmap.h"
a034e910 5#include "object-store-ll.h"
d88f9fdf 6#include "replace-object.h"
68095570 7#include "refs.h"
d88f9fdf 8#include "repository.h"
c2e86add 9#include "commit.h"
68095570 10
212e0f7e
SB
11static int register_replace_ref(struct repository *r,
12 const char *refname,
00530834 13 const struct object_id *oid,
5cf88fd8
ÆAB
14 int flag UNUSED,
15 void *cb_data UNUSED)
68095570
CC
16{
17 /* Get sha1 from refname */
18 const char *slash = strrchr(refname, '/');
19 const char *hash = slash ? slash + 1 : refname;
20 struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
21
f37b9bc0 22 if (get_oid_hex(hash, &repl_obj->original.oid)) {
68095570 23 free(repl_obj);
b73c6e3a 24 warning(_("bad replace ref name: %s"), refname);
68095570
CC
25 return 0;
26 }
27
28 /* Copy sha1 from the read ref */
1731a1e2 29 oidcpy(&repl_obj->replacement, oid);
68095570
CC
30
31 /* Register new object */
212e0f7e 32 if (oidmap_put(r->objects->replace_map, repl_obj))
b73c6e3a 33 die(_("duplicate replace ref: %s"), refname);
68095570
CC
34
35 return 0;
36}
37
d6538246 38void prepare_replace_object(struct repository *r)
68095570 39{
b1fc9da1 40 if (r->objects->replace_map_initialized)
68095570
CC
41 return;
42
b1fc9da1
MT
43 pthread_mutex_lock(&r->objects->replace_mutex);
44 if (r->objects->replace_map_initialized) {
45 pthread_mutex_unlock(&r->objects->replace_mutex);
46 return;
47 }
48
5982da9d 49 r->objects->replace_map =
74fd0705 50 xmalloc(sizeof(*r->objects->replace_map));
5982da9d 51 oidmap_init(r->objects->replace_map, 0);
c1274495 52
5982da9d 53 for_each_replace_ref(r, register_replace_ref, NULL);
b1fc9da1
MT
54 r->objects->replace_map_initialized = 1;
55
56 pthread_mutex_unlock(&r->objects->replace_mutex);
68095570
CC
57}
58
59/* We allow "recursive" replacement. Only within reason, though */
60#define MAXREPLACEDEPTH 5
61
1f91e79c 62/*
b383a13c 63 * If a replacement for object oid has been set up, return the
1f91e79c 64 * replacement object's name (replaced recursively, if necessary).
b383a13c 65 * The return value is either oid or a pointer to a
1f91e79c 66 * permanently-allocated value. This function always respects replace
9c7d1b05 67 * references, regardless of the value of r->settings.read_replace_refs.
1f91e79c 68 */
5643557e
SB
69const struct object_id *do_lookup_replace_object(struct repository *r,
70 const struct object_id *oid)
68095570 71{
f37b9bc0 72 int depth = MAXREPLACEDEPTH;
b383a13c 73 const struct object_id *cur = oid;
68095570 74
5643557e 75 prepare_replace_object(r);
68095570
CC
76
77 /* Try to recursively replace the object */
f37b9bc0 78 while (depth-- > 0) {
d88f9fdf 79 struct replace_object *repl_obj =
5643557e 80 oidmap_get(r->objects->replace_map, cur);
f37b9bc0
RS
81 if (!repl_obj)
82 return cur;
83 cur = &repl_obj->replacement;
84 }
b73c6e3a 85 die(_("replace depth too high for object %s"), oid_to_hex(oid));
68095570 86}
d24eda4e 87
9c7d1b05
DS
88/*
89 * This indicator determines whether replace references should be
90 * respected process-wide, regardless of which repository is being
91 * using at the time.
92 */
93static int read_replace_refs = 1;
94
d24eda4e
DS
95void disable_replace_refs(void)
96{
97 read_replace_refs = 0;
98}
f1178380
DS
99
100int replace_refs_enabled(struct repository *r)
101{
9c7d1b05
DS
102 if (!read_replace_refs)
103 return 0;
104
105 if (r->gitdir) {
106 prepare_repo_settings(r);
107 return r->settings.read_replace_refs;
108 }
109
110 /* repository has no objects or refs. */
111 return 0;
f1178380 112}