]> git.ipfire.org Git - thirdparty/git.git/commitdiff
read-cache: pass 'repo' to 'ce_mode_from_stat()'
authorTian Yuchen <cat@malon.dev>
Mon, 20 Jul 2026 10:53:33 +0000 (18:53 +0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Jul 2026 14:37:05 +0000 (07:37 -0700)
The ce_mode_from_stat() function is a performance-critical static
inline helper in 'read-cache.h'. As we migrate configuration
variables into the repository struct, this helper needs access
to the repository context.

Update the signature of ce_mode_from_stat() to take a 'struct
repository *' parameter, and update all callers to pass the
appropriate repository instance.

To prepare for the overhead of replacing cheap global variable
accesses with getter functions, the boolean expressions are
reordered to evaluate 'S_ISREG(mode)' first.

While at it, add a comment for ce_mode_from_stat().

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>
apply.c
builtin/update-index.c
diff-lib.c
read-cache.c
read-cache.h

diff --git a/apply.c b/apply.c
index 249248d4f205ca5f5121487573d30f4ed0011b9d..26286eb57b4f52bbd3b9955071c0d52fe2c7dda0 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -3894,7 +3894,7 @@ static int check_preimage(struct apply_state *state,
                        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);
+                       st_mode = ce_mode_from_stat(state->repo, *ce, st->st_mode);
                else if (*ce)
                        st_mode = (*ce)->ce_mode;
                else
index 3d6646c318b98e806a0aba09c3f034b133dc582c..afd672a9145b4f954a7d93b6cc7bef9528981e0c 100644 (file)
@@ -294,7 +294,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)) {
index ae91027a024eece23f0f1ede20467eeb425a2b3b..46cae637ecda839ffefe417df8e13279ca72bb47 100644 (file)
@@ -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(revs->repo, 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, 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(revs->repo, 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, 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(diffopt->repo, ce, st.st_mode);
                        oid = null_oid(the_hash_algo);
                }
        }
index 1ced8c630ef637340f3063ae06bd2aa1f0d894bf..a9f059174305eb402540f8b67bf105783395c09f 100644 (file)
@@ -750,7 +750,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->repo, ent, st_mode);
        }
 
        /* When core.ignorecase=true, determine if a directory of the same name but differing
index 043da1f1aae706746ea46544a9dfbf0fae6c8f55..af8c657ecbeb48e8c520ba5bd062b7d7bd895d73 100644 (file)
@@ -4,15 +4,24 @@
 #include "read-cache-ll.h"
 #include "object.h"
 #include "pathspec.h"
+#include "environment.h"
 
-static inline unsigned int ce_mode_from_stat(const struct cache_entry *ce,
+/*
+ * Determine the appropriate index mode for a file based on its stat()
+ * information and the existing cache entry (if any).
+ *
+ * This function handles degradation for filesystems that lack
+ * symlink support or reliable executable bits.
+ */
+static inline unsigned int ce_mode_from_stat(struct repository *repo UNUSED,
+                                            const struct cache_entry *ce,
                                             unsigned int mode)
 {
        extern int trust_executable_bit, has_symlinks;
-       if (!has_symlinks && S_ISREG(mode) &&
+       if (S_ISREG(mode) && !has_symlinks &&
            ce && S_ISLNK(ce->ce_mode))
                return ce->ce_mode;
-       if (!trust_executable_bit && S_ISREG(mode)) {
+       if (S_ISREG(mode) && !trust_executable_bit) {
                if (ce && S_ISREG(ce->ce_mode))
                        return ce->ce_mode;
                return create_ce_mode(0666);