2023-03-21 06:25:56 +00:00
|
|
|
#include "git-compat-util.h"
|
2023-03-21 06:25:54 +00:00
|
|
|
#include "gettext.h"
|
2023-02-24 00:09:27 +00:00
|
|
|
#include "hex.h"
|
2018-04-12 00:21:04 +00:00
|
|
|
#include "oidmap.h"
|
2023-05-16 06:34:06 +00:00
|
|
|
#include "object-store-ll.h"
|
2018-04-12 00:21:05 +00:00
|
|
|
#include "replace-object.h"
|
2009-01-23 09:06:53 +00:00
|
|
|
#include "refs.h"
|
2018-04-12 00:21:05 +00:00
|
|
|
#include "repository.h"
|
Fix sparse warnings
Fix warnings from 'make check'.
- These files don't include 'builtin.h' causing sparse to complain that
cmd_* isn't declared:
builtin/clone.c:364, builtin/fetch-pack.c:797,
builtin/fmt-merge-msg.c:34, builtin/hash-object.c:78,
builtin/merge-index.c:69, builtin/merge-recursive.c:22
builtin/merge-tree.c:341, builtin/mktag.c:156, builtin/notes.c:426
builtin/notes.c:822, builtin/pack-redundant.c:596,
builtin/pack-refs.c:10, builtin/patch-id.c:60, builtin/patch-id.c:149,
builtin/remote.c:1512, builtin/remote-ext.c:240,
builtin/remote-fd.c:53, builtin/reset.c:236, builtin/send-pack.c:384,
builtin/unpack-file.c:25, builtin/var.c:75
- These files have symbols which should be marked static since they're
only file scope:
submodule.c:12, diff.c:631, replace_object.c:92, submodule.c:13,
submodule.c:14, trace.c:78, transport.c:195, transport-helper.c:79,
unpack-trees.c:19, url.c:3, url.c:18, url.c:104, url.c:117, url.c:123,
url.c:129, url.c:136, thread-utils.c:21, thread-utils.c:48
- These files redeclare symbols to be different types:
builtin/index-pack.c:210, parse-options.c:564, parse-options.c:571,
usage.c:49, usage.c:58, usage.c:63, usage.c:72
- These files use a literal integer 0 when they really should use a NULL
pointer:
daemon.c:663, fast-import.c:2942, imap-send.c:1072, notes-merge.c:362
While we're in the area, clean up some unused #includes in builtin files
(mostly exec_cmd.h).
Signed-off-by: Stephen Boyd <bebarino@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-22 07:51:05 +00:00
|
|
|
#include "commit.h"
|
2009-01-23 09:06:53 +00:00
|
|
|
|
2018-08-20 18:24:19 +00:00
|
|
|
static int register_replace_ref(struct repository *r,
|
|
|
|
const char *refname,
|
2015-05-25 18:39:02 +00:00
|
|
|
const struct object_id *oid,
|
2022-08-25 17:09:48 +00:00
|
|
|
int flag UNUSED,
|
|
|
|
void *cb_data UNUSED)
|
2009-01-23 09:06:53 +00:00
|
|
|
{
|
|
|
|
/* Get sha1 from refname */
|
|
|
|
const char *slash = strrchr(refname, '/');
|
|
|
|
const char *hash = slash ? slash + 1 : refname;
|
|
|
|
struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
|
|
|
|
|
2018-04-12 00:21:04 +00:00
|
|
|
if (get_oid_hex(hash, &repl_obj->original.oid)) {
|
2009-01-23 09:06:53 +00:00
|
|
|
free(repl_obj);
|
2018-07-21 07:49:37 +00:00
|
|
|
warning(_("bad replace ref name: %s"), refname);
|
2009-01-23 09:06:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy sha1 from the read ref */
|
2018-03-12 02:27:33 +00:00
|
|
|
oidcpy(&repl_obj->replacement, oid);
|
2009-01-23 09:06:53 +00:00
|
|
|
|
|
|
|
/* Register new object */
|
2018-08-20 18:24:19 +00:00
|
|
|
if (oidmap_put(r->objects->replace_map, repl_obj))
|
2018-07-21 07:49:37 +00:00
|
|
|
die(_("duplicate replace ref: %s"), refname);
|
2009-01-23 09:06:53 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-20 18:24:27 +00:00
|
|
|
void prepare_replace_object(struct repository *r)
|
2009-01-23 09:06:53 +00:00
|
|
|
{
|
replace-object: make replace operations thread-safe
replace-object functions are very close to being thread-safe: the only
current racy section is the lazy initialization at
prepare_replace_object(). The following patches will protect some object
reading operations to be called threaded, but before that, replace
functions must be protected. To do so, add a mutex to struct
raw_object_store and acquire it before lazy initializing the
replace_map. This won't cause any noticeable performance drop as the
mutex will no longer be used after the replace_map is initialized.
Later, when the replace functions are called in parallel, thread
debuggers might point our use of the added replace_map_initialized flag
as a data race. However, as this boolean variable is initialized as
false and it's only updated once, there's no real harm. It's perfectly
fine if the value is updated right after a thread read it in
replace-map.h:lookup_replace_object() (there'll only be a performance
penalty for the affected threads at that moment). We could cease the
debugger warning protecting the variable reading at the said function.
However, this would negatively affect performance for all threads
calling it, at any time, so it's not really worthy since the warning
doesn't represent a real problem. Instead, to make sure we don't get
false positives (at ThreadSanitizer, at least) an entry for the
respective function is added to .tsan-suppressions.
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-16 02:39:52 +00:00
|
|
|
if (r->objects->replace_map_initialized)
|
2009-01-23 09:06:53 +00:00
|
|
|
return;
|
|
|
|
|
replace-object: make replace operations thread-safe
replace-object functions are very close to being thread-safe: the only
current racy section is the lazy initialization at
prepare_replace_object(). The following patches will protect some object
reading operations to be called threaded, but before that, replace
functions must be protected. To do so, add a mutex to struct
raw_object_store and acquire it before lazy initializing the
replace_map. This won't cause any noticeable performance drop as the
mutex will no longer be used after the replace_map is initialized.
Later, when the replace functions are called in parallel, thread
debuggers might point our use of the added replace_map_initialized flag
as a data race. However, as this boolean variable is initialized as
false and it's only updated once, there's no real harm. It's perfectly
fine if the value is updated right after a thread read it in
replace-map.h:lookup_replace_object() (there'll only be a performance
penalty for the affected threads at that moment). We could cease the
debugger warning protecting the variable reading at the said function.
However, this would negatively affect performance for all threads
calling it, at any time, so it's not really worthy since the warning
doesn't represent a real problem. Instead, to make sure we don't get
false positives (at ThreadSanitizer, at least) an entry for the
respective function is added to .tsan-suppressions.
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-16 02:39:52 +00:00
|
|
|
pthread_mutex_lock(&r->objects->replace_mutex);
|
|
|
|
if (r->objects->replace_map_initialized) {
|
|
|
|
pthread_mutex_unlock(&r->objects->replace_mutex);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-04-12 00:21:16 +00:00
|
|
|
r->objects->replace_map =
|
2018-05-09 23:40:59 +00:00
|
|
|
xmalloc(sizeof(*r->objects->replace_map));
|
2018-04-12 00:21:16 +00:00
|
|
|
oidmap_init(r->objects->replace_map, 0);
|
2018-04-12 00:21:07 +00:00
|
|
|
|
2018-04-12 00:21:16 +00:00
|
|
|
for_each_replace_ref(r, register_replace_ref, NULL);
|
replace-object: make replace operations thread-safe
replace-object functions are very close to being thread-safe: the only
current racy section is the lazy initialization at
prepare_replace_object(). The following patches will protect some object
reading operations to be called threaded, but before that, replace
functions must be protected. To do so, add a mutex to struct
raw_object_store and acquire it before lazy initializing the
replace_map. This won't cause any noticeable performance drop as the
mutex will no longer be used after the replace_map is initialized.
Later, when the replace functions are called in parallel, thread
debuggers might point our use of the added replace_map_initialized flag
as a data race. However, as this boolean variable is initialized as
false and it's only updated once, there's no real harm. It's perfectly
fine if the value is updated right after a thread read it in
replace-map.h:lookup_replace_object() (there'll only be a performance
penalty for the affected threads at that moment). We could cease the
debugger warning protecting the variable reading at the said function.
However, this would negatively affect performance for all threads
calling it, at any time, so it's not really worthy since the warning
doesn't represent a real problem. Instead, to make sure we don't get
false positives (at ThreadSanitizer, at least) an entry for the
respective function is added to .tsan-suppressions.
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-16 02:39:52 +00:00
|
|
|
r->objects->replace_map_initialized = 1;
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&r->objects->replace_mutex);
|
2009-01-23 09:06:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We allow "recursive" replacement. Only within reason, though */
|
|
|
|
#define MAXREPLACEDEPTH 5
|
|
|
|
|
2014-02-28 16:29:16 +00:00
|
|
|
/*
|
2018-03-12 02:27:54 +00:00
|
|
|
* If a replacement for object oid has been set up, return the
|
2014-02-28 16:29:16 +00:00
|
|
|
* replacement object's name (replaced recursively, if necessary).
|
2018-03-12 02:27:54 +00:00
|
|
|
* The return value is either oid or a pointer to a
|
2014-02-28 16:29:16 +00:00
|
|
|
* permanently-allocated value. This function always respects replace
|
2023-06-06 13:24:37 +00:00
|
|
|
* references, regardless of the value of r->settings.read_replace_refs.
|
2014-02-28 16:29:16 +00:00
|
|
|
*/
|
2018-04-12 00:21:17 +00:00
|
|
|
const struct object_id *do_lookup_replace_object(struct repository *r,
|
|
|
|
const struct object_id *oid)
|
2009-01-23 09:06:53 +00:00
|
|
|
{
|
2018-04-12 00:21:04 +00:00
|
|
|
int depth = MAXREPLACEDEPTH;
|
2018-03-12 02:27:54 +00:00
|
|
|
const struct object_id *cur = oid;
|
2009-01-23 09:06:53 +00:00
|
|
|
|
2018-04-12 00:21:17 +00:00
|
|
|
prepare_replace_object(r);
|
2009-01-23 09:06:53 +00:00
|
|
|
|
|
|
|
/* Try to recursively replace the object */
|
2018-04-12 00:21:04 +00:00
|
|
|
while (depth-- > 0) {
|
2018-04-12 00:21:05 +00:00
|
|
|
struct replace_object *repl_obj =
|
2018-04-12 00:21:17 +00:00
|
|
|
oidmap_get(r->objects->replace_map, cur);
|
2018-04-12 00:21:04 +00:00
|
|
|
if (!repl_obj)
|
|
|
|
return cur;
|
|
|
|
cur = &repl_obj->replacement;
|
|
|
|
}
|
2018-07-21 07:49:37 +00:00
|
|
|
die(_("replace depth too high for object %s"), oid_to_hex(oid));
|
2009-01-23 09:06:53 +00:00
|
|
|
}
|
2023-06-06 13:24:35 +00:00
|
|
|
|
2023-06-06 13:24:37 +00:00
|
|
|
/*
|
|
|
|
* This indicator determines whether replace references should be
|
|
|
|
* respected process-wide, regardless of which repository is being
|
|
|
|
* using at the time.
|
|
|
|
*/
|
|
|
|
static int read_replace_refs = 1;
|
|
|
|
|
2023-06-06 13:24:35 +00:00
|
|
|
void disable_replace_refs(void)
|
|
|
|
{
|
|
|
|
read_replace_refs = 0;
|
|
|
|
}
|
2023-06-06 13:24:36 +00:00
|
|
|
|
|
|
|
int replace_refs_enabled(struct repository *r)
|
|
|
|
{
|
2023-06-06 13:24:37 +00:00
|
|
|
if (!read_replace_refs)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (r->gitdir) {
|
|
|
|
prepare_repo_settings(r);
|
|
|
|
return r->settings.read_replace_refs;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* repository has no objects or refs. */
|
|
|
|
return 0;
|
2023-06-06 13:24:36 +00:00
|
|
|
}
|