]> Kevux Git Server - rit/commitdiff
environment: move access to "core.bigFileThreshold" into repo settings
authorPatrick Steinhardt <ps@pks.im>
Mon, 10 Mar 2025 07:13:23 +0000 (08:13 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Mar 2025 20:16:18 +0000 (13:16 -0700)
The "core.bigFileThreshold" setting is stored in a global variable and
populated via `git_default_core_config()`. This may cause issues in
the case where one is handling multiple different repositories in a
single process with different values for that config key, as we may or
may not see the correct value in that case. Furthermore, global state
blocks our path towards libification.

Refactor the code so that we instead store the value in `struct
repo_settings`, where the value is computed as-needed and cached.

Note that this change requires us to adapt one test in t1050 that
verifies that we die when parsing an invalid "core.bigFileThreshold"
value. The exercised Git command doesn't use the value at all, and thus
it won't hit the new code path that parses the value. This is addressed
by using git-hash-object(1) instead, which does read the value.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
15 files changed:
archive.c
builtin/fast-import.c
builtin/index-pack.c
builtin/pack-objects.c
builtin/unpack-objects.c
config.c
diff.c
environment.c
environment.h
object-file.c
pack-check.c
repo-settings.c
repo-settings.h
streaming.c
t/t1050-large.sh

index 8be4e7a..f4331ae 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -216,7 +216,7 @@ static int write_archive_entry(const struct object_id *oid, const char *base,
        /* Stream it? */
        if (S_ISREG(mode) && !args->convert &&
            oid_object_info(args->repo, oid, &size) == OBJ_BLOB &&
-           size > big_file_threshold)
+           size > repo_settings_get_big_file_threshold(the_repository))
                return write_entry(args, oid, path.buf, path.len, mode, NULL, size);
 
        buffer = object_file_to_archive(args, path.buf, oid, mode, &type, &size);
index e1758aa..ce52f78 100644 (file)
@@ -2021,7 +2021,7 @@ static void parse_and_store_blob(
        static struct strbuf buf = STRBUF_INIT;
        uintmax_t len;
 
-       if (parse_data(&buf, big_file_threshold, &len))
+       if (parse_data(&buf, repo_settings_get_big_file_threshold(the_repository), &len))
                store_object(OBJ_BLOB, &buf, last, oidout, mark);
        else {
                if (last) {
@@ -3402,7 +3402,7 @@ static int parse_one_option(const char *option)
                unsigned long v;
                if (!git_parse_ulong(option, &v))
                        return 0;
-               big_file_threshold = v;
+               repo_settings_set_big_file_threshold(the_repository, v);
        } else if (skip_prefix(option, "depth=", &option)) {
                option_depth(option);
        } else if (skip_prefix(option, "active-branches=", &option)) {
index 174e03a..09c0a8a 100644 (file)
@@ -485,7 +485,8 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
                git_hash_update(&c, hdr, hdrlen);
        } else
                oid = NULL;
-       if (type == OBJ_BLOB && size > big_file_threshold)
+       if (type == OBJ_BLOB &&
+           size > repo_settings_get_big_file_threshold(the_repository))
                buf = fixed_buf;
        else
                buf = xmallocz(size);
@@ -799,7 +800,8 @@ static int check_collison(struct object_entry *entry)
        enum object_type type;
        unsigned long size;
 
-       if (entry->size <= big_file_threshold || entry->type != OBJ_BLOB)
+       if (entry->size <= repo_settings_get_big_file_threshold(the_repository) ||
+           entry->type != OBJ_BLOB)
                return -1;
 
        memset(&data, 0, sizeof(data));
index e05dfc4..eefc6c7 100644 (file)
@@ -499,7 +499,8 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
 
        if (!usable_delta) {
                if (oe_type(entry) == OBJ_BLOB &&
-                   oe_size_greater_than(&to_pack, entry, big_file_threshold) &&
+                   oe_size_greater_than(&to_pack, entry,
+                                        repo_settings_get_big_file_threshold(the_repository)) &&
                    (st = open_istream(the_repository, &entry->idx.oid, &type,
                                       &size, NULL)) != NULL)
                        buf = NULL;
@@ -2454,7 +2455,8 @@ static void get_object_details(void)
                struct object_entry *entry = sorted_by_offset[i];
                check_object(entry, i);
                if (entry->type_valid &&
-                   oe_size_greater_than(&to_pack, entry, big_file_threshold))
+                   oe_size_greater_than(&to_pack, entry,
+                                        repo_settings_get_big_file_threshold(the_repository)))
                        entry->no_try_delta = 1;
                display_progress(progress_state, i + 1);
        }
index 8383bcf..e20c120 100644 (file)
@@ -553,7 +553,8 @@ static void unpack_one(unsigned nr)
 
        switch (type) {
        case OBJ_BLOB:
-               if (!dry_run && size > big_file_threshold) {
+               if (!dry_run &&
+                   size > repo_settings_get_big_file_threshold(the_repository)) {
                        stream_blob(size, nr);
                        return;
                }
index dfd03b9..dc95608 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1490,11 +1490,6 @@ static int git_default_core_config(const char *var, const char *value,
                return 0;
        }
 
-       if (!strcmp(var, "core.bigfilethreshold")) {
-               big_file_threshold = git_config_ulong(var, value, ctx->kvi);
-               return 0;
-       }
-
        if (!strcmp(var, "core.autocrlf")) {
                if (value && !strcasecmp(value, "input")) {
                        auto_crlf = AUTO_CRLF_INPUT;
diff --git a/diff.c b/diff.c
index c89c15d..4f802b4 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -4193,7 +4193,8 @@ int diff_populate_filespec(struct repository *r,
                 * is probably fine.
                 */
                if (check_binary &&
-                   s->size > big_file_threshold && s->is_binary == -1) {
+                   s->size > repo_settings_get_big_file_threshold(the_repository) &&
+                   s->is_binary == -1) {
                        s->is_binary = 1;
                        return 0;
                }
@@ -4243,7 +4244,8 @@ object_read:
                if (size_only || check_binary) {
                        if (size_only)
                                return 0;
-                       if (s->size > big_file_threshold && s->is_binary == -1) {
+                       if (s->size > repo_settings_get_big_file_threshold(the_repository) &&
+                           s->is_binary == -1) {
                                s->is_binary = 1;
                                return 0;
                        }
index 9e4c778..3c32367 100644 (file)
@@ -49,7 +49,6 @@ int fsync_object_files = -1;
 int use_fsync = -1;
 enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT;
 enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT;
-unsigned long big_file_threshold = 512 * 1024 * 1024;
 char *editor_program;
 char *askpass_program;
 char *excludes_file;
index 45e690f..91d854d 100644 (file)
@@ -154,7 +154,6 @@ extern int zlib_compression_level;
 extern int pack_compression_level;
 extern size_t packed_git_window_size;
 extern size_t packed_git_limit;
-extern unsigned long big_file_threshold;
 extern unsigned long pack_size_limit_cfg;
 extern int max_allowed_tree_depth;
 
index 726e41a..b3e0276 100644 (file)
@@ -2803,7 +2803,8 @@ int index_fd(struct index_state *istate, struct object_id *oid,
                ret = index_stream_convert_blob(istate, oid, fd, path, flags);
        else if (!S_ISREG(st->st_mode))
                ret = index_pipe(istate, oid, fd, type, path, flags);
-       else if (st->st_size <= big_file_threshold || type != OBJ_BLOB ||
+       else if (st->st_size <= repo_settings_get_big_file_threshold(the_repository) ||
+                type != OBJ_BLOB ||
                 (path && would_convert_to_git(istate, path)))
                ret = index_core(istate, oid, fd, xsize_t(st->st_size),
                                 type, path, flags);
@@ -3137,7 +3138,8 @@ int read_loose_object(const char *path,
                goto out;
        }
 
-       if (*oi->typep == OBJ_BLOB && *size > big_file_threshold) {
+       if (*oi->typep == OBJ_BLOB &&
+           *size > repo_settings_get_big_file_threshold(the_repository)) {
                if (check_stream_oid(&stream, hdr, *size, path, expected_oid) < 0)
                        goto out;
        } else {
index 6bcadc1..017dc74 100644 (file)
@@ -131,7 +131,8 @@ static int verify_packfile(struct repository *r,
                type = unpack_object_header(p, w_curs, &curpos, &size);
                unuse_pack(w_curs);
 
-               if (type == OBJ_BLOB && big_file_threshold <= size) {
+               if (type == OBJ_BLOB &&
+                   repo_settings_get_big_file_threshold(the_repository) <= size) {
                        /*
                         * Let stream_object_signature() check it with
                         * the streaming interface; no point slurping
index 67e9cfd..4129f8f 100644 (file)
@@ -20,6 +20,13 @@ static void repo_cfg_int(struct repository *r, const char *key, int *dest,
                *dest = def;
 }
 
+static void repo_cfg_ulong(struct repository *r, const char *key, unsigned long *dest,
+                          unsigned long def)
+{
+       if (repo_config_get_ulong(r, key, dest))
+               *dest = def;
+}
+
 void prepare_repo_settings(struct repository *r)
 {
        int experimental;
@@ -151,6 +158,19 @@ void repo_settings_clear(struct repository *r)
        r->settings = empty;
 }
 
+unsigned long repo_settings_get_big_file_threshold(struct repository *repo)
+{
+       if (!repo->settings.big_file_threshold)
+               repo_cfg_ulong(repo, "core.bigfilethreshold",
+                              &repo->settings.big_file_threshold, 512 * 1024 * 1024);
+       return repo->settings.big_file_threshold;
+}
+
+void repo_settings_set_big_file_threshold(struct repository *repo, unsigned long value)
+{
+       repo->settings.big_file_threshold = value;
+}
+
 enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo)
 {
        const char *value;
index ddc1196..2bf24b2 100644 (file)
@@ -64,6 +64,7 @@ struct repo_settings {
        size_t delta_base_cache_limit;
        size_t packed_git_window_size;
        size_t packed_git_limit;
+       unsigned long big_file_threshold;
 
        char *hooks_path;
 };
@@ -88,6 +89,10 @@ int repo_settings_get_warn_ambiguous_refs(struct repository *repo);
 /* Read the value for "core.hooksPath". */
 const char *repo_settings_get_hooks_path(struct repository *repo);
 
+/* Read and set the value for "core.bigFileThreshold". */
+unsigned long repo_settings_get_big_file_threshold(struct repository *repo);
+void repo_settings_set_big_file_threshold(struct repository *repo, unsigned long value);
+
 /* Read, set or reset the value for "core.sharedRepository". */
 int repo_settings_get_shared_repository(struct repository *repo);
 void repo_settings_set_shared_repository(struct repository *repo, int value);
index 3883951..018b794 100644 (file)
@@ -431,7 +431,8 @@ static int istream_source(struct git_istream *st,
                st->open = open_istream_loose;
                return 0;
        case OI_PACKED:
-               if (!oi.u.packed.is_delta && big_file_threshold < size) {
+               if (!oi.u.packed.is_delta &&
+                   repo_settings_get_big_file_threshold(the_repository) < size) {
                        st->u.in_pack.pack = oi.u.packed.pack;
                        st->u.in_pack.pos = oi.u.packed.offset;
                        st->open = open_istream_pack_non_delta;
index c71932b..5be2736 100755 (executable)
@@ -6,7 +6,8 @@ test_description='adding and checking out large blobs'
 . ./test-lib.sh
 
 test_expect_success 'core.bigFileThreshold must be non-negative' '
-       test_must_fail git -c core.bigFileThreshold=-1 rev-parse >out 2>err &&
+       : >input &&
+       test_must_fail git -c core.bigFileThreshold=-1 hash-object input >out 2>err &&
        grep "bad numeric config value" err &&
        test_must_be_empty out
 '