From f37b9bc00ca3cb9a22c4d5da564eb271ba13c109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Wed, 11 Apr 2018 17:21:04 -0700 Subject: replace_object: use oidmap Load the replace objects into an oidmap to allow for easy lookups in constant time. Signed-off-by: Rene Scharfe Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace_object.c b/replace_object.c index 3363573..a757a5e 100644 --- a/replace_object.c +++ b/replace_object.c @@ -1,54 +1,14 @@ #include "cache.h" -#include "sha1-lookup.h" +#include "oidmap.h" #include "refs.h" #include "commit.h" -/* - * An array of replacements. The array is kept sorted by the original - * sha1. - */ -static struct replace_object { - struct object_id original; +struct replace_object { + struct oidmap_entry original; struct object_id replacement; -} **replace_object; - -static int replace_object_alloc, replace_object_nr; +}; -static const unsigned char *replace_sha1_access(size_t index, void *table) -{ - struct replace_object **replace = table; - return replace[index]->original.hash; -} - -static int replace_object_pos(const unsigned char *sha1) -{ - return sha1_pos(sha1, replace_object, replace_object_nr, - replace_sha1_access); -} - -static int register_replace_object(struct replace_object *replace, - int ignore_dups) -{ - int pos = replace_object_pos(replace->original.hash); - - if (0 <= pos) { - if (ignore_dups) - free(replace); - else { - free(replace_object[pos]); - replace_object[pos] = replace; - } - return 1; - } - pos = -pos - 1; - ALLOC_GROW(replace_object, replace_object_nr + 1, replace_object_alloc); - replace_object_nr++; - if (pos < replace_object_nr) - MOVE_ARRAY(replace_object + pos + 1, replace_object + pos, - replace_object_nr - pos - 1); - replace_object[pos] = replace; - return 0; -} +static struct oidmap replace_map = OIDMAP_INIT; static int register_replace_ref(const char *refname, const struct object_id *oid, @@ -59,7 +19,7 @@ static int register_replace_ref(const char *refname, const char *hash = slash ? slash + 1 : refname; struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj)); - if (get_oid_hex(hash, &repl_obj->original)) { + if (get_oid_hex(hash, &repl_obj->original.oid)) { free(repl_obj); warning("bad replace ref name: %s", refname); return 0; @@ -69,7 +29,7 @@ static int register_replace_ref(const char *refname, oidcpy(&repl_obj->replacement, oid); /* Register new object */ - if (register_replace_object(repl_obj, 1)) + if (oidmap_put(&replace_map, repl_obj)) die("duplicate replace ref: %s", refname); return 0; @@ -84,7 +44,7 @@ static void prepare_replace_object(void) for_each_replace_ref(register_replace_ref, NULL); replace_object_prepared = 1; - if (!replace_object_nr) + if (!replace_map.map.tablesize) check_replace_refs = 0; } @@ -100,21 +60,17 @@ static void prepare_replace_object(void) */ const struct object_id *do_lookup_replace_object(const struct object_id *oid) { - int pos, depth = MAXREPLACEDEPTH; + int depth = MAXREPLACEDEPTH; const struct object_id *cur = oid; prepare_replace_object(); /* Try to recursively replace the object */ - do { - if (--depth < 0) - die("replace depth too high for object %s", - oid_to_hex(oid)); - - pos = replace_object_pos(cur->hash); - if (0 <= pos) - cur = &replace_object[pos]->replacement; - } while (0 <= pos); - - return cur; + while (depth-- > 0) { + struct replace_object *repl_obj = oidmap_get(&replace_map, cur); + if (!repl_obj) + return cur; + cur = &repl_obj->replacement; + } + die("replace depth too high for object %s", oid_to_hex(oid)); } -- cgit v0.10.2-6-g49f6 From d88f9fdf8b2ccf65993bb977094ab9b2249635ee Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:05 -0700 Subject: replace-object: move replace_map to object store The relationship between an object X and another object Y that replaces the object X is defined only within the scope of a single repository. The exception in reachability rule around these replacement objects is also local to a repository (i.e. if traversal from refs reaches X, then both X and Y are reachable and need to be kept from gc). Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/object-store.h b/object-store.h index fef33f3..c04b4c9 100644 --- a/object-store.h +++ b/object-store.h @@ -1,6 +1,8 @@ #ifndef OBJECT_STORE_H #define OBJECT_STORE_H +#include "oidmap.h" + struct alternate_object_database { struct alternate_object_database *next; @@ -94,6 +96,12 @@ struct raw_object_store { struct alternate_object_database **alt_odb_tail; /* + * Objects that should be substituted by other objects + * (see git-replace(1)). + */ + struct oidmap replace_map; + + /* * private data * * should only be accessed directly by packfile.c diff --git a/replace-object.h b/replace-object.h new file mode 100644 index 0000000..f9a2b70 --- /dev/null +++ b/replace-object.h @@ -0,0 +1,9 @@ +#ifndef REPLACE_OBJECT_H +#define REPLACE_OBJECT_H + +struct replace_object { + struct oidmap_entry original; + struct object_id replacement; +}; + +#endif /* REPLACE_OBJECT_H */ diff --git a/replace_object.c b/replace_object.c index a757a5e..afbdf2d 100644 --- a/replace_object.c +++ b/replace_object.c @@ -1,15 +1,11 @@ #include "cache.h" #include "oidmap.h" +#include "object-store.h" +#include "replace-object.h" #include "refs.h" +#include "repository.h" #include "commit.h" -struct replace_object { - struct oidmap_entry original; - struct object_id replacement; -}; - -static struct oidmap replace_map = OIDMAP_INIT; - static int register_replace_ref(const char *refname, const struct object_id *oid, int flag, void *cb_data) @@ -29,7 +25,7 @@ static int register_replace_ref(const char *refname, oidcpy(&repl_obj->replacement, oid); /* Register new object */ - if (oidmap_put(&replace_map, repl_obj)) + if (oidmap_put(&the_repository->objects->replace_map, repl_obj)) die("duplicate replace ref: %s", refname); return 0; @@ -44,7 +40,7 @@ static void prepare_replace_object(void) for_each_replace_ref(register_replace_ref, NULL); replace_object_prepared = 1; - if (!replace_map.map.tablesize) + if (!the_repository->objects->replace_map.map.tablesize) check_replace_refs = 0; } @@ -67,7 +63,8 @@ const struct object_id *do_lookup_replace_object(const struct object_id *oid) /* Try to recursively replace the object */ while (depth-- > 0) { - struct replace_object *repl_obj = oidmap_get(&replace_map, cur); + struct replace_object *repl_obj = + oidmap_get(&the_repository->objects->replace_map, cur); if (!repl_obj) return cur; cur = &repl_obj->replacement; -- cgit v0.10.2-6-g49f6 From 47f351e9b328cd828d85c45a736eca252152aa5c Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:06 -0700 Subject: object-store: move lookup_replace_object to replace-object.h lookup_replace_object is a low-level function that most users of the object store do not need to use directly. Move it to replace-object.h to avoid a dependency loop in an upcoming change to its inline definition that will make use of repository.h. Signed-off-by: Stefan Beller Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano diff --git a/builtin/mktag.c b/builtin/mktag.c index 9f5a50a..e3d20a7 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "tag.h" +#include "replace-object.h" /* * A signature file has a very simple fixed format: four lines diff --git a/cache.h b/cache.h index bbaf5c3..027bd7f 100644 --- a/cache.h +++ b/cache.h @@ -1191,25 +1191,6 @@ static inline void *read_object_file(const struct object_id *oid, enum object_ty return read_object_file_extended(oid, type, size, 1); } -/* - * This internal function is only declared here for the benefit of - * lookup_replace_object(). Please do not call it directly. - */ -extern const struct object_id *do_lookup_replace_object(const struct object_id *oid); - -/* - * If object sha1 should be replaced, return the replacement object's - * name (replaced recursively, if necessary). The return value is - * either sha1 or a pointer to a permanently-allocated value. When - * object replacement is suppressed, always return sha1. - */ -static inline const struct object_id *lookup_replace_object(const struct object_id *oid) -{ - if (!check_replace_refs) - return oid; - return do_lookup_replace_object(oid); -} - /* Read and unpack an object file into memory, write memory to an object file */ extern int oid_object_info(const struct object_id *, unsigned long *); diff --git a/object.c b/object.c index a0a756f..998ec2a 100644 --- a/object.c +++ b/object.c @@ -1,5 +1,6 @@ #include "cache.h" #include "object.h" +#include "replace-object.h" #include "blob.h" #include "tree.h" #include "commit.h" diff --git a/replace-object.h b/replace-object.h index f9a2b70..1531531 100644 --- a/replace-object.h +++ b/replace-object.h @@ -1,9 +1,31 @@ #ifndef REPLACE_OBJECT_H #define REPLACE_OBJECT_H +#include "oidmap.h" +#include "repository.h" + struct replace_object { struct oidmap_entry original; struct object_id replacement; }; +/* + * This internal function is only declared here for the benefit of + * lookup_replace_object(). Please do not call it directly. + */ +extern const struct object_id *do_lookup_replace_object(const struct object_id *oid); + +/* + * If object sha1 should be replaced, return the replacement object's + * name (replaced recursively, if necessary). The return value is + * either sha1 or a pointer to a permanently-allocated value. When + * object replacement is suppressed, always return sha1. + */ +static inline const struct object_id *lookup_replace_object(const struct object_id *oid) +{ + if (!check_replace_refs) + return oid; + return do_lookup_replace_object(oid); +} + #endif /* REPLACE_OBJECT_H */ diff --git a/sha1_file.c b/sha1_file.c index 77ccaab..67698fc 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -23,6 +23,7 @@ #include "sha1-lookup.h" #include "bulk-checkin.h" #include "repository.h" +#include "replace-object.h" #include "streaming.h" #include "dir.h" #include "list.h" diff --git a/streaming.c b/streaming.c index 7d55ba6..a6e1162 100644 --- a/streaming.c +++ b/streaming.c @@ -5,6 +5,7 @@ #include "streaming.h" #include "repository.h" #include "object-store.h" +#include "replace-object.h" #include "packfile.h" enum input_source { -- cgit v0.10.2-6-g49f6 From c1274495ce74cb71c8c6e9e16490d6c4d2d1fe22 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:07 -0700 Subject: replace-object: eliminate replace objects prepared flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the oidmap a pointer. That way we eliminate the need for the global boolean variable 'replace_object_prepared' as we can put this information into the pointer being NULL or not. Another advantage of this is that we would more quickly catch code that tries to access replace-map without initializing it. This also allows the '#include "oidmap.h"' introduced in a previous patch to be replaced by the forward declaration of 'struct oidmap;'. Keeping the type opaque discourages circumventing accessor functions; not dragging in other headers avoids some compile time overhead. One disadvantage of this is change is performance as we need to pay the overhead for a malloc. The alternative of moving the global variable into the object store is less modular code. Helped-by: René Scharfe Helped-by: Junio C Hamano Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/object-store.h b/object-store.h index c04b4c9..1ff862c 100644 --- a/object-store.h +++ b/object-store.h @@ -99,7 +99,7 @@ struct raw_object_store { * Objects that should be substituted by other objects * (see git-replace(1)). */ - struct oidmap replace_map; + struct oidmap *replace_map; /* * private data diff --git a/replace_object.c b/replace_object.c index afbdf2d..953fa9c 100644 --- a/replace_object.c +++ b/replace_object.c @@ -25,7 +25,7 @@ static int register_replace_ref(const char *refname, oidcpy(&repl_obj->replacement, oid); /* Register new object */ - if (oidmap_put(&the_repository->objects->replace_map, repl_obj)) + if (oidmap_put(the_repository->objects->replace_map, repl_obj)) die("duplicate replace ref: %s", refname); return 0; @@ -33,14 +33,16 @@ static int register_replace_ref(const char *refname, static void prepare_replace_object(void) { - static int replace_object_prepared; - - if (replace_object_prepared) + if (the_repository->objects->replace_map) return; + the_repository->objects->replace_map = + xmalloc(sizeof(*the_repository->objects->replace_map)); + oidmap_init(the_repository->objects->replace_map, 0); + for_each_replace_ref(register_replace_ref, NULL); - replace_object_prepared = 1; - if (!the_repository->objects->replace_map.map.tablesize) + + if (!the_repository->objects->replace_map->map.tablesize) check_replace_refs = 0; } @@ -64,7 +66,7 @@ const struct object_id *do_lookup_replace_object(const struct object_id *oid) /* Try to recursively replace the object */ while (depth-- > 0) { struct replace_object *repl_obj = - oidmap_get(&the_repository->objects->replace_map, cur); + oidmap_get(the_repository->objects->replace_map, cur); if (!repl_obj) return cur; cur = &repl_obj->replacement; -- cgit v0.10.2-6-g49f6 From c3c36d7de2cf09fb05701ed672b26c51a008f5cd Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:08 -0700 Subject: replace-object: check_replace_refs is safe in multi repo environment In e1111cef23 (inline lookup_replace_object() calls, 2011-05-15) a shortcut for checking the object replacement was added by setting check_replace_refs to 0 once the replacements were evaluated to not exist. This works fine in with the assumption of only one repository in existence. The assumption won't hold true any more when we work on multiple instances of a repository structs (e.g. one struct per submodule), as the first repository to be inspected may have no replacements and would set the global variable. Other repositories would then completely omit their evaluation of replacements. This reverts back the meaning of the flag `check_replace_refs` of "Do we need to check with the lookup table?" to "Do we need to read the replacement definition?", adding the bypassing logic to lookup_replace_object after the replacement definition was read. As with the original patch, delay the renaming of the global variable Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/environment.c b/environment.c index 39b3d90..b991fc0 100644 --- a/environment.c +++ b/environment.c @@ -50,7 +50,7 @@ const char *editor_program; const char *askpass_program; const char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; -int check_replace_refs = 1; +int check_replace_refs = 1; /* NEEDSWORK: rename to read_replace_refs */ char *git_replace_ref_base; enum eol core_eol = EOL_UNSET; int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; diff --git a/replace-object.h b/replace-object.h index 1531531..dbc5126 100644 --- a/replace-object.h +++ b/replace-object.h @@ -3,6 +3,7 @@ #include "oidmap.h" #include "repository.h" +#include "object-store.h" struct replace_object { struct oidmap_entry original; @@ -23,7 +24,9 @@ extern const struct object_id *do_lookup_replace_object(const struct object_id * */ static inline const struct object_id *lookup_replace_object(const struct object_id *oid) { - if (!check_replace_refs) + if (!check_replace_refs || + (the_repository->objects->replace_map && + the_repository->objects->replace_map->map.tablesize == 0)) return oid; return do_lookup_replace_object(oid); } diff --git a/replace_object.c b/replace_object.c index 953fa9c..b2405f6 100644 --- a/replace_object.c +++ b/replace_object.c @@ -41,9 +41,6 @@ static void prepare_replace_object(void) oidmap_init(the_repository->objects->replace_map, 0); for_each_replace_ref(register_replace_ref, NULL); - - if (!the_repository->objects->replace_map->map.tablesize) - check_replace_refs = 0; } /* We allow "recursive" replacement. Only within reason, though */ -- cgit v0.10.2-6-g49f6 From 23a3f0cb16caa1cc79cf0af42a92bff61fe955a4 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:09 -0700 Subject: refs: add repository argument to get_main_ref_store Add a repository argument to allow the get_main_ref_store caller to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index b106a39..f335356 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,6 +1,7 @@ #include "builtin.h" #include "parse-options.h" #include "refs.h" +#include "repository.h" static char const * const pack_refs_usage[] = { N_("git pack-refs []"), @@ -17,5 +18,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix) }; if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0)) usage_with_options(pack_refs_usage, opts); - return refs_pack_refs(get_main_ref_store(), flags); + return refs_pack_refs(get_main_ref_store(the_repository), flags); } diff --git a/refs.c b/refs.c index 8b7a77f..74d4ed9 100644 --- a/refs.c +++ b/refs.c @@ -13,6 +13,7 @@ #include "tag.h" #include "submodule.h" #include "worktree.h" +#include "repository.h" /* * List of all available backends @@ -206,7 +207,7 @@ char *refs_resolve_refdup(struct ref_store *refs, char *resolve_refdup(const char *refname, int resolve_flags, struct object_id *oid, int *flags) { - return refs_resolve_refdup(get_main_ref_store(), + return refs_resolve_refdup(get_main_ref_store(the_repository), refname, resolve_flags, oid, flags); } @@ -228,7 +229,7 @@ int refs_read_ref_full(struct ref_store *refs, const char *refname, int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags) { - return refs_read_ref_full(get_main_ref_store(), refname, + return refs_read_ref_full(get_main_ref_store(the_repository), refname, resolve_flags, oid, flags); } @@ -375,7 +376,7 @@ int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) int for_each_tag_ref(each_ref_fn fn, void *cb_data) { - return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data); + return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data); } int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) @@ -385,7 +386,7 @@ int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da int for_each_branch_ref(each_ref_fn fn, void *cb_data) { - return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data); + return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data); } int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) @@ -395,7 +396,7 @@ int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da int for_each_remote_ref(each_ref_fn fn, void *cb_data) { - return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data); + return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data); } int head_ref_namespaced(each_ref_fn fn, void *cb_data) @@ -730,7 +731,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg, struct strbuf err = STRBUF_INIT; if (ref_type(refname) == REF_TYPE_PSEUDOREF) { - assert(refs == get_main_ref_store()); + assert(refs == get_main_ref_store(the_repository)); return delete_pseudoref(refname, old_oid); } @@ -752,7 +753,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg, int delete_ref(const char *msg, const char *refname, const struct object_id *old_oid, unsigned int flags) { - return refs_delete_ref(get_main_ref_store(), msg, refname, + return refs_delete_ref(get_main_ref_store(the_repository), msg, refname, old_oid, flags); } @@ -928,7 +929,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, struct ref_transaction *ref_transaction_begin(struct strbuf *err) { - return ref_store_transaction_begin(get_main_ref_store(), err); + return ref_store_transaction_begin(get_main_ref_store(the_repository), err); } void ref_transaction_free(struct ref_transaction *transaction) @@ -1060,7 +1061,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg, int ret = 0; if (ref_type(refname) == REF_TYPE_PSEUDOREF) { - assert(refs == get_main_ref_store()); + assert(refs == get_main_ref_store(the_repository)); ret = write_pseudoref(refname, new_oid, old_oid, &err); } else { t = ref_store_transaction_begin(refs, &err); @@ -1099,7 +1100,7 @@ int update_ref(const char *msg, const char *refname, const struct object_id *old_oid, unsigned int flags, enum action_on_err onerr) { - return refs_update_ref(get_main_ref_store(), msg, refname, new_oid, + return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid, old_oid, flags, onerr); } @@ -1320,7 +1321,7 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) int head_ref(each_ref_fn fn, void *cb_data) { - return refs_head_ref(get_main_ref_store(), fn, cb_data); + return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data); } struct ref_iterator *refs_ref_iterator_begin( @@ -1379,7 +1380,7 @@ int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) int for_each_ref(each_ref_fn fn, void *cb_data) { - return refs_for_each_ref(get_main_ref_store(), fn, cb_data); + return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data); } int refs_for_each_ref_in(struct ref_store *refs, const char *prefix, @@ -1390,7 +1391,7 @@ int refs_for_each_ref_in(struct ref_store *refs, const char *prefix, int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) { - return refs_for_each_ref_in(get_main_ref_store(), prefix, fn, cb_data); + return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data); } int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken) @@ -1399,7 +1400,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsig if (broken) flag = DO_FOR_EACH_INCLUDE_BROKEN; - return do_for_each_ref(get_main_ref_store(), + return do_for_each_ref(get_main_ref_store(the_repository), prefix, fn, 0, flag, cb_data); } @@ -1416,7 +1417,7 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, int for_each_replace_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref(get_main_ref_store(), + return do_for_each_ref(get_main_ref_store(the_repository), git_replace_ref_base, fn, strlen(git_replace_ref_base), DO_FOR_EACH_INCLUDE_BROKEN, cb_data); @@ -1427,7 +1428,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) struct strbuf buf = STRBUF_INIT; int ret; strbuf_addf(&buf, "%srefs/", get_git_namespace()); - ret = do_for_each_ref(get_main_ref_store(), + ret = do_for_each_ref(get_main_ref_store(the_repository), buf.buf, fn, 0, 0, cb_data); strbuf_release(&buf); return ret; @@ -1441,7 +1442,7 @@ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data) int for_each_rawref(each_ref_fn fn, void *cb_data) { - return refs_for_each_rawref(get_main_ref_store(), fn, cb_data); + return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data); } int refs_read_raw_ref(struct ref_store *ref_store, @@ -1547,7 +1548,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, /* backend functions */ int refs_init_db(struct strbuf *err) { - struct ref_store *refs = get_main_ref_store(); + struct ref_store *refs = get_main_ref_store(the_repository); return refs->be->init_db(refs, err); } @@ -1555,7 +1556,7 @@ int refs_init_db(struct strbuf *err) const char *resolve_ref_unsafe(const char *refname, int resolve_flags, struct object_id *oid, int *flags) { - return refs_resolve_ref_unsafe(get_main_ref_store(), refname, + return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname, resolve_flags, oid, flags); } @@ -1651,7 +1652,7 @@ static struct ref_store *ref_store_init(const char *gitdir, return refs; } -struct ref_store *get_main_ref_store(void) +struct ref_store *get_main_ref_store_the_repository(void) { if (main_ref_store) return main_ref_store; @@ -1726,7 +1727,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt) const char *id; if (wt->is_current) - return get_main_ref_store(); + return get_main_ref_store(the_repository); id = wt->id ? wt->id : "/"; refs = lookup_ref_store_map(&worktree_ref_stores, id); @@ -1782,7 +1783,7 @@ int refs_peel_ref(struct ref_store *refs, const char *refname, int peel_ref(const char *refname, struct object_id *oid) { - return refs_peel_ref(get_main_ref_store(), refname, oid); + return refs_peel_ref(get_main_ref_store(the_repository), refname, oid); } int refs_create_symref(struct ref_store *refs, @@ -1798,7 +1799,7 @@ int refs_create_symref(struct ref_store *refs, int create_symref(const char *ref_target, const char *refs_heads_master, const char *logmsg) { - return refs_create_symref(get_main_ref_store(), ref_target, + return refs_create_symref(get_main_ref_store(the_repository), ref_target, refs_heads_master, logmsg); } @@ -2006,7 +2007,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data) int for_each_reflog(each_ref_fn fn, void *cb_data) { - return refs_for_each_reflog(get_main_ref_store(), fn, cb_data); + return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data); } int refs_for_each_reflog_ent_reverse(struct ref_store *refs, @@ -2021,7 +2022,7 @@ int refs_for_each_reflog_ent_reverse(struct ref_store *refs, int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data) { - return refs_for_each_reflog_ent_reverse(get_main_ref_store(), + return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository), refname, fn, cb_data); } @@ -2034,7 +2035,7 @@ int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname, int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data) { - return refs_for_each_reflog_ent(get_main_ref_store(), refname, + return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname, fn, cb_data); } @@ -2045,7 +2046,7 @@ int refs_reflog_exists(struct ref_store *refs, const char *refname) int reflog_exists(const char *refname) { - return refs_reflog_exists(get_main_ref_store(), refname); + return refs_reflog_exists(get_main_ref_store(the_repository), refname); } int refs_create_reflog(struct ref_store *refs, const char *refname, @@ -2057,7 +2058,7 @@ int refs_create_reflog(struct ref_store *refs, const char *refname, int safe_create_reflog(const char *refname, int force_create, struct strbuf *err) { - return refs_create_reflog(get_main_ref_store(), refname, + return refs_create_reflog(get_main_ref_store(the_repository), refname, force_create, err); } @@ -2068,7 +2069,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname) int delete_reflog(const char *refname) { - return refs_delete_reflog(get_main_ref_store(), refname); + return refs_delete_reflog(get_main_ref_store(the_repository), refname); } int refs_reflog_expire(struct ref_store *refs, @@ -2091,7 +2092,7 @@ int reflog_expire(const char *refname, const struct object_id *oid, reflog_expiry_cleanup_fn cleanup_fn, void *policy_cb_data) { - return refs_reflog_expire(get_main_ref_store(), + return refs_reflog_expire(get_main_ref_store(the_repository), refname, oid, flags, prepare_fn, should_prune_fn, cleanup_fn, policy_cb_data); @@ -2114,7 +2115,7 @@ int refs_delete_refs(struct ref_store *refs, const char *msg, int delete_refs(const char *msg, struct string_list *refnames, unsigned int flags) { - return refs_delete_refs(get_main_ref_store(), msg, refnames, flags); + return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags); } int refs_rename_ref(struct ref_store *refs, const char *oldref, @@ -2125,7 +2126,7 @@ int refs_rename_ref(struct ref_store *refs, const char *oldref, int rename_ref(const char *oldref, const char *newref, const char *logmsg) { - return refs_rename_ref(get_main_ref_store(), oldref, newref, logmsg); + return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg); } int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, @@ -2136,5 +2137,5 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg) { - return refs_copy_existing_ref(get_main_ref_store(), oldref, newref, logmsg); + return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg); } diff --git a/refs.h b/refs.h index 01be5ae..0d01337 100644 --- a/refs.h +++ b/refs.h @@ -758,7 +758,9 @@ int reflog_expire(const char *refname, const struct object_id *oid, int ref_storage_backend_exists(const char *name); -struct ref_store *get_main_ref_store(void); +#define get_main_ref_store(r) \ + get_main_ref_store_##r() +struct ref_store *get_main_ref_store_the_repository(void); /* * Return the ref_store instance for the specified submodule. For the * main repository, use submodule==NULL; such a call cannot fail. For diff --git a/revision.c b/revision.c index b42c836..1cff118 100644 --- a/revision.c +++ b/revision.c @@ -6,6 +6,7 @@ #include "diff.h" #include "refs.h" #include "revision.h" +#include "repository.h" #include "graph.h" #include "grep.h" #include "reflog-walk.h" @@ -1285,7 +1286,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags) cb.all_revs = revs; cb.all_flags = flags; - cb.refs = get_main_ref_store(); + cb.refs = get_main_ref_store(the_repository); for_each_reflog(handle_one_reflog, &cb); if (!revs->single_worktree) @@ -2176,7 +2177,7 @@ static int handle_revision_pseudo_opt(const char *submodule, die("BUG: --single-worktree cannot be used together with submodule"); refs = get_submodule_ref_store(submodule); } else - refs = get_main_ref_store(); + refs = get_main_ref_store(the_repository); /* * NOTE! diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 7c4f437..e9e0541 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -3,6 +3,7 @@ #include "refs.h" #include "worktree.h" #include "object-store.h" +#include "repository.h" static const char *notnull(const char *arg, const char *name) { @@ -23,7 +24,7 @@ static const char **get_store(const char **argv, struct ref_store **refs) if (!argv[0]) { die("ref store required"); } else if (!strcmp(argv[0], "main")) { - *refs = get_main_ref_store(); + *refs = get_main_ref_store(the_repository); } else if (skip_prefix(argv[0], "submodule:", &gitdir)) { struct strbuf sb = STRBUF_INIT; int ret; -- cgit v0.10.2-6-g49f6 From 60ce76d35819a9679104b6615aa0466ae49023a0 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:10 -0700 Subject: refs: add repository argument to for_each_replace_ref Add a repository argument to allow for_each_replace_ref callers to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/builtin/replace.c b/builtin/replace.c index 935647b..237ea65 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -14,6 +14,8 @@ #include "refs.h" #include "parse-options.h" #include "run-command.h" +#include "object-store.h" +#include "repository.h" #include "tag.h" static const char * const git_replace_usage[] = { @@ -83,7 +85,7 @@ static int list_replace_refs(const char *pattern, const char *format) "valid formats are 'short', 'medium' and 'long'\n", format); - for_each_replace_ref(show_reference, (void *)&data); + for_each_replace_ref(the_repository, show_reference, (void *)&data); return 0; } diff --git a/refs.c b/refs.c index 74d4ed9..f58b9fb 100644 --- a/refs.c +++ b/refs.c @@ -1415,7 +1415,7 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data); } -int for_each_replace_ref(each_ref_fn fn, void *cb_data) +int for_each_replace_ref_the_repository(each_ref_fn fn, void *cb_data) { return do_for_each_ref(get_main_ref_store(the_repository), git_replace_ref_base, fn, diff --git a/refs.h b/refs.h index 0d01337..ab3d2be 100644 --- a/refs.h +++ b/refs.h @@ -300,7 +300,9 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, int for_each_tag_ref(each_ref_fn fn, void *cb_data); int for_each_branch_ref(each_ref_fn fn, void *cb_data); int for_each_remote_ref(each_ref_fn fn, void *cb_data); -int for_each_replace_ref(each_ref_fn fn, void *cb_data); +#define for_each_replace_ref(r, fn, cb) \ + for_each_replace_ref_##r(fn, cb) +int for_each_replace_ref_the_repository(each_ref_fn fn, void *cb_data); int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data); diff --git a/replace_object.c b/replace_object.c index b2405f6..16a95ea 100644 --- a/replace_object.c +++ b/replace_object.c @@ -40,7 +40,7 @@ static void prepare_replace_object(void) xmalloc(sizeof(*the_repository->objects->replace_map)); oidmap_init(the_repository->objects->replace_map, 0); - for_each_replace_ref(register_replace_ref, NULL); + for_each_replace_ref(the_repository, register_replace_ref, NULL); } /* We allow "recursive" replacement. Only within reason, though */ -- cgit v0.10.2-6-g49f6 From fe6d34d863a351034cbc7c756465f84dc64007ad Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:11 -0700 Subject: replace-object: add repository argument to prepare_replace_object Add a repository argument to allow the prepare_replace_object caller to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace_object.c b/replace_object.c index 16a95ea..567d9da 100644 --- a/replace_object.c +++ b/replace_object.c @@ -31,7 +31,9 @@ static int register_replace_ref(const char *refname, return 0; } -static void prepare_replace_object(void) +#define prepare_replace_object(r) \ + prepare_replace_object_##r() +static void prepare_replace_object_the_repository(void) { if (the_repository->objects->replace_map) return; @@ -58,7 +60,7 @@ const struct object_id *do_lookup_replace_object(const struct object_id *oid) int depth = MAXREPLACEDEPTH; const struct object_id *cur = oid; - prepare_replace_object(); + prepare_replace_object(the_repository); /* Try to recursively replace the object */ while (depth-- > 0) { -- cgit v0.10.2-6-g49f6 From 9dfe98a8b3fba6df799686a276a39db39761863f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:12 -0700 Subject: replace-object: add repository argument to do_lookup_replace_object Add a repository argument to allow the do_lookup_replace_object caller to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace-object.h b/replace-object.h index dbc5126..ddeb047 100644 --- a/replace-object.h +++ b/replace-object.h @@ -14,7 +14,8 @@ struct replace_object { * This internal function is only declared here for the benefit of * lookup_replace_object(). Please do not call it directly. */ -extern const struct object_id *do_lookup_replace_object(const struct object_id *oid); +#define do_lookup_replace_object(r, s) do_lookup_replace_object_##r(s) +extern const struct object_id *do_lookup_replace_object_the_repository(const struct object_id *oid); /* * If object sha1 should be replaced, return the replacement object's @@ -28,7 +29,7 @@ static inline const struct object_id *lookup_replace_object(const struct object_ (the_repository->objects->replace_map && the_repository->objects->replace_map->map.tablesize == 0)) return oid; - return do_lookup_replace_object(oid); + return do_lookup_replace_object(the_repository, oid); } #endif /* REPLACE_OBJECT_H */ diff --git a/replace_object.c b/replace_object.c index 567d9da..adfed78 100644 --- a/replace_object.c +++ b/replace_object.c @@ -55,7 +55,7 @@ static void prepare_replace_object_the_repository(void) * permanently-allocated value. This function always respects replace * references, regardless of the value of check_replace_refs. */ -const struct object_id *do_lookup_replace_object(const struct object_id *oid) +const struct object_id *do_lookup_replace_object_the_repository(const struct object_id *oid) { int depth = MAXREPLACEDEPTH; const struct object_id *cur = oid; -- cgit v0.10.2-6-g49f6 From 1f2e7ceabcc1559e5b3e49df91036d3106f727f4 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:13 -0700 Subject: replace-object: add repository argument to lookup_replace_object Add a repository argument to allow callers of lookup_replace_object to be more specific about which repository to handle. This is a small mechanical change; it doesn't change the implementation to handle repositories other than the_repository yet. As with the previous commits, use a macro to catch callers passing a repository other than the_repository at compile time. Signed-off-by: Jonathan Nieder Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/builtin/mktag.c b/builtin/mktag.c index e3d20a7..82a6e86 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -25,7 +25,7 @@ static int verify_object(const struct object_id *oid, const char *expected_type) enum object_type type; unsigned long size; void *buffer = read_object_file(oid, &type, &size); - const struct object_id *repl = lookup_replace_object(oid); + const struct object_id *repl = lookup_replace_object(the_repository, oid); if (buffer) { if (type == type_from_string(expected_type)) diff --git a/object.c b/object.c index 998ec2a..66cffaf 100644 --- a/object.c +++ b/object.c @@ -247,7 +247,7 @@ struct object *parse_object(const struct object_id *oid) unsigned long size; enum object_type type; int eaten; - const struct object_id *repl = lookup_replace_object(oid); + const struct object_id *repl = lookup_replace_object(the_repository, oid); void *buffer; struct object *obj; diff --git a/replace-object.h b/replace-object.h index ddeb047..dff57bf 100644 --- a/replace-object.h +++ b/replace-object.h @@ -23,7 +23,8 @@ extern const struct object_id *do_lookup_replace_object_the_repository(const str * either sha1 or a pointer to a permanently-allocated value. When * object replacement is suppressed, always return sha1. */ -static inline const struct object_id *lookup_replace_object(const struct object_id *oid) +#define lookup_replace_object(r, s) lookup_replace_object_##r(s) +static inline const struct object_id *lookup_replace_object_the_repository(const struct object_id *oid) { if (!check_replace_refs || (the_repository->objects->replace_map && diff --git a/sha1_file.c b/sha1_file.c index 67698fc..64a5bd7 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1240,7 +1240,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi int already_retried = 0; if (flags & OBJECT_INFO_LOOKUP_REPLACE) - real = lookup_replace_object(oid); + real = lookup_replace_object(the_repository, oid); if (is_null_oid(real)) return -1; @@ -1384,8 +1384,8 @@ void *read_object_file_extended(const struct object_id *oid, const struct packed_git *p; const char *path; struct stat st; - const struct object_id *repl = lookup_replace ? lookup_replace_object(oid) - : oid; + const struct object_id *repl = lookup_replace ? + lookup_replace_object(the_repository, oid) : oid; errno = 0; data = read_object(repl->hash, type, size); diff --git a/streaming.c b/streaming.c index a6e1162..cce7b17 100644 --- a/streaming.c +++ b/streaming.c @@ -140,7 +140,7 @@ struct git_istream *open_istream(const struct object_id *oid, { struct git_istream *st; struct object_info oi = OBJECT_INFO_INIT; - const struct object_id *real = lookup_replace_object(oid); + const struct object_id *real = lookup_replace_object(the_repository, oid); enum input_source src = istream_source(real, type, &oi); if (src < 0) -- cgit v0.10.2-6-g49f6 From 64a741619d27ede27788d2d444257635f4af8ffd Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:14 -0700 Subject: refs: store the main ref store inside the repository struct This moves the 'main_ref_store', which was a global variable in refs.c into the repository struct. This patch does not deal with the parts in the refs subsystem which deal with the submodules there. A later patch needs to get rid of the submodule exposure in the refs API, such as 'get_submodule_ref_store(path)'. Acked-by: Michael Haggerty Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/refs.c b/refs.c index f58b9fb..36df1bc 100644 --- a/refs.c +++ b/refs.c @@ -1608,9 +1608,6 @@ static struct ref_store_hash_entry *alloc_ref_store_hash_entry( return entry; } -/* A pointer to the ref_store for the main repository: */ -static struct ref_store *main_ref_store; - /* A hashmap of ref_stores, stored by submodule name: */ static struct hashmap submodule_ref_stores; @@ -1652,13 +1649,13 @@ static struct ref_store *ref_store_init(const char *gitdir, return refs; } -struct ref_store *get_main_ref_store_the_repository(void) +struct ref_store *get_main_ref_store(struct repository *r) { - if (main_ref_store) - return main_ref_store; + if (r->refs) + return r->refs; - main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS); - return main_ref_store; + r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS); + return r->refs; } /* diff --git a/refs.h b/refs.h index ab3d2be..f5ab68c 100644 --- a/refs.h +++ b/refs.h @@ -760,9 +760,7 @@ int reflog_expire(const char *refname, const struct object_id *oid, int ref_storage_backend_exists(const char *name); -#define get_main_ref_store(r) \ - get_main_ref_store_##r() -struct ref_store *get_main_ref_store_the_repository(void); +struct ref_store *get_main_ref_store(struct repository *r); /* * Return the ref_store instance for the specified submodule. For the * main repository, use submodule==NULL; such a call cannot fail. For diff --git a/refs/files-backend.c b/refs/files-backend.c index bec8e30..5c76a75 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -61,10 +61,6 @@ struct ref_lock { struct object_id old_oid; }; -/* - * Future: need to be in "struct repository" - * when doing a full libification. - */ struct files_ref_store { struct ref_store base; unsigned int store_flags; diff --git a/repository.h b/repository.h index 09df94a..e6e00f5 100644 --- a/repository.h +++ b/repository.h @@ -26,6 +26,9 @@ struct repository { */ struct raw_object_store *objects; + /* The store in which the refs are held. */ + struct ref_store *refs; + /* * Path to the repository's graft file. * Cannot be NULL after initialization. -- cgit v0.10.2-6-g49f6 From 0d296c57aec3a2c311abc5ebe7d1499bc41bc9df Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:15 -0700 Subject: refs: allow for_each_replace_ref to handle arbitrary repositories Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/refs.c b/refs.c index 36df1bc..9b56fa9 100644 --- a/refs.c +++ b/refs.c @@ -1415,9 +1415,9 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data); } -int for_each_replace_ref_the_repository(each_ref_fn fn, void *cb_data) +int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data) { - return do_for_each_ref(get_main_ref_store(the_repository), + return do_for_each_ref(get_main_ref_store(r), git_replace_ref_base, fn, strlen(git_replace_ref_base), DO_FOR_EACH_INCLUDE_BROKEN, cb_data); diff --git a/refs.h b/refs.h index f5ab68c..15f3a91 100644 --- a/refs.h +++ b/refs.h @@ -300,9 +300,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, int for_each_tag_ref(each_ref_fn fn, void *cb_data); int for_each_branch_ref(each_ref_fn fn, void *cb_data); int for_each_remote_ref(each_ref_fn fn, void *cb_data); -#define for_each_replace_ref(r, fn, cb) \ - for_each_replace_ref_##r(fn, cb) -int for_each_replace_ref_the_repository(each_ref_fn fn, void *cb_data); +int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data); int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data); -- cgit v0.10.2-6-g49f6 From 5982da9d2ce75d445cb2a74351c34efa07342ea2 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:16 -0700 Subject: replace-object: allow prepare_replace_object to handle arbitrary repositories Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace_object.c b/replace_object.c index adfed78..eae52c6 100644 --- a/replace_object.c +++ b/replace_object.c @@ -31,18 +31,16 @@ static int register_replace_ref(const char *refname, return 0; } -#define prepare_replace_object(r) \ - prepare_replace_object_##r() -static void prepare_replace_object_the_repository(void) +static void prepare_replace_object(struct repository *r) { - if (the_repository->objects->replace_map) + if (r->objects->replace_map) return; - the_repository->objects->replace_map = + r->objects->replace_map = xmalloc(sizeof(*the_repository->objects->replace_map)); - oidmap_init(the_repository->objects->replace_map, 0); + oidmap_init(r->objects->replace_map, 0); - for_each_replace_ref(the_repository, register_replace_ref, NULL); + for_each_replace_ref(r, register_replace_ref, NULL); } /* We allow "recursive" replacement. Only within reason, though */ -- cgit v0.10.2-6-g49f6 From 5643557e63de2cd0b81297fe975b001fa5be2c0a Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:17 -0700 Subject: replace-object: allow do_lookup_replace_object to handle arbitrary repositories Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace-object.h b/replace-object.h index dff57bf..f05354c 100644 --- a/replace-object.h +++ b/replace-object.h @@ -14,8 +14,8 @@ struct replace_object { * This internal function is only declared here for the benefit of * lookup_replace_object(). Please do not call it directly. */ -#define do_lookup_replace_object(r, s) do_lookup_replace_object_##r(s) -extern const struct object_id *do_lookup_replace_object_the_repository(const struct object_id *oid); +extern const struct object_id *do_lookup_replace_object(struct repository *r, + const struct object_id *oid); /* * If object sha1 should be replaced, return the replacement object's diff --git a/replace_object.c b/replace_object.c index eae52c6..246b98c 100644 --- a/replace_object.c +++ b/replace_object.c @@ -53,17 +53,18 @@ static void prepare_replace_object(struct repository *r) * permanently-allocated value. This function always respects replace * references, regardless of the value of check_replace_refs. */ -const struct object_id *do_lookup_replace_object_the_repository(const struct object_id *oid) +const struct object_id *do_lookup_replace_object(struct repository *r, + const struct object_id *oid) { int depth = MAXREPLACEDEPTH; const struct object_id *cur = oid; - prepare_replace_object(the_repository); + prepare_replace_object(r); /* Try to recursively replace the object */ while (depth-- > 0) { struct replace_object *repl_obj = - oidmap_get(the_repository->objects->replace_map, cur); + oidmap_get(r->objects->replace_map, cur); if (!repl_obj) return cur; cur = &repl_obj->replacement; -- cgit v0.10.2-6-g49f6 From 90e777f1e20dd6bdc022d5720a9169ea2205d9ad Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 11 Apr 2018 17:21:18 -0700 Subject: replace-object: allow lookup_replace_object to handle arbitrary repositories Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano diff --git a/replace-object.h b/replace-object.h index f05354c..f996de3 100644 --- a/replace-object.h +++ b/replace-object.h @@ -23,14 +23,14 @@ extern const struct object_id *do_lookup_replace_object(struct repository *r, * either sha1 or a pointer to a permanently-allocated value. When * object replacement is suppressed, always return sha1. */ -#define lookup_replace_object(r, s) lookup_replace_object_##r(s) -static inline const struct object_id *lookup_replace_object_the_repository(const struct object_id *oid) +static inline const struct object_id *lookup_replace_object(struct repository *r, + const struct object_id *oid) { if (!check_replace_refs || - (the_repository->objects->replace_map && - the_repository->objects->replace_map->map.tablesize == 0)) + (r->objects->replace_map && + r->objects->replace_map->map.tablesize == 0)) return oid; - return do_lookup_replace_object(the_repository, oid); + return do_lookup_replace_object(r, oid); } #endif /* REPLACE_OBJECT_H */ -- cgit v0.10.2-6-g49f6