On Thu, 7 May 2009, Linus Torvalds wrote:
this patch is worthwhile in itself, but the use case that is presented
here is slightly different, and I wonder if it's common enough to be worth
having a config option for.
his use case (as I understand it) is that the working tree is never
updated by anything other than git. it never recieves patches or manual
edits.
as such _any_ lstats of the tree are a waste of time. if git knows what
was checked out before and what is being checked out now, it can find what
files need to be changed.
this situation is not common for most developers, but it would be
reasonable for build farms, so it's not just a one-person issue.
David Lang
On Thu, 7 May 2009, Linus Torvalds wrote:
Hmm. The second pass comes from
show_local_changes(&new->commit->object);
(this is the "git checkout" without actual filenames), and is suppressed
if we ask for a quiet checkout. But it's sad how it re-loads the index. I
wonder where the CE_VALID bit got dropped.
Ahh. It's not actually dropped, it's still there.
It's just that 'get_stat_data()' doesn't check it, when asking for
noncached data.
The logic of 'get_stat_data()' is that it will return the stat data from
the filesystem (unless we explicitly ask for just the cached case, in
which case it will take it from the cache entry directly).
However, the code doesn't realize that if ce_uptodate() is true, then we
already know the stat data, so no need to do the lstat() again, and we
can take it all from the cache entry regardless of whether we asked for
filesystem data or cached data.
So here's a better patch. It should cut down the 'lstat()' calls from "git
checkout" a lot.
It looks obvious enough, and it passes testing (and now "git checkout"
only does about as many lstat's as there are files in the repository, and
they seem to all be properly asynchronous if 'core.preloadindex' is set.
Somebody should check. It would be interesting to hear about whether this
makes a performance impact, especially with slow filesystems and/or other
operating systems that have a relatively higher cost for 'lstat()'.
Linus
---
builtin-checkout.c | 4 ++--
diff-lib.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 15f0c32..3100ccd 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -216,7 +216,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_locked_index(lock_file, 1);
- if (read_cache() < 0)
+ if (read_cache_preload(pathspec) < 0)
return error("corrupt index file");
if (source_tree)
@@ -367,7 +367,7 @@ static int merge_working_tree(struct checkout_opts *opts,
int newfd = hold_locked_index(lock_file, 1);
int reprime_cache_tree = 0;
- if (read_cache() < 0)
+ if (read_cache_preload(NULL) < 0)
return error("corrupt index file");
cache_tree_free(&active_cache_tree);
diff --git a/diff-lib.c b/diff-lib.c
index a310fb2..0aba6cd 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -214,7 +214,7 @@ static int get_stat_data(struct cache_entry *ce,
const unsigned char *sha1 = ce->sha1;
unsigned int mode = ce->ce_mode;
- if (!cached) {
+ if (!cached && !ce_uptodate(ce)) {
int changed;
struct stat st;
changed = check_removed(ce, &st);
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html