* [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting
@ 2026-03-01 18:59 drona
2026-03-06 18:02 ` Tian Yuchen
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: drona @ 2026-03-01 18:59 UTC (permalink / raw)
To: git; +Cc: Dorna Raj Gyawali
From: Dorna Raj Gyawali <dronarajgyawali@gmail.com>
Currently, 'trust_executable_bit' is a global variable in environment.c,
which controls how executable bits are interpreted when creating/updating
cache entries.
This patch moves 'trust_executable_bit' into 'struct repo_settings', making
it a repository-scoped configuration. All references in files have been updated to use
'the_repository->settings.trust_executable_bit'.
Why this is a good candidate:
- It's a self-contained global variable that only affects file mode logic.
- Low risk: changes only impact mode calculations and related apply/update
operations.
- Makes Git codebase more maintainable and prepares for future multi-repo
support.
- Manual sanity check with a test repo confirms executable bits behave correctly.
Signed-off-by: Dorna Raj Gyawali <dronarajgyawali@gmail.com>
---
apply.c | 4 ++--
builtin/update-index.c | 2 +-
diff-lib.c | 10 +++++-----
environment.c | 3 +--
environment.h | 1 -
read-cache.c | 10 +++++-----
read-cache.h | 11 +++++++----
repo-settings.h | 6 +++++-
8 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/apply.c b/apply.c
index d044c95d50..2bcb22a4bc 100644
--- a/apply.c
+++ b/apply.c
@@ -3838,8 +3838,8 @@ static int check_preimage(struct apply_state *state,
if (*ce && !(*ce)->ce_mode)
BUG("ce_mode == 0 for path '%s'", old_name);
- if (trust_executable_bit || !S_ISREG(st->st_mode))
- st_mode = ce_mode_from_stat(*ce, st->st_mode);
+ if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode))
+ st_mode = ce_mode_from_stat(the_repository, *ce, st->st_mode);
else if (*ce)
st_mode = (*ce)->ce_mode;
else
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 8a5907767b..7917bd286f 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -293,7 +293,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
ce->ce_flags = create_ce_flags(0);
ce->ce_namelen = len;
fill_stat_cache_info(the_repository->index, ce, st);
- ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
+ ce->ce_mode = ce_mode_from_stat(the_repository, old, st->st_mode);
if (index_path(the_repository->index, &ce->oid, path, st,
info_only ? 0 : INDEX_WRITE_OBJECT)) {
diff --git a/diff-lib.c b/diff-lib.c
index ae91027a02..894358c8b0 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
changed = check_removed(ce, &st);
if (!changed)
- wt_mode = ce_mode_from_stat(ce, st.st_mode);
+ wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode);
else {
if (changed < 0) {
perror(ce->name);
@@ -193,7 +193,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
num_compare_stages++;
oidcpy(&dpath->parent[stage - 2].oid,
&nce->oid);
- dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode);
+ dpath->parent[stage-2].mode = ce_mode_from_stat(the_repository,nce, mode);
dpath->parent[stage-2].status =
DIFF_STATUS_MODIFIED;
}
@@ -262,7 +262,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
continue;
} else if (revs->diffopt.ita_invisible_in_index &&
ce_intent_to_add(ce)) {
- newmode = ce_mode_from_stat(ce, st.st_mode);
+ newmode = ce_mode_from_stat(the_repository, ce, st.st_mode);
diff_addremove(&revs->diffopt, '+', newmode,
null_oid(the_hash_algo), 0, ce->name, 0);
continue;
@@ -270,7 +270,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
ce_option, &dirty_submodule);
- newmode = ce_mode_from_stat(ce, st.st_mode);
+ newmode = ce_mode_from_stat(the_repository, ce, st.st_mode);
}
if (!changed && !dirty_submodule) {
@@ -338,7 +338,7 @@ static int get_stat_data(const struct cache_entry *ce,
changed = match_stat_with_submodule(diffopt, ce, &st,
0, dirty_submodule);
if (changed) {
- mode = ce_mode_from_stat(ce, st.st_mode);
+ mode = ce_mode_from_stat(the_repository, ce, st.st_mode);
oid = null_oid(the_hash_algo);
}
}
diff --git a/environment.c b/environment.c
index 0026eb2274..861ef084dc 100644
--- a/environment.c
+++ b/environment.c
@@ -41,7 +41,6 @@
static int pack_compression_seen;
static int zlib_compression_seen;
-int trust_executable_bit = 1;
int trust_ctime = 1;
int check_stat = 1;
int has_symlinks = 1;
@@ -306,7 +305,7 @@ int git_default_core_config(const char *var, const char *value,
{
/* This needs a better name */
if (!strcmp(var, "core.filemode")) {
- trust_executable_bit = git_config_bool(var, value);
+ the_repository->settings.trust_executable_bit = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "core.trustctime")) {
diff --git a/environment.h b/environment.h
index 27f657af04..7f3437f369 100644
--- a/environment.h
+++ b/environment.h
@@ -144,7 +144,6 @@ int is_bare_repository(void);
extern char *git_work_tree_cfg;
/* Environment bits from configuration mechanism */
-extern int trust_executable_bit;
extern int trust_ctime;
extern int check_stat;
extern int has_symlinks;
diff --git a/read-cache.c b/read-cache.c
index 0c07c3aef7..b1fcb9e1a0 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -201,13 +201,13 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
static unsigned int st_mode_from_ce(const struct cache_entry *ce)
{
- extern int trust_executable_bit, has_symlinks;
+ extern int has_symlinks;
switch (ce->ce_mode & S_IFMT) {
case S_IFLNK:
return has_symlinks ? S_IFLNK : (S_IFREG | 0644);
case S_IFREG:
- return (ce->ce_mode & (trust_executable_bit ? 0755 : 0644)) | S_IFREG;
+ return (ce->ce_mode & (the_repository->settings.trust_executable_bit ? 0755 : 0644)) | S_IFREG;
case S_IFGITLINK:
return S_IFDIR | 0755;
case S_IFDIR:
@@ -317,7 +317,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
/* We consider only the owner x bit to be relevant for
* "mode changes"
*/
- if (trust_executable_bit &&
+ if (the_repository->settings.trust_executable_bit &&
(0100 & (ce->ce_mode ^ st->st_mode)))
changed |= MODE_CHANGED;
break;
@@ -738,7 +738,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
ce->ce_flags |= CE_INTENT_TO_ADD;
- if (trust_executable_bit && has_symlinks) {
+ if (the_repository->settings.trust_executable_bit && has_symlinks) {
ce->ce_mode = create_ce_mode(st_mode);
} else {
/* If there is an existing entry, pick the mode bits and type
@@ -748,7 +748,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
int pos = index_name_pos_also_unmerged(istate, path, namelen);
ent = (0 <= pos) ? istate->cache[pos] : NULL;
- ce->ce_mode = ce_mode_from_stat(ent, st_mode);
+ ce->ce_mode = ce_mode_from_stat(the_repository, ent, st_mode);
}
/* When core.ignorecase=true, determine if a directory of the same name but differing
diff --git a/read-cache.h b/read-cache.h
index 043da1f1aa..4e88d476aa 100644
--- a/read-cache.h
+++ b/read-cache.h
@@ -4,15 +4,18 @@
#include "read-cache-ll.h"
#include "object.h"
#include "pathspec.h"
+#include "repository.h"
-static inline unsigned int ce_mode_from_stat(const struct cache_entry *ce,
- unsigned int mode)
+static inline unsigned int ce_mode_from_stat(
+ struct repository *repo,
+ const struct cache_entry *ce,
+ unsigned int mode)
{
- extern int trust_executable_bit, has_symlinks;
+ extern int has_symlinks;
if (!has_symlinks && S_ISREG(mode) &&
ce && S_ISLNK(ce->ce_mode))
return ce->ce_mode;
- if (!trust_executable_bit && S_ISREG(mode)) {
+ if (!repo->settings.trust_executable_bit && S_ISREG(mode)) {
if (ce && S_ISREG(ce->ce_mode))
return ce->ce_mode;
return create_ce_mode(0666);
diff --git a/repo-settings.h b/repo-settings.h
index cad9c3f0cc..a12e763f4f 100644
--- a/repo-settings.h
+++ b/repo-settings.h
@@ -48,7 +48,10 @@ struct repo_settings {
* replace_refs_enabled() for more details.
*/
int read_replace_refs;
-
+
+ /* Whether to trust executable bit on filesystem (core.filemode) */
+ int trust_executable_bit;
+
struct fsmonitor_settings *fsmonitor; /* lazily loaded */
int index_version;
@@ -74,6 +77,7 @@ struct repo_settings {
#define REPO_SETTINGS_INIT { \
.shared_repository = -1, \
.index_version = -1, \
+ .trust_executable_bit = 1, \
.core_untracked_cache = UNTRACKED_CACHE_KEEP, \
.fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \
.warn_ambiguous_refs = -1, \
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting 2026-03-01 18:59 [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting drona @ 2026-03-06 18:02 ` Tian Yuchen 2026-03-08 18:24 ` [PATCH] Make 'trust_executable_bit' repository-scoped drona ` (2 subsequent siblings) 3 siblings, 0 replies; 11+ messages in thread From: Tian Yuchen @ 2026-03-06 18:02 UTC (permalink / raw) To: drona, git Hi drona, On 3/2/26 02:59, drona wrote: > This patch moves 'trust_executable_bit' into 'struct repo_settings', making > it a repository-scoped configuration. All references in files have been updated to use > 'the_repository->settings.trust_executable_bit'. The original intent of this patch should be sound. > Why this is a good candidate: > - It's a self-contained global variable that only affects file mode logic. > - Low risk: changes only impact mode calculations and related apply/update > operations. > - Makes Git codebase more maintainable and prepares for future multi-repo > support. > > - Manual sanity check with a test repo confirms executable bits behave correctly. > > Signed-off-by: Dorna Raj Gyawali <dronarajgyawali@gmail.com> > --- > apply.c | 4 ++-- > builtin/update-index.c | 2 +- > diff-lib.c | 10 +++++----- > environment.c | 3 +-- > environment.h | 1 - > read-cache.c | 10 +++++----- > read-cache.h | 11 +++++++---- > repo-settings.h | 6 +++++- > 8 files changed, 26 insertions(+), 21 deletions(-) > > diff --git a/apply.c b/apply.c > index d044c95d50..2bcb22a4bc 100644 > --- a/apply.c > +++ b/apply.c > @@ -3838,8 +3838,8 @@ static int check_preimage(struct apply_state *state, > if (*ce && !(*ce)->ce_mode) > BUG("ce_mode == 0 for path '%s'", old_name); > > - if (trust_executable_bit || !S_ISREG(st->st_mode)) > - st_mode = ce_mode_from_stat(*ce, st->st_mode); > + if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) > + st_mode = ce_mode_from_stat(the_repository, *ce, st->st_mode); > else if (*ce) > st_mode = (*ce)->ce_mode; > else You can run git diff --check before committing. There's an extra space here. > diff --git a/builtin/update-index.c b/builtin/update-index.c > index 8a5907767b..7917bd286f 100644 > --- a/builtin/update-index.c > +++ b/builtin/update-index.c > @@ -293,7 +293,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len > ce->ce_flags = create_ce_flags(0); > ce->ce_namelen = len; > fill_stat_cache_info(the_repository->index, ce, st); > - ce->ce_mode = ce_mode_from_stat(old, st->st_mode); > + ce->ce_mode = ce_mode_from_stat(the_repository, old, st->st_mode); > > if (index_path(the_repository->index, &ce->oid, path, st, > info_only ? 0 : INDEX_WRITE_OBJECT)) { > diff --git a/diff-lib.c b/diff-lib.c > index ae91027a02..894358c8b0 100644 > --- a/diff-lib.c > +++ b/diff-lib.c > @@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) > > changed = check_removed(ce, &st); > if (!changed) > - wt_mode = ce_mode_from_stat(ce, st.st_mode); > + wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode); > else { > if (changed < 0) { > perror(ce->name); > @@ -193,7 +193,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) > num_compare_stages++; > oidcpy(&dpath->parent[stage - 2].oid, > &nce->oid); > - dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode); > + dpath->parent[stage-2].mode = ce_mode_from_stat(the_repository,nce, mode); > dpath->parent[stage-2].status = > DIFF_STATUS_MODIFIED; > } > @@ -262,7 +262,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) > continue; > } else if (revs->diffopt.ita_invisible_in_index && > ce_intent_to_add(ce)) { > - newmode = ce_mode_from_stat(ce, st.st_mode); > + newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); > diff_addremove(&revs->diffopt, '+', newmode, > null_oid(the_hash_algo), 0, ce->name, 0); > continue; > @@ -270,7 +270,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) > > changed = match_stat_with_submodule(&revs->diffopt, ce, &st, > ce_option, &dirty_submodule); > - newmode = ce_mode_from_stat(ce, st.st_mode); > + newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); > } > > if (!changed && !dirty_submodule) { > @@ -338,7 +338,7 @@ static int get_stat_data(const struct cache_entry *ce, > changed = match_stat_with_submodule(diffopt, ce, &st, > 0, dirty_submodule); > if (changed) { > - mode = ce_mode_from_stat(ce, st.st_mode); > + mode = ce_mode_from_stat(the_repository, ce, st.st_mode); > oid = null_oid(the_hash_algo); > } > } > diff --git a/environment.c b/environment.c > index 0026eb2274..861ef084dc 100644 > --- a/environment.c > +++ b/environment.c > @@ -41,7 +41,6 @@ > static int pack_compression_seen; > static int zlib_compression_seen; > > -int trust_executable_bit = 1; > int trust_ctime = 1; > int check_stat = 1; > int has_symlinks = 1; But the_repository itself is a global variable, isn't it? If you understand what “removing global variables” means, you should grasp the direction we're heading: passing global variables -> passing context For example, in > @@ -160,7 +160,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) > > changed = check_removed(ce, &st); > if (!changed) > - wt_mode = ce_mode_from_stat(ce, st.st_mode); > + wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode); perror(ce->name); A more appropriate of passing value could be something like: wt_mode = ce_mode_from_stat(revs->repo, ce, st.st_mode) > @@ -306,7 +305,7 @@ int git_default_core_config(const char *var, const char *value, > { > /* This needs a better name */ > if (!strcmp(var, "core.filemode")) { > - trust_executable_bit = git_config_bool(var, value); > + the_repository->settings.trust_executable_bit = git_config_bool(var, value); > return 0; > } > if (!strcmp(var, "core.trustctime")) { I didn't think it through, but my gut tells me there might be some weird variable overwriting issues here. But more importantly, I feel that the changes here somewhat undermine lazy loading behavior. Variables in repo_settings are lazy-loaded, meaning you cannot read their values via actions like repo->settings.trust_executable_bit because they are not loaded until needed. The function prepare_repo_settings(repo) should be called to load the values. However, the change here appears to manually assign a value during the global config parsing phase. I believe this is incorrect. For more information you can look through https://lore.kernel.org/all/48821a3848bef25c13038be8377ad73e7c17a924.1771258573.git.belkid98@gmail.com/ Regards, Yuchen ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] Make 'trust_executable_bit' repository-scoped 2026-03-01 18:59 [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting drona 2026-03-06 18:02 ` Tian Yuchen @ 2026-03-08 18:24 ` drona 2026-03-08 18:34 ` [PATCH] [PATCH v2] " drona 2026-03-08 18:37 ` drona 3 siblings, 0 replies; 11+ messages in thread From: drona @ 2026-03-08 18:24 UTC (permalink / raw) To: git; +Cc: Dorna Raj Gyawali From: Dorna Raj Gyawali <dronarajgyawali@gmail.com> - Moved 'trust_executable_bit' from a global variable to struct repo_settings. - Updated all calls to ce_mode_from_stat() to pass the repository. - Updated environment.c to set the repository's trust_executable_bit when reading core.filemode. - Fixed apply.c, update-index.c, diff-lib.c, and read-cache.c to reference the_repository->settings.trust_executable_bit. - Added prepare_repo_settings() call in diff-lib.c to ensure repo settings are loaded. This change makes executable-bit handling repository-scoped and prepares the code for multi-repo support. Signed-off-by: Dorna Raj Gyawali <dronarajgyawali@gmail.com> --- apply.c | 2 +- diff-lib.c | 9 +++++---- environment.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apply.c b/apply.c index f9fd7b0030..1677ddca15 100644 --- a/apply.c +++ b/apply.c @@ -3838,7 +3838,7 @@ static int check_preimage(struct apply_state *state, if (*ce && !(*ce)->ce_mode) BUG("ce_mode == 0 for path '%s'", old_name); - if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) + if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) st_mode = ce_mode_from_stat(the_repository, *ce, st->st_mode); else if (*ce) st_mode = (*ce)->ce_mode; diff --git a/diff-lib.c b/diff-lib.c index 894358c8b0..276efef407 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -108,6 +108,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt, void run_diff_files(struct rev_info *revs, unsigned int option) { + prepare_repo_settings(revs->repo); int entries, i; int diff_unmerged_stage = revs->max_count; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) @@ -160,7 +161,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = check_removed(ce, &st); if (!changed) - wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode); + wt_mode = ce_mode_from_stat(revs->repo, ce, st.st_mode); else { if (changed < 0) { perror(ce->name); @@ -193,7 +194,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) num_compare_stages++; oidcpy(&dpath->parent[stage - 2].oid, &nce->oid); - dpath->parent[stage-2].mode = ce_mode_from_stat(the_repository,nce, mode); + dpath->parent[stage-2].mode = ce_mode_from_stat(revs->repo, nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } @@ -262,7 +263,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) continue; } else if (revs->diffopt.ita_invisible_in_index && ce_intent_to_add(ce)) { - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); diff_addremove(&revs->diffopt, '+', newmode, null_oid(the_hash_algo), 0, ce->name, 0); continue; @@ -270,7 +271,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = match_stat_with_submodule(&revs->diffopt, ce, &st, ce_option, &dirty_submodule); - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); } if (!changed && !dirty_submodule) { diff --git a/environment.c b/environment.c index 591683ce8c..9d12c5fa56 100644 --- a/environment.c +++ b/environment.c @@ -304,6 +304,7 @@ int git_default_core_config(const char *var, const char *value, /* This needs a better name */ if (!strcmp(var, "core.filemode")) { + prepare_repo_settings(the_repository); the_repository->settings.trust_executable_bit = git_config_bool(var, value); return 0; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-01 18:59 [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting drona 2026-03-06 18:02 ` Tian Yuchen 2026-03-08 18:24 ` [PATCH] Make 'trust_executable_bit' repository-scoped drona @ 2026-03-08 18:34 ` drona 2026-03-08 18:37 ` drona 3 siblings, 0 replies; 11+ messages in thread From: drona @ 2026-03-08 18:34 UTC (permalink / raw) To: git; +Cc: 24f40e5a-a5fd-49ec-86e7-921b44e4abd9, Dorna Raj Gyawali From: Dorna Raj Gyawali <dronarajgyawali@gmail.com> - Moved 'trust_executable_bit' from a global variable to struct repo_settings. - Updated all calls to ce_mode_from_stat() to pass the repository. - Updated environment.c to set the repository's trust_executable_bit when reading core.filemode. - Fixed apply.c, update-index.c, diff-lib.c, and read-cache.c to reference the_repository->settings.trust_executable_bit. - Added prepare_repo_settings() call in diff-lib.c to ensure repo settings are loaded. This change makes executable-bit handling repository-scoped and prepares the code for multi-repo support. Signed-off-by: Dorna Raj Gyawali <dronarajgyawali@gmail.com> --- apply.c | 2 +- diff-lib.c | 9 +++++---- environment.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apply.c b/apply.c index f9fd7b0030..1677ddca15 100644 --- a/apply.c +++ b/apply.c @@ -3838,7 +3838,7 @@ static int check_preimage(struct apply_state *state, if (*ce && !(*ce)->ce_mode) BUG("ce_mode == 0 for path '%s'", old_name); - if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) + if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) st_mode = ce_mode_from_stat(the_repository, *ce, st->st_mode); else if (*ce) st_mode = (*ce)->ce_mode; diff --git a/diff-lib.c b/diff-lib.c index 894358c8b0..276efef407 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -108,6 +108,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt, void run_diff_files(struct rev_info *revs, unsigned int option) { + prepare_repo_settings(revs->repo); int entries, i; int diff_unmerged_stage = revs->max_count; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) @@ -160,7 +161,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = check_removed(ce, &st); if (!changed) - wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode); + wt_mode = ce_mode_from_stat(revs->repo, ce, st.st_mode); else { if (changed < 0) { perror(ce->name); @@ -193,7 +194,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) num_compare_stages++; oidcpy(&dpath->parent[stage - 2].oid, &nce->oid); - dpath->parent[stage-2].mode = ce_mode_from_stat(the_repository,nce, mode); + dpath->parent[stage-2].mode = ce_mode_from_stat(revs->repo, nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } @@ -262,7 +263,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) continue; } else if (revs->diffopt.ita_invisible_in_index && ce_intent_to_add(ce)) { - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); diff_addremove(&revs->diffopt, '+', newmode, null_oid(the_hash_algo), 0, ce->name, 0); continue; @@ -270,7 +271,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = match_stat_with_submodule(&revs->diffopt, ce, &st, ce_option, &dirty_submodule); - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); } if (!changed && !dirty_submodule) { diff --git a/environment.c b/environment.c index 591683ce8c..9d12c5fa56 100644 --- a/environment.c +++ b/environment.c @@ -304,6 +304,7 @@ int git_default_core_config(const char *var, const char *value, /* This needs a better name */ if (!strcmp(var, "core.filemode")) { + prepare_repo_settings(the_repository); the_repository->settings.trust_executable_bit = git_config_bool(var, value); return 0; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-01 18:59 [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting drona ` (2 preceding siblings ...) 2026-03-08 18:34 ` [PATCH] [PATCH v2] " drona @ 2026-03-08 18:37 ` drona [not found] ` <f03d40072ab106d1a0a7852718d42f56@purelymail.com> 3 siblings, 1 reply; 11+ messages in thread From: drona @ 2026-03-08 18:37 UTC (permalink / raw) To: git; +Cc: 24f40e5a-a5fd-49ec-86e7-921b44e4abd9, Dorna Raj Gyawali From: Dorna Raj Gyawali <dronarajgyawali@gmail.com> - Moved 'trust_executable_bit' from a global variable to struct repo_settings. - Updated all calls to ce_mode_from_stat() to pass the repository. - Updated environment.c to set the repository's trust_executable_bit when reading core.filemode. - Fixed apply.c, update-index.c, diff-lib.c, and read-cache.c to reference the_repository->settings.trust_executable_bit. - Added prepare_repo_settings() call in diff-lib.c to ensure repo settings are loaded. This change makes executable-bit handling repository-scoped and prepares the code for multi-repo support. Signed-off-by: Dorna Raj Gyawali <dronarajgyawali@gmail.com> --- apply.c | 2 +- diff-lib.c | 9 +++++---- environment.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apply.c b/apply.c index f9fd7b0030..1677ddca15 100644 --- a/apply.c +++ b/apply.c @@ -3838,7 +3838,7 @@ static int check_preimage(struct apply_state *state, if (*ce && !(*ce)->ce_mode) BUG("ce_mode == 0 for path '%s'", old_name); - if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) + if (the_repository->settings.trust_executable_bit || !S_ISREG(st->st_mode)) st_mode = ce_mode_from_stat(the_repository, *ce, st->st_mode); else if (*ce) st_mode = (*ce)->ce_mode; diff --git a/diff-lib.c b/diff-lib.c index 894358c8b0..276efef407 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -108,6 +108,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt, void run_diff_files(struct rev_info *revs, unsigned int option) { + prepare_repo_settings(revs->repo); int entries, i; int diff_unmerged_stage = revs->max_count; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) @@ -160,7 +161,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = check_removed(ce, &st); if (!changed) - wt_mode = ce_mode_from_stat(the_repository, ce, st.st_mode); + wt_mode = ce_mode_from_stat(revs->repo, ce, st.st_mode); else { if (changed < 0) { perror(ce->name); @@ -193,7 +194,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) num_compare_stages++; oidcpy(&dpath->parent[stage - 2].oid, &nce->oid); - dpath->parent[stage-2].mode = ce_mode_from_stat(the_repository,nce, mode); + dpath->parent[stage-2].mode = ce_mode_from_stat(revs->repo, nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } @@ -262,7 +263,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) continue; } else if (revs->diffopt.ita_invisible_in_index && ce_intent_to_add(ce)) { - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); diff_addremove(&revs->diffopt, '+', newmode, null_oid(the_hash_algo), 0, ce->name, 0); continue; @@ -270,7 +271,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option) changed = match_stat_with_submodule(&revs->diffopt, ce, &st, ce_option, &dirty_submodule); - newmode = ce_mode_from_stat(the_repository, ce, st.st_mode); + newmode = ce_mode_from_stat(revs->repo, ce, st.st_mode); } if (!changed && !dirty_submodule) { diff --git a/environment.c b/environment.c index 591683ce8c..9d12c5fa56 100644 --- a/environment.c +++ b/environment.c @@ -304,6 +304,7 @@ int git_default_core_config(const char *var, const char *value, /* This needs a better name */ if (!strcmp(var, "core.filemode")) { + prepare_repo_settings(the_repository); the_repository->settings.trust_executable_bit = git_config_bool(var, value); return 0; } -- 2.43.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
[parent not found: <f03d40072ab106d1a0a7852718d42f56@purelymail.com>]
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped [not found] ` <f03d40072ab106d1a0a7852718d42f56@purelymail.com> @ 2026-03-09 7:13 ` cat 2026-03-09 13:33 ` Dronaraj Gyawali 2026-03-09 15:07 ` Junio C Hamano 0 siblings, 2 replies; 11+ messages in thread From: cat @ 2026-03-09 7:13 UTC (permalink / raw) To: drona; +Cc: Junio C Hamano, Git > Hi drona, > > Thanks for the update! Just a quick heads-up: it looks like > you forgot to CC Junio (gitster@pobox.com) on this iteration. > Additionally, I think it's a good practice to respond to > reviews before sending new patches. What do you think? > >> if (!strcmp(var, "core.filemode")) { >> + prepare_repo_settings(the_repository); >> the_repository->settings.trust_executable_bit = >> git_config_bool(var, value); >> return 0; >> } > > Regarding the code, calling 'prepare_repo_settings()' inside > 'git_default_core_config()' defeats the purpose of lazy-loading, > doesn't it? > > if (!strcmp(var, "core.filemode")) { > prepare_repo_settings(the_repository); > the_repository->settings.trust_executable_bit = git_config_bool(var, > value); > return 0; > } > > I think the standard practice is to drop the variable from > 'environment.c' completely and read it directly inside > 'repo-settings.c: prepare_repo_settings()' using > 'repo_config_get_bool()'. > > Regards, > > Yuchen I accidentally clicked the wrong option and didn't select Reply All. I'll CC Junio on this message. Regards, Yuchen ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-09 7:13 ` cat @ 2026-03-09 13:33 ` Dronaraj Gyawali 2026-03-09 16:23 ` Tian Yuchen 2026-03-09 15:07 ` Junio C Hamano 1 sibling, 1 reply; 11+ messages in thread From: Dronaraj Gyawali @ 2026-03-09 13:33 UTC (permalink / raw) To: cat; +Cc: Junio C Hamano, Git Hi Yuchen, Thanks for the review and for pointing that out. You're right that calling prepare_repo_settings() inside git_default_core_config() defeats the purpose of lazy loading. I'll update the patch accordingly by removing the handling from environment.c and reading core.filemode directly in repo-settings.c using repo_config_get_bool(). Also, I'm new to contributing to Git, so thank you for the guidance and patience while I learn. Thanks again for the help. Regards, Drona ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-09 13:33 ` Dronaraj Gyawali @ 2026-03-09 16:23 ` Tian Yuchen 2026-03-09 22:03 ` Junio C Hamano 0 siblings, 1 reply; 11+ messages in thread From: Tian Yuchen @ 2026-03-09 16:23 UTC (permalink / raw) To: Dronaraj Gyawali; +Cc: Junio C Hamano, Git Hi drona, Junio C Hamano <gitster@pobox.com> writes: > There were discussions on pros and cons moving global recipients of > configuration values into a dynamically allocated strucrure... > and excellent pieces of advice have been given by Phillip Wood. > If anything, a change like this should ask for input from him. That makes sense. I think you should CC him whenever you've thoroughly polished the patch or when you encounter unresolved issues. > This "v2" applies to a mythical codebase where trust_executable_bit > is somehow a member in the settings structure, which I do not think > we have. Given Junio's observation, it seems this iteration is targeting an incorrect or non-existent codebase structure. I'll hold off on further reviews of the specific implementation details until the base codebase issue is sorted out and the structural design (incorporating Phillip's previous advice) is settled. Looking forward to the updated version! Thanks, Yuchen ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-09 16:23 ` Tian Yuchen @ 2026-03-09 22:03 ` Junio C Hamano 0 siblings, 0 replies; 11+ messages in thread From: Junio C Hamano @ 2026-03-09 22:03 UTC (permalink / raw) To: Tian Yuchen; +Cc: Dronaraj Gyawali, Git Tian Yuchen <cat@malon.dev> writes: > Hi drona, > > Junio C Hamano <gitster@pobox.com> writes: > > > There were discussions on pros and cons moving global recipients of > > configuration values into a dynamically allocated strucrure... > > and excellent pieces of advice have been given by Phillip Wood. > > If anything, a change like this should ask for input from him. > > That makes sense. I think you should CC him whenever you've thoroughly > polished the patch or when you encounter unresolved issues. > > > This "v2" applies to a mythical codebase where trust_executable_bit > > is somehow a member in the settings structure, which I do not think > > we have. > > Given Junio's observation, it seems this iteration is targeting an > incorrect or non-existent codebase structure. > > I'll hold off on further reviews of the specific implementation details > until the base codebase issue is sorted out and the structural design > (incorporating Phillip's previous advice) is settled. I think what the author called v2 was actually [2/N] where the previous version was treated as [1/N] of the same series. The line I noticed was strange in my response is probably correcting what the previous one did, which is not what we want to see. It probably is similar to https://lore.kernel.org/git/xmqqh5qxzzzn.fsf@gitster.g/ We prefer the patch authors to pretend to be a perfect developer who never made any mistakes while writing their series. This unfortunately is a recurring theme among new developers. https://lore.kernel.org/git/xmqqk29bsz2o.fsf@gitster.mtv.corp.google.com/ https://lore.kernel.org/git/xmqqd0ds5ysq.fsf@gitster-ct.c.googlers.com/ https://lore.kernel.org/git/xmqqr173faez.fsf@gitster.g/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-09 7:13 ` cat 2026-03-09 13:33 ` Dronaraj Gyawali @ 2026-03-09 15:07 ` Junio C Hamano 2026-03-09 17:51 ` Dronaraj Gyawali 1 sibling, 1 reply; 11+ messages in thread From: Junio C Hamano @ 2026-03-09 15:07 UTC (permalink / raw) To: cat; +Cc: drona, Git cat@malon.dev writes: >> Hi drona, >> >> Thanks for the update! Just a quick heads-up: it looks like >> you forgot to CC Junio (gitster@pobox.com) on this iteration. No strong need to Cc the maintainer when the patch is not ready to be applied, even though it may be nice. I'll be seeing it either way as I rarely look at my mailbox and use the mailing list archive at lore.kernel.org my primary source of Git patches anyway. There were discussions on pros and cons moving global recipients of configuration values into a dynamically allocated strucrure, which can change when they are parsed and when bad values in them result in warnings, depending on the way the change is done, and excellent pieces of advice have been given by Phillip Wood. If anything, a change like this should ask for input from him. >> Additionally, I think it's a good practice to respond to >> reviews before sending new patches. Absolutely. >>> if (!strcmp(var, "core.filemode")) { >>> + prepare_repo_settings(the_repository); >>> the_repository->settings.trust_executable_bit = >>> git_config_bool(var, value); >>> return 0; >>> } >> >> Regarding the code, calling 'prepare_repo_settings()' inside >> 'git_default_core_config()' defeats the purpose of lazy-loading, >> doesn't it? >> >> if (!strcmp(var, "core.filemode")) { >> prepare_repo_settings(the_repository); >> the_repository->settings.trust_executable_bit = git_config_bool(var, >> value); >> return 0; >> } >> >> I think the standard practice is to drop the variable from >> 'environment.c' completely and read it directly inside >> 'repo-settings.c: prepare_repo_settings()' using >> 'repo_config_get_bool()'. This "v2" applies to a mythical codebase where trust_executable_bit is somehow a member in the settings structure, which I do not think we have. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] Make 'trust_executable_bit' repository-scoped 2026-03-09 15:07 ` Junio C Hamano @ 2026-03-09 17:51 ` Dronaraj Gyawali 0 siblings, 0 replies; 11+ messages in thread From: Dronaraj Gyawali @ 2026-03-09 17:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: cat, Git Hi Junio, I have sent a new updated series of changes that aligns with the actual code structure. There was some confusion regarding work flow by my side. I am still learning.. Thanks for earlier review and guidance. Best regards, dorna On Mon, 9 Mar 2026 at 20:52, Junio C Hamano <gitster@pobox.com> wrote: > > cat@malon.dev writes: > > >> Hi drona, > >> > >> Thanks for the update! Just a quick heads-up: it looks like > >> you forgot to CC Junio (gitster@pobox.com) on this iteration. > > No strong need to Cc the maintainer when the patch is not ready to > be applied, even though it may be nice. I'll be seeing it either > way as I rarely look at my mailbox and use the mailing list archive > at lore.kernel.org my primary source of Git patches anyway. > > There were discussions on pros and cons moving global recipients of > configuration values into a dynamically allocated strucrure, which > can change when they are parsed and when bad values in them result > in warnings, depending on the way the change is done, and excellent > pieces of advice have been given by Phillip Wood. If anything, a > change like this should ask for input from him. > > >> Additionally, I think it's a good practice to respond to > >> reviews before sending new patches. > > Absolutely. > > >>> if (!strcmp(var, "core.filemode")) { > >>> + prepare_repo_settings(the_repository); > >>> the_repository->settings.trust_executable_bit = > >>> git_config_bool(var, value); > >>> return 0; > >>> } > >> > >> Regarding the code, calling 'prepare_repo_settings()' inside > >> 'git_default_core_config()' defeats the purpose of lazy-loading, > >> doesn't it? > >> > >> if (!strcmp(var, "core.filemode")) { > >> prepare_repo_settings(the_repository); > >> the_repository->settings.trust_executable_bit = git_config_bool(var, > >> value); > >> return 0; > >> } > >> > >> I think the standard practice is to drop the variable from > >> 'environment.c' completely and read it directly inside > >> 'repo-settings.c: prepare_repo_settings()' using > >> 'repo_config_get_bool()'. > > This "v2" applies to a mythical codebase where trust_executable_bit > is somehow a member in the settings structure, which I do not think > we have. > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-03-09 22:03 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-01 18:59 [PATCH] Refactor 'trust_executable_bit' to repository-scoped setting drona
2026-03-06 18:02 ` Tian Yuchen
2026-03-08 18:24 ` [PATCH] Make 'trust_executable_bit' repository-scoped drona
2026-03-08 18:34 ` [PATCH] [PATCH v2] " drona
2026-03-08 18:37 ` drona
[not found] ` <f03d40072ab106d1a0a7852718d42f56@purelymail.com>
2026-03-09 7:13 ` cat
2026-03-09 13:33 ` Dronaraj Gyawali
2026-03-09 16:23 ` Tian Yuchen
2026-03-09 22:03 ` Junio C Hamano
2026-03-09 15:07 ` Junio C Hamano
2026-03-09 17:51 ` Dronaraj Gyawali
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox