From: Tian Yuchen <cat@malon.dev>
To: git@vger.kernel.org
Cc: christian.couder@gmail.com, ps@pks.im,
Tian Yuchen <cat@malon.dev>,
Ayush Chandekar <ayu.chandekar@gmail.com>,
Olamide Caleb Bello <belkid98@gmail.com>
Subject: [PATCH v1 4/4] read-cache: pass 'istate' to stat/mode helper functions
Date: Sun, 31 May 2026 00:05:19 +0800 [thread overview]
Message-ID: <20260530160520.77859-5-cat@malon.dev> (raw)
In-Reply-To: <20260530160520.77859-1-cat@malon.dev>
In the previous commit, the gloabl 'trust_executable_bit' was
migrated into 'repo_config_values', but low-level helpers in
read-cache.c still relied on 'the_repository' to access it.
Refactor the signatures of ce_mode_from_stat(), st_mode_from_ce(),
fake_lstat(), and check_removed() to accept a 'struct
index_state *istate'. This allows these functions to retrieve the
repository context via 'istate->repo'.
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>
---
apply.c | 4 ++--
builtin/update-index.c | 2 +-
diff-lib.c | 20 ++++++++++----------
read-cache-ll.h | 2 +-
read-cache.c | 31 +++++++++++++++++++------------
read-cache.h | 3 ++-
6 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/apply.c b/apply.c
index 73ca9907f8..a81bb29a6f 100644
--- a/apply.c
+++ b/apply.c
@@ -3890,13 +3890,13 @@ static int check_preimage(struct apply_state *state,
}
if (!state->cached && !previous) {
- struct repo_config_values *cfg = repo_config_values(the_repository);
+ struct repo_config_values *cfg = repo_config_values(state->repo);
if (*ce && !(*ce)->ce_mode)
BUG("ce_mode == 0 for path '%s'", old_name);
if (cfg->trust_executable_bit || !S_ISREG(st->st_mode))
- st_mode = ce_mode_from_stat(*ce, st->st_mode);
+ st_mode = ce_mode_from_stat(state->repo->index, *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..3f6967bd84 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->index, 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..95fd3ba4b9 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -39,14 +39,14 @@
* exists for ce that is a submodule -- it is a submodule that is not
* checked out). Return negative for an error.
*/
-static int check_removed(const struct cache_entry *ce, struct stat *st)
+static int check_removed(struct index_state *istate, const struct cache_entry *ce, struct stat *st)
{
int stat_err;
if (!(ce->ce_flags & CE_FSMONITOR_VALID))
stat_err = lstat(ce->name, st);
else
- stat_err = fake_lstat(ce, st);
+ stat_err = fake_lstat(istate, ce, st);
if (stat_err < 0) {
if (!is_missing_file_error(errno))
return -1;
@@ -158,9 +158,9 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
int num_compare_stages = 0;
struct stat st;
- changed = check_removed(ce, &st);
+ changed = check_removed(revs->repo->index, ce, &st);
if (!changed)
- wt_mode = ce_mode_from_stat(ce, st.st_mode);
+ wt_mode = ce_mode_from_stat(revs->repo->index, 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(revs->repo->index, nce, mode);
dpath->parent[stage-2].status =
DIFF_STATUS_MODIFIED;
}
@@ -249,7 +249,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
} else {
struct stat st;
- changed = check_removed(ce, &st);
+ changed = check_removed(revs->repo->index, ce, &st);
if (changed) {
if (changed < 0) {
perror(ce->name);
@@ -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(revs->repo->index, 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(revs->repo->index, ce, st.st_mode);
}
if (!changed && !dirty_submodule) {
@@ -324,7 +324,7 @@ static int get_stat_data(const struct cache_entry *ce,
if (!cached && !ce_uptodate(ce)) {
int changed;
struct stat st;
- changed = check_removed(ce, &st);
+ changed = check_removed(diffopt->repo->index, ce, &st);
if (changed < 0)
return -1;
else if (changed) {
@@ -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(diffopt->repo->index, ce, st.st_mode);
oid = null_oid(the_hash_algo);
}
}
diff --git a/read-cache-ll.h b/read-cache-ll.h
index 2c8b4b21b1..9fb9bedfbf 100644
--- a/read-cache-ll.h
+++ b/read-cache-ll.h
@@ -442,7 +442,7 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
* for lstat() for a tracked path that is known to be up-to-date via
* some out-of-line means (like fsmonitor).
*/
-int fake_lstat(const struct cache_entry *ce, struct stat *st);
+int fake_lstat(struct index_state *istate, const struct cache_entry *ce, struct stat *st);
#define REFRESH_REALLY (1 << 0) /* ignore_valid */
#define REFRESH_UNMERGED (1 << 1) /* allow unmerged */
diff --git a/read-cache.c b/read-cache.c
index 18af533649..28e7f24382 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -202,9 +202,12 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
}
}
-unsigned int ce_mode_from_stat(const struct cache_entry *ce, unsigned int mode)
+unsigned int ce_mode_from_stat(struct index_state *istate,
+ const struct cache_entry *ce,
+ unsigned int mode)
{
- struct repo_config_values *cfg = repo_config_values(the_repository);
+ struct repository *repo = (istate && istate->repo) ? istate->repo : the_repository;
+ struct repo_config_values *cfg = repo_config_values(repo);
if (!has_symlinks && S_ISREG(mode) &&
ce && S_ISLNK(ce->ce_mode))
@@ -217,9 +220,10 @@ unsigned int ce_mode_from_stat(const struct cache_entry *ce, unsigned int mode)
return create_ce_mode(mode);
}
-static unsigned int st_mode_from_ce(const struct cache_entry *ce)
+static unsigned int st_mode_from_ce(struct index_state *istate, const struct cache_entry *ce)
{
- struct repo_config_values *cfg = repo_config_values(the_repository);
+ struct repository *repo = (istate && istate->repo) ? istate->repo : the_repository;
+ struct repo_config_values *cfg = repo_config_values(repo);
switch (ce->ce_mode & S_IFMT) {
case S_IFLNK:
@@ -235,10 +239,10 @@ static unsigned int st_mode_from_ce(const struct cache_entry *ce)
}
}
-int fake_lstat(const struct cache_entry *ce, struct stat *st)
+int fake_lstat(struct index_state *istate, const struct cache_entry *ce, struct stat *st)
{
fake_lstat_data(&ce->ce_stat_data, st);
- st->st_mode = st_mode_from_ce(ce);
+ st->st_mode = st_mode_from_ce(istate, ce);
/* always succeed as lstat() replacement */
return 0;
@@ -322,10 +326,12 @@ static int ce_modified_check_fs(struct index_state *istate,
return 0;
}
-static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
+static int ce_match_stat_basic(struct index_state *istate,
+ const struct cache_entry *ce, struct stat *st)
{
unsigned int changed = 0;
- struct repo_config_values *cfg = repo_config_values(the_repository);
+ struct repository *repo = (istate && istate->repo) ? istate->repo : the_repository;
+ struct repo_config_values *cfg = repo_config_values(repo);
if (ce->ce_flags & CE_REMOVE)
return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED;
@@ -430,7 +436,7 @@ int ie_match_stat(struct index_state *istate,
if (ce_intent_to_add(ce))
return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED;
- changed = ce_match_stat_basic(ce, st);
+ changed = ce_match_stat_basic(istate, ce, st);
/*
* Within 1 second of this sequence:
@@ -737,7 +743,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
(intent_only ? ADD_CACHE_NEW_ONLY : 0));
unsigned hash_flags = pretend ? 0 : INDEX_WRITE_OBJECT;
- struct repo_config_values *cfg = repo_config_values(the_repository);
+ struct repository *repo = (istate && istate->repo) ? istate->repo : the_repository;
+ struct repo_config_values *cfg = repo_config_values(repo);
if (flags & ADD_CACHE_RENORMALIZE)
hash_flags |= INDEX_RENORMALIZE;
@@ -769,7 +776,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(istate, ent, st_mode);
}
/* When core.ignorecase=true, determine if a directory of the same name but differing
@@ -2592,7 +2599,7 @@ static void ce_smudge_racily_clean_entry(struct index_state *istate,
if (lstat(ce->name, &st) < 0)
return;
- if (ce_match_stat_basic(ce, &st))
+ if (ce_match_stat_basic(istate, ce, &st))
return;
if (ce_modified_check_fs(istate, ce, &st)) {
/* This is "racily clean"; smudge it. Note that this
diff --git a/read-cache.h b/read-cache.h
index 3c4af2faeb..61299ed95b 100644
--- a/read-cache.h
+++ b/read-cache.h
@@ -5,7 +5,8 @@
#include "object.h"
#include "pathspec.h"
-unsigned int ce_mode_from_stat(const struct cache_entry *ce,
+unsigned int ce_mode_from_stat(struct index_state *istate,
+ const struct cache_entry *ce,
unsigned int mode);
static inline int ce_to_dtype(const struct cache_entry *ce)
--
2.43.0
next prev parent reply other threads:[~2026-05-30 16:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 16:05 [PATCH v1 0/4] environment.c: migrate 'trust_executable_bit' into 'repo_config_values' Tian Yuchen
2026-05-30 16:05 ` [PATCH v1 1/4] read-cache: remove redundant extern declarations Tian Yuchen
2026-05-30 16:05 ` [PATCH v1 2/4] read-cache: move 'ce_mode_from_stat()' to 'read-cache.c' Tian Yuchen
2026-05-30 16:05 ` [PATCH v1 3/4] environment: move 'trust_executable_bit' into repo_config_values Tian Yuchen
2026-05-30 18:02 ` Christian Couder
2026-05-30 23:17 ` Junio C Hamano
2026-06-01 10:10 ` Tian Yuchen
2026-06-01 18:03 ` Tian Yuchen
2026-05-30 16:05 ` Tian Yuchen [this message]
2026-05-30 18:14 ` [PATCH v1 4/4] read-cache: pass 'istate' to stat/mode helper functions Christian Couder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260530160520.77859-5-cat@malon.dev \
--to=cat@malon.dev \
--cc=ayu.chandekar@gmail.com \
--cc=belkid98@gmail.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox