From eadb5831342bb2e756fa05c03642c4aa1929d4f5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 18 Jan 2008 23:45:24 -0800 Subject: 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 Signed-off-by: Linus Torvalds --- diff.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'diff.c') diff --git a/diff.c b/diff.c index 5b8afdcb05..d464fe3b20 100644 --- a/diff.c +++ b/diff.c @@ -1510,17 +1510,22 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int if (pos < 0) return 0; ce = active_cache[pos]; - if ((lstat(name, &st) < 0) || - !S_ISREG(st.st_mode) || /* careful! */ - ce_match_stat(ce, &st, 0) || - hashcmp(sha1, ce->sha1)) + + /* + * This is not the sha1 we are looking for, or + * unreusable because it is not a regular file. + */ + if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode)) return 0; - /* we return 1 only when we can stat, it is a regular file, - * stat information matches, and sha1 recorded in the cache - * matches. I.e. we know the file in the work tree really is - * the same as the pair. + + /* + * If ce matches the file in the work tree, we can reuse it. */ - return 1; + if (ce_uptodate(ce) || + (!lstat(name, &st) && !ce_match_stat(ce, &st, 0))) + return 1; + + return 0; } static int populate_from_stdin(struct diff_filespec *s) -- cgit v1.2.3