Git fork
at reftables-rust 232 lines 7.6 kB view raw
1#include "git-compat-util.h" 2#include "config.h" 3#include "repo-settings.h" 4#include "repository.h" 5#include "midx.h" 6#include "pack-objects.h" 7#include "setup.h" 8 9static void repo_cfg_bool(struct repository *r, const char *key, int *dest, 10 int def) 11{ 12 if (repo_config_get_bool(r, key, dest)) 13 *dest = def; 14} 15 16static void repo_cfg_int(struct repository *r, const char *key, int *dest, 17 int def) 18{ 19 if (repo_config_get_int(r, key, dest)) 20 *dest = def; 21} 22 23static void repo_cfg_ulong(struct repository *r, const char *key, unsigned long *dest, 24 unsigned long def) 25{ 26 if (repo_config_get_ulong(r, key, dest)) 27 *dest = def; 28} 29 30void prepare_repo_settings(struct repository *r) 31{ 32 int experimental; 33 int value; 34 const char *strval; 35 int manyfiles; 36 int read_changed_paths; 37 unsigned long ulongval; 38 39 if (!r->gitdir) 40 BUG("Cannot add settings for uninitialized repository"); 41 42 if (r->settings.initialized) 43 return; 44 45 repo_settings_clear(r); 46 r->settings.initialized++; 47 48 /* Booleans config or default, cascades to other settings */ 49 repo_cfg_bool(r, "feature.manyfiles", &manyfiles, 0); 50 repo_cfg_bool(r, "feature.experimental", &experimental, 0); 51 52 /* Defaults modified by feature.* */ 53 if (experimental) { 54 r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING; 55 r->settings.pack_use_bitmap_boundary_traversal = 1; 56 r->settings.pack_use_multi_pack_reuse = 1; 57 r->settings.pack_use_path_walk = 1; 58 } 59 if (manyfiles) { 60 r->settings.index_version = 4; 61 r->settings.index_skip_hash = 1; 62 r->settings.core_untracked_cache = UNTRACKED_CACHE_WRITE; 63 r->settings.pack_use_path_walk = 1; 64 } 65 66 /* Commit graph config or default, does not cascade (simple) */ 67 repo_cfg_bool(r, "core.commitgraph", &r->settings.core_commit_graph, 1); 68 repo_cfg_int(r, "commitgraph.generationversion", &r->settings.commit_graph_generation_version, 2); 69 repo_cfg_bool(r, "commitgraph.readchangedpaths", &read_changed_paths, 1); 70 repo_cfg_int(r, "commitgraph.changedpathsversion", 71 &r->settings.commit_graph_changed_paths_version, 72 read_changed_paths ? -1 : 0); 73 repo_cfg_bool(r, "gc.writecommitgraph", &r->settings.gc_write_commit_graph, 1); 74 repo_cfg_bool(r, "fetch.writecommitgraph", &r->settings.fetch_write_commit_graph, 0); 75 76 /* Boolean config or default, does not cascade (simple) */ 77 repo_cfg_bool(r, "pack.usesparse", &r->settings.pack_use_sparse, 1); 78 repo_cfg_bool(r, "pack.usepathwalk", &r->settings.pack_use_path_walk, 0); 79 repo_cfg_bool(r, "core.multipackindex", &r->settings.core_multi_pack_index, 1); 80 repo_cfg_bool(r, "index.sparse", &r->settings.sparse_index, 0); 81 repo_cfg_bool(r, "index.skiphash", &r->settings.index_skip_hash, r->settings.index_skip_hash); 82 repo_cfg_bool(r, "pack.readreverseindex", &r->settings.pack_read_reverse_index, 1); 83 repo_cfg_bool(r, "pack.usebitmapboundarytraversal", 84 &r->settings.pack_use_bitmap_boundary_traversal, 85 r->settings.pack_use_bitmap_boundary_traversal); 86 repo_cfg_bool(r, "core.usereplacerefs", &r->settings.read_replace_refs, 1); 87 88 /* 89 * The GIT_TEST_MULTI_PACK_INDEX variable is special in that 90 * either it *or* the config sets 91 * r->settings.core_multi_pack_index if true. We don't take 92 * the environment variable if it exists (even if false) over 93 * any config, as in most other cases. 94 */ 95 if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) 96 r->settings.core_multi_pack_index = 1; 97 98 /* 99 * Non-boolean config 100 */ 101 if (!repo_config_get_int(r, "index.version", &value)) 102 r->settings.index_version = value; 103 104 if (!repo_config_get_string_tmp(r, "core.untrackedcache", &strval)) { 105 int v = git_parse_maybe_bool(strval); 106 107 /* 108 * If it's set to "keep", or some other non-boolean 109 * value then "v < 0". Then we do nothing and keep it 110 * at the default of UNTRACKED_CACHE_KEEP. 111 */ 112 if (v >= 0) 113 r->settings.core_untracked_cache = v ? 114 UNTRACKED_CACHE_WRITE : UNTRACKED_CACHE_REMOVE; 115 } 116 117 if (!repo_config_get_string_tmp(r, "fetch.negotiationalgorithm", &strval)) { 118 int fetch_default = r->settings.fetch_negotiation_algorithm; 119 if (!strcasecmp(strval, "skipping")) 120 r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING; 121 else if (!strcasecmp(strval, "noop")) 122 r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_NOOP; 123 else if (!strcasecmp(strval, "consecutive")) 124 r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE; 125 else if (!strcasecmp(strval, "default")) 126 r->settings.fetch_negotiation_algorithm = fetch_default; 127 else 128 die("unknown fetch negotiation algorithm '%s'", strval); 129 } 130 131 /* 132 * This setting guards all index reads to require a full index 133 * over a sparse index. After suitable guards are placed in the 134 * codebase around uses of the index, this setting will be 135 * removed. 136 */ 137 r->settings.command_requires_full_index = 1; 138 139 if (!repo_config_get_ulong(r, "core.deltabasecachelimit", &ulongval)) 140 r->settings.delta_base_cache_limit = ulongval; 141 142 if (!repo_config_get_ulong(r, "core.packedgitwindowsize", &ulongval)) { 143 int pgsz_x2 = getpagesize() * 2; 144 145 /* This value must be multiple of (pagesize * 2) */ 146 ulongval /= pgsz_x2; 147 if (ulongval < 1) 148 ulongval = 1; 149 r->settings.packed_git_window_size = ulongval * pgsz_x2; 150 } 151 152 if (!repo_config_get_ulong(r, "core.packedgitlimit", &ulongval)) 153 r->settings.packed_git_limit = ulongval; 154} 155 156void repo_settings_clear(struct repository *r) 157{ 158 struct repo_settings empty = REPO_SETTINGS_INIT; 159 FREE_AND_NULL(r->settings.fsmonitor); 160 FREE_AND_NULL(r->settings.hooks_path); 161 r->settings = empty; 162} 163 164unsigned long repo_settings_get_big_file_threshold(struct repository *repo) 165{ 166 if (!repo->settings.big_file_threshold) 167 repo_cfg_ulong(repo, "core.bigfilethreshold", 168 &repo->settings.big_file_threshold, 512 * 1024 * 1024); 169 return repo->settings.big_file_threshold; 170} 171 172void repo_settings_set_big_file_threshold(struct repository *repo, unsigned long value) 173{ 174 repo->settings.big_file_threshold = value; 175} 176 177enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo) 178{ 179 const char *value; 180 181 if (!repo_config_get_string_tmp(repo, "core.logallrefupdates", &value)) { 182 if (value && !strcasecmp(value, "always")) 183 return LOG_REFS_ALWAYS; 184 else if (git_config_bool("core.logallrefupdates", value)) 185 return LOG_REFS_NORMAL; 186 else 187 return LOG_REFS_NONE; 188 } 189 190 return LOG_REFS_UNSET; 191} 192 193int repo_settings_get_warn_ambiguous_refs(struct repository *repo) 194{ 195 prepare_repo_settings(repo); 196 if (repo->settings.warn_ambiguous_refs < 0) 197 repo_cfg_bool(repo, "core.warnambiguousrefs", 198 &repo->settings.warn_ambiguous_refs, 1); 199 return repo->settings.warn_ambiguous_refs; 200} 201 202const char *repo_settings_get_hooks_path(struct repository *repo) 203{ 204 if (!repo->settings.hooks_path) 205 repo_config_get_pathname(repo, "core.hookspath", &repo->settings.hooks_path); 206 return repo->settings.hooks_path; 207} 208 209int repo_settings_get_shared_repository(struct repository *repo) 210{ 211 if (!repo->settings.shared_repository_initialized) { 212 const char *var = "core.sharedrepository"; 213 const char *value; 214 if (!repo_config_get_value(repo, var, &value)) 215 repo->settings.shared_repository = git_config_perm(var, value); 216 else 217 repo->settings.shared_repository = PERM_UMASK; 218 repo->settings.shared_repository_initialized = 1; 219 } 220 return repo->settings.shared_repository; 221} 222 223void repo_settings_set_shared_repository(struct repository *repo, int value) 224{ 225 repo->settings.shared_repository = value; 226 repo->settings.shared_repository_initialized = 1; 227} 228 229void repo_settings_reset_shared_repository(struct repository *repo) 230{ 231 repo->settings.shared_repository_initialized = 0; 232}