summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2007-08-10 16:51:58 (GMT)
committerJunio C Hamano <gitster@pobox.com>2007-08-10 20:57:43 (GMT)
commit22631473e0b7a33356587ba3e38a9b4cc4dba2f1 (patch)
treef0dfa89ae59bc56039c72eebcc8013d0169bd399
parentaf3785dc5a76f4d5ddb8039e33c322e0e8b60e72 (diff)
downloadgit-22631473e0b7a33356587ba3e38a9b4cc4dba2f1.zip
git-22631473e0b7a33356587ba3e38a9b4cc4dba2f1.tar.gz
git-22631473e0b7a33356587ba3e38a9b4cc4dba2f1.tar.bz2
Fix "git commit directory/" performance anomaly
This trivial patch avoids re-hashing files that are already clean in the index. This mirrors what commit 0781b8a9b2fe760fc4ed519a3a26e4b9bd6ccffe did for "git add .", only for "git commit ." instead. This improves the cold-cache case immensely, since we don't need to bring in all the file contents, just the index and any files dirty in the index. Before: [torvalds@woody linux]$ time git commit . real 1m49.537s user 0m3.892s sys 0m2.432s After: [torvalds@woody linux]$ time git commit . real 0m14.273s user 0m1.312s sys 0m0.516s (both after doing a "echo 3 > /proc/sys/vm/drop_caches" to get cold-cache behaviour - even with the index optimization git still has to "lstat()" all the files, so with a truly cold cache, bringing all the inodes in will take some time). [jc: trivial "return 0;" fixed] Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin-update-index.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 509369e..a7a4574 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -86,9 +86,15 @@ static int process_lstat_error(const char *path, int err)
static int add_one_path(struct cache_entry *old, const char *path, int len, struct stat *st)
{
- int option, size = cache_entry_size(len);
- struct cache_entry *ce = xcalloc(1, size);
+ int option, size;
+ struct cache_entry *ce;
+
+ /* Was the old index entry already up-to-date? */
+ if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))
+ return 0;
+ size = cache_entry_size(len);
+ ce = xcalloc(1, size);
memcpy(ce->name, path, len);
ce->ce_flags = htons(len);
fill_stat_cache_info(ce, st);