config: use repo_ignore_case() to access core.ignorecase

Replace the accesses to the global 'ignore_case' variable with calls to 'repo_ignore_case(the_repository)'. This step eliminates the 'ignore_case' global state. Note on compat/win32/path-utils.c: To eliminate the global state, several helper functions (e.g. 'win32_fspathncmp()') now read from 'repo_ignore_case(the_repository)'. While this introduces dependency on 'repository.h' into the 'compat/', it avoids massive refactoring of the signatures across the codebase. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com> Mentored-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Tian Yuchen <cat@malon.dev> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Tian Yuchen committed Jun 19, 2026 at 23:51 UTC e6a79c9eb88e9bb07af94cc35dfdb392de56456a
14 files changed +27 -28
apply.c
+1 -1
@@ -4008,7 +4008,7 @@ static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *na
4008 struct cache_entry *ce;
4009
4010 ce = index_file_exists(state->repo->index, name->buf,
4011 - name->len, ignore_case);
4011 + name->len, repo_ignore_case(the_repository));
4012 if (ce && S_ISLNK(ce->ce_mode))
4013 return 1;
4014 } else {
builtin/fetch.c
+1 -1
@@ -1819,7 +1819,7 @@ static void ref_transaction_rejection_handler(const char *refname,
1819 {
1820 struct ref_rejection_data *data = cb_data;
1821
1822 - if (err == REF_TRANSACTION_ERROR_CASE_CONFLICT && ignore_case &&
1822 + if (err == REF_TRANSACTION_ERROR_CASE_CONFLICT && repo_ignore_case(the_repository) &&
1823 !data->case_sensitive_msg_shown) {
1824 error(_("You're on a case-insensitive filesystem, and the remote you are\n"
1825 "trying to fetch from has references that only differ in casing. It\n"
builtin/mv.c
+1 -1
@@ -419,7 +419,7 @@ dir_check:
419 goto act_on_entry;
420 }
421 if (lstat(dst, &st) == 0 &&
422 - (!ignore_case || strcasecmp(src, dst))) {
422 + (!repo_ignore_case(the_repository) || strcasecmp(src, dst))) {
423 bad = _("destination exists");
424 if (force) {
425 /*
compat/win32/path-utils.c
+2 -1
@@ -2,6 +2,7 @@
2
3 #include "../../git-compat-util.h"
4 #include "../../environment.h"
5 +#include "../../repository.h"
6
7 int win32_has_dos_drive_prefix(const char *path)
8 {
@@ -75,7 +76,7 @@ int win32_fspathncmp(const char *a, const char *b, size_t count)
76 } else if (is_dir_sep(*b))
77 return +1;
78
78 - diff = ignore_case ?
79 + diff = repo_ignore_case(the_repository) ?
80 (unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
81 (unsigned char)*a - (int)(unsigned char)*b;
82 if (diff)
dir.c
+9 -9
@@ -126,7 +126,7 @@ int count_slashes(const char *s)
126
127 int git_fspathcmp(const char *a, const char *b)
128 {
129 - return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
129 + return repo_ignore_case(the_repository) ? strcasecmp(a, b) : strcmp(a, b);
130 }
131
132 int fspatheq(const char *a, const char *b)
@@ -136,7 +136,7 @@ int fspatheq(const char *a, const char *b)
136
137 int git_fspathncmp(const char *a, const char *b, size_t count)
138 {
139 - return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
139 + return repo_ignore_case(the_repository) ? strncasecmp(a, b, count) : strncmp(a, b, count);
140 }
141
142 int paths_collide(const char *a, const char *b)
@@ -153,7 +153,7 @@ int paths_collide(const char *a, const char *b)
153
154 unsigned int fspathhash(const char *str)
155 {
156 - return ignore_case ? strihash(str) : strhash(str);
156 + return repo_ignore_case(the_repository) ? strihash(str) : strhash(str);
157 }
158
159 int git_fnmatch(const struct pathspec_item *item,
@@ -202,7 +202,7 @@ static int fnmatch_icase_mem(const char *pattern, int patternlen,
202 use_str = str_buf.buf;
203 }
204
205 - if (ignore_case)
205 + if (repo_ignore_case(the_repository))
206 flags |= WM_CASEFOLD;
207 match_status = wildmatch(use_pat, use_str, flags);
208
@@ -1851,7 +1851,7 @@ static struct dir_entry *dir_add_name(struct dir_struct *dir,
1851 struct index_state *istate,
1852 const char *pathname, int len)
1853 {
1854 - if (index_file_exists(istate, pathname, len, ignore_case))
1854 + if (index_file_exists(istate, pathname, len, repo_ignore_case(the_repository)))
1855 return NULL;
1856
1857 ALLOC_GROW(dir->entries, dir->nr+1, dir->internal.alloc);
@@ -1888,7 +1888,7 @@ static enum exist_status directory_exists_in_index_icase(struct index_state *ist
1888 if (index_dir_exists(istate, dirname, len))
1889 return index_directory;
1890
1891 - ce = index_file_exists(istate, dirname, len, ignore_case);
1891 + ce = index_file_exists(istate, dirname, len, repo_ignore_case(the_repository));
1892 if (ce && S_ISGITLINK(ce->ce_mode))
1893 return index_gitdir;
1894
@@ -1907,7 +1907,7 @@ static enum exist_status directory_exists_in_index(struct index_state *istate,
1907 {
1908 int pos;
1909
1910 - if (ignore_case)
1910 + if (repo_ignore_case(the_repository))
1911 return directory_exists_in_index_icase(istate, dirname, len);
1912
1913 pos = index_name_pos(istate, dirname, len);
@@ -2447,7 +2447,7 @@ static enum path_treatment treat_path(struct dir_struct *dir,
2447
2448 /* Always exclude indexed files */
2449 has_path_in_index = !!index_file_exists(istate, path->buf, path->len,
2450 - ignore_case);
2450 + repo_ignore_case(the_repository));
2451 if (dtype != DT_DIR && has_path_in_index)
2452 return path_none;
2453
@@ -3201,7 +3201,7 @@ static int cmp_icase(char a, char b)
3201 {
3202 if (a == b)
3203 return 0;
3204 - if (ignore_case)
3204 + if (repo_ignore_case(the_repository))
3205 return toupper(a) - toupper(b);
3206 return a - b;
3207 }
environment.c
+1 -2
@@ -46,7 +46,6 @@ int trust_ctime = 1;
46 int check_stat = 1;
47 int has_symlinks = 1;
48 int minimum_abbrev = 4, default_abbrev = -1;
49 -int ignore_case;
49 int assume_unchanged;
50 int is_bare_repository_cfg = -1; /* unspecified */
51 int warn_on_object_refname_ambiguity = 1;
@@ -342,7 +341,7 @@ int git_default_core_config(const char *var, const char *value,
341 }
342
343 if (!strcmp(var, "core.ignorecase")) {
345 - ignore_case = git_config_bool(var, value);
344 + cfg->ignore_case = git_config_bool(var, value);
345 return 0;
346 }
347
environment.h
-1
@@ -171,7 +171,6 @@ extern int trust_ctime;
171 extern int check_stat;
172 extern int has_symlinks;
173 extern int minimum_abbrev, default_abbrev;
174 -extern int ignore_case;
174 extern int assume_unchanged;
175 extern int warn_on_object_refname_ambiguity;
176 extern char *apply_default_whitespace;
fsmonitor.c
+1 -1
@@ -453,7 +453,7 @@ static void fsmonitor_refresh_callback(struct index_state *istate, char *name)
453 * case-insensitive file system, try again using the name-hash
454 * and dir-name-hash.
455 */
456 - if (!nr_in_cone && ignore_case) {
456 + if (!nr_in_cone && repo_ignore_case(the_repository)) {
457 nr_in_cone = handle_using_name_hash_icase(istate, name);
458 if (!nr_in_cone)
459 nr_in_cone = handle_using_dir_name_hash_icase(
name-hash.c
+3 -3
@@ -126,7 +126,7 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
126 hashmap_add(&istate->name_hash, &ce->ent);
127 }
128
129 - if (ignore_case)
129 + if (repo_ignore_case(the_repository))
130 add_dir_entry(istate, ce);
131 }
132
@@ -207,7 +207,7 @@ static int lookup_lazy_params(struct index_state *istate)
207 * code to build the "istate->name_hash". We don't
208 * need the complexity here.
209 */
210 - if (!ignore_case)
210 + if (!repo_ignore_case(the_repository))
211 return 0;
212
213 nr_cpus = online_cpus();
@@ -651,7 +651,7 @@ void remove_name_hash(struct index_state *istate, struct cache_entry *ce)
651 ce->ce_flags &= ~CE_HASHED;
652 hashmap_remove(&istate->name_hash, &ce->ent, ce);
653
654 - if (ignore_case)
654 + if (repo_ignore_case(the_repository))
655 remove_dir_entry(istate, ce);
656 }
657
read-cache.c
+3 -3
@@ -760,12 +760,12 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
760 * case of the file being added to the repository matches (is folded into) the existing
761 * entry's directory case.
762 */
763 - if (ignore_case) {
763 + if (repo_ignore_case(the_repository)) {
764 adjust_dirname_case(istate, ce->name);
765 }
766 if (!(flags & ADD_CACHE_RENORMALIZE)) {
767 alias = index_file_exists(istate, ce->name,
768 - ce_namelen(ce), ignore_case);
768 + ce_namelen(ce), repo_ignore_case(the_repository));
769 if (alias &&
770 !ce_stage(alias) &&
771 !ie_match_stat(istate, alias, st, ce_option)) {
@@ -786,7 +786,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
786 } else
787 set_object_name_for_intent_to_add_entry(ce);
788
789 - if (ignore_case && alias && different_name(ce, alias))
789 + if (repo_ignore_case(the_repository) && alias && different_name(ce, alias))
790 ce = create_alias_ce(istate, ce, alias);
791 ce->ce_flags |= CE_ADDED;
792
refs/files-backend.c
+2 -2
@@ -806,7 +806,7 @@ retry:
806 } else {
807 unable_to_lock_message(ref_file.buf, myerr, err);
808 if (myerr == EEXIST) {
809 - if (ignore_case &&
809 + if (repo_ignore_case(the_repository) &&
810 transaction_has_case_conflicting_update(transaction, update)) {
811 /*
812 * In case-insensitive filesystems, ensure that conflicts within a
@@ -920,7 +920,7 @@ retry:
920 * conflicts between 'foo' and 'Foo/bar'. So let's lowercase
921 * the refname.
922 */
923 - if (ignore_case) {
923 + if (repo_ignore_case(the_repository)) {
924 struct strbuf lower = STRBUF_INIT;
925
926 strbuf_addstr(&lower, refname);
submodule.c
+1 -1
@@ -2389,7 +2389,7 @@ static int validate_submodule_encoded_git_dir(char *git_dir, const char *submodu
2389
2390 /* Prevent conflicts on case-folding filesystems */
2391 repo_config_get_bool(the_repository, "core.ignorecase", &config_ignorecase);
2392 - if (ignore_case || config_ignorecase) {
2392 + if (repo_ignore_case(the_repository) || config_ignorecase) {
2393 bool suffixes_match = !strcmp(last_submodule_name, submodule_name);
2394 return check_casefolding_conflict(git_dir, submodule_name,
2395 suffixes_match);
t/helper/test-lazy-init-name-hash.c
+1 -1
@@ -218,7 +218,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv)
218 /*
219 * istate->dir_hash is only created when ignore_case is set.
220 */
221 - ignore_case = 1;
221 + repo_config_values(the_repository)->ignore_case = 1;
222
223 if (dump) {
224 if (perf || analyze > 0)
unpack-trees.c
+1 -1
@@ -2428,7 +2428,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
2428 *
2429 * Ignore that lstat() if it matches.
2430 */
2431 - if (ignore_case && icase_exists(o, name, len, st))
2431 + if (repo_ignore_case(the_repository) && icase_exists(o, name, len, st))
2432 return 0;
2433
2434 if (o->internal.dir &&