path: root/read-cache.c
diff options
authorLinus Torvalds <>2008-05-09 16:11:43 (GMT)
committerJunio C Hamano <>2008-05-11 01:16:30 (GMT)
commitd177cab0480f9fa172103071203fed1bff95f5c2 (patch)
treeb864a5d65713a74315730aa4222f44bf1149ce06 /read-cache.c
parent2855e70ad11abf7e7f30f975b063bd60d5abdf4f (diff)
Avoid some unnecessary lstat() calls
The commit sequence used to do if (file_exists(p->path)) add_file_to_cache(p->path, 0); where both "file_exists()" and "add_file_to_cache()" needed to do a lstat() on the path to do their work. This cuts down 'lstat()' calls for the partial commit case by two for each path we know about (because we do this twice per path). Just move the lstat() to the caller instead (that's all that "file_exists()" really does), and pass the stat information down to the add_to_cache() function. This essentially makes 'add_to_index()' the core function that adds a path to the index, getting the index pointer, the pathname and the stat information as arguments. There are then shorthand helper functions that use this core function: - 'add_to_cache()' is just 'add_to_index()' with the default index - 'add_file_to_cache/index()' is the same, but does the lstat() call itself, so you can pass just the pathname if you don't already have the stat information available. So old users of the 'add_file_to_xyzzy()' are essentially left unchanged, and this just exposes the more generic helper function that can take existing stat information into account. Signed-off-by: Linus Torvalds <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'read-cache.c')
1 files changed, 17 insertions, 12 deletions
diff --git a/read-cache.c b/read-cache.c
index 4525f8a..0382804 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -462,21 +462,18 @@ static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_
return new;
-int add_file_to_index(struct index_state *istate, const char *path, int verbose)
+int add_to_index(struct index_state *istate, const char *path, struct stat *st, int verbose)
int size, namelen;
- struct stat st;
+ mode_t st_mode = st->st_mode;
struct cache_entry *ce, *alias;
- if (lstat(path, &st))
- die("%s: unable to stat (%s)", path, strerror(errno));
- if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
+ if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
die("%s: can only add regular files, symbolic links or git-directories", path);
namelen = strlen(path);
- if (S_ISDIR(st.st_mode)) {
+ if (S_ISDIR(st_mode)) {
while (namelen && path[namelen-1] == '/')
@@ -484,10 +481,10 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
ce = xcalloc(1, size);
memcpy(ce->name, path, namelen);
ce->ce_flags = namelen;
- fill_stat_cache_info(ce, &st);
+ fill_stat_cache_info(ce, st);
if (trust_executable_bit && has_symlinks)
- ce->ce_mode = create_ce_mode(st.st_mode);
+ ce->ce_mode = create_ce_mode(st_mode);
else {
/* If there is an existing entry, pick the mode bits and type
* from it, otherwise assume unexecutable regular file.
@@ -496,18 +493,18 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
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.st_mode);
+ ce->ce_mode = ce_mode_from_stat(ent, st_mode);
alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
- if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, &st, ce_option)) {
+ if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
/* Nothing changed, really */
alias->ce_flags |= CE_ADDED;
return 0;
- if (index_path(ce->sha1, path, &st, 1))
+ if (index_path(ce->sha1, path, st, 1))
die("unable to index file %s", path);
if (ignore_case && alias && different_name(ce, alias))
ce = create_alias_ce(ce, alias);
@@ -519,6 +516,14 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
return 0;
+int add_file_to_index(struct index_state *istate, const char *path, int verbose)
+ struct stat st;
+ if (lstat(path, &st))
+ die("%s: unable to stat (%s)", path, strerror(errno));
+ return add_to_index(istate, path, &st, verbose);
struct cache_entry *make_cache_entry(unsigned int mode,
const unsigned char *sha1, const char *path, int stage,
int refresh)