diff --git a/config.c b/config.c index 50bf73d07d2f3e..cc6402e6f29beb 100644 --- a/config.c +++ b/config.c @@ -1807,6 +1807,11 @@ int git_default_core_config(const char *var, const char *value, return 0; } + if (!strcmp(var, "core.virtualizeobjects")) { + core_virtualize_objects = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return platform_core_config(var, value, ctx, cb); } diff --git a/connected.c b/connected.c index bc850e50ce4dcc..12b9f49cdfa801 100644 --- a/connected.c +++ b/connected.c @@ -1,4 +1,5 @@ #include "git-compat-util.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "gvfs.h" @@ -50,6 +51,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data, */ if (gvfs_config_is_set(GVFS_FETCH_SKIP_REACHABILITY_AND_UPLOADPACK)) return 0; + if (core_virtualize_objects) + return 0; if (!opt) opt = &defaults; diff --git a/environment.c b/environment.c index 0681edbab9cac6..e3cbae74f31875 100644 --- a/environment.c +++ b/environment.c @@ -81,6 +81,7 @@ int core_gvfs; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; +int core_virtualize_objects; enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET; #ifndef PROTECT_HFS_DEFAULT diff --git a/environment.h b/environment.h index 8881ac7528a9c6..9373b7e2f22113 100644 --- a/environment.h +++ b/environment.h @@ -11,6 +11,8 @@ struct strvec; extern char comment_line_char; extern int auto_comment_line_char; +extern int core_virtualize_objects; + /* * Wrapper of getenv() that returns a strdup value. This value is kept * in argv to be freed later. diff --git a/object-file.c b/object-file.c index 4df61c0ce6b33f..774f45b254f64a 100644 --- a/object-file.c +++ b/object-file.c @@ -43,6 +43,8 @@ #include "setup.h" #include "submodule.h" #include "fsck.h" +#include "trace.h" +#include "hook.h" /* The maximum size for an object header. */ #define MAX_HEADER_LEN 32 @@ -1552,6 +1554,20 @@ void disable_obj_read_lock(void) pthread_mutex_destroy(&obj_read_mutex); } +static int run_read_object_hook(const struct object_id *oid) +{ + struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; + int ret; + uint64_t start; + + start = getnanotime(); + strvec_push(&opt.args, oid_to_hex(oid)); + ret = run_hooks_opt("read-object", &opt); + trace_performance_since(start, "run_read_object_hook"); + + return ret; +} + int fetch_if_missing = 1; static int do_oid_object_info_extended(struct repository *r, @@ -1564,6 +1580,7 @@ static int do_oid_object_info_extended(struct repository *r, int rtype; const struct object_id *real = oid; int already_retried = 0; + int tried_hook = 0; if (flags & OBJECT_INFO_LOOKUP_REPLACE) @@ -1575,6 +1592,7 @@ static int do_oid_object_info_extended(struct repository *r, if (!oi) oi = &blank_oi; +retry: co = find_cached_object(real); if (co) { if (oi->typep) @@ -1606,6 +1624,11 @@ static int do_oid_object_info_extended(struct repository *r, reprepare_packed_git(r); if (find_pack_entry(r, real, &e)) break; + if (core_virtualize_objects && !tried_hook) { + tried_hook = 1; + if (!run_read_object_hook(oid)) + goto retry; + } } /*