diff options
author | Junio C Hamano <gitster@pobox.com> | 2008-01-18 23:45:24 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-21 12:44:31 -0800 |
commit | eadb5831342bb2e756fa05c03642c4aa1929d4f5 (patch) | |
tree | 7ae11a8f2038467abe6ed4c9aef5294433da2955 /read-cache.c | |
parent | 7fec10b7f41fa32e71aa6377bd04cd7c6fb419e0 (diff) | |
download | git-eadb5831342bb2e756fa05c03642c4aa1929d4f5.tar.gz |
Avoid running lstat(2) on the same cache entry.
Aside from the lstat(2) done for work tree files, there are
quite many lstat(2) calls in refname dwimming codepath. This
patch is not about reducing them.
* It adds a new ce_flag, CE_UPTODATE, that is meant to mark the
cache entries that record a regular file blob that is up to
date in the work tree. If somebody later walks the index and
wants to see if the work tree has changes, they do not have
to be checked with lstat(2) again.
* fill_stat_cache_info() marks the cache entry it just added
with CE_UPTODATE. This has the effect of marking the paths
we write out of the index and lstat(2) immediately as "no
need to lstat -- we know it is up-to-date", from quite a lot
fo callers:
- git-apply --index
- git-update-index
- git-checkout-index
- git-add (uses add_file_to_index())
- git-commit (ditto)
- git-mv (ditto)
* refresh_cache_ent() also marks the cache entry that are clean
with CE_UPTODATE.
* write_index is changed not to write CE_UPTODATE out to the
index file, because CE_UPTODATE is meant to be transient only
in core. For the same reason, CE_UPDATE is not written to
prevent an accident from happening.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/read-cache.c b/read-cache.c index 528f697f59..8ba8f0f88f 100644 --- a/read-cache.c +++ b/read-cache.c @@ -40,6 +40,9 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st) if (assume_unchanged) ce->ce_flags |= CE_VALID; + + if (S_ISREG(st->st_mode)) + ce_mark_uptodate(ce); } static int ce_compare_data(struct cache_entry *ce, struct stat *st) @@ -412,6 +415,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) !ie_match_stat(istate, istate->cache[pos], &st, ce_option)) { /* Nothing changed, really */ free(ce); + ce_mark_uptodate(istate->cache[pos]); return 0; } @@ -779,6 +783,9 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, int changed, size; int ignore_valid = options & CE_MATCH_IGNORE_VALID; + if (ce_uptodate(ce)) + return ce; + if (lstat(ce->name, &st) < 0) { if (err) *err = errno; @@ -797,8 +804,15 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, if (ignore_valid && assume_unchanged && !(ce->ce_flags & CE_VALID)) ; /* mark this one VALID again */ - else + else { + /* + * We do not mark the index itself "modified" + * because CE_UPTODATE flag is in-core only; + * we are not going to write this change out. + */ + ce_mark_uptodate(ce); return ce; + } } if (ie_modified(istate, ce, &st, options)) { |