From 2516df27a52c2b4d86d648bb2a24fe3f504dd81c Mon Sep 17 00:00:00 2001 From: Ben Peart Date: Tue, 10 Jan 2017 18:47:14 +0000 Subject: [PATCH] gvfs: allow "virtualizing" objects The idea is to allow blob objects to be missing from the local repository, and to load them lazily on demand. After discussing this idea on the mailing list, we will rename the feature to "lazy clone" and work more on this. Signed-off-by: Ben Peart Signed-off-by: Johannes Schindelin --- config.c | 5 +++++ connected.c | 3 +++ environment.c | 1 + environment.h | 1 + object-file.c | 23 +++++++++++++++++++++++ 5 files changed, 33 insertions(+) diff --git a/config.c b/config.c index 480264a398c407..335459faee6b3c 100644 --- a/config.c +++ b/config.c @@ -1678,6 +1678,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 44e5f75eb063b4..a8cf3dc351fc54 100644 --- a/connected.c +++ b/connected.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "gvfs.h" @@ -52,6 +53,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 6c821d4c5862dc..91962ab8d0ebaf 100644 --- a/environment.c +++ b/environment.c @@ -75,6 +75,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; int max_allowed_tree_depth = #ifdef _MSC_VER /* diff --git a/environment.h b/environment.h index ebb5beae7b22dc..d3d88598256237 100644 --- a/environment.h +++ b/environment.h @@ -226,5 +226,6 @@ extern const char *comment_line_str; extern char *comment_line_str_to_free; extern int auto_comment_line_char; +extern int core_virtualize_objects; # endif /* USE_THE_REPOSITORY_VARIABLE */ #endif /* ENVIRONMENT_H */ diff --git a/object-file.c b/object-file.c index a19be7222a19af..afdca5fe453c04 100644 --- a/object-file.c +++ b/object-file.c @@ -40,6 +40,8 @@ #include "fsck.h" #include "loose.h" #include "object-file-convert.h" +#include "trace.h" +#include "hook.h" /* The maximum size for an object header. */ #define MAX_HEADER_LEN 32 @@ -1620,6 +1622,20 @@ void disable_obj_read_lock(void) pthread_mutex_destroy(&obj_read_mutex); } +static int run_read_object_hook(struct repository *r, 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(r, "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, @@ -1632,6 +1648,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) @@ -1643,6 +1660,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) @@ -1674,6 +1692,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(r, oid)) + goto retry; + } } /*