@matheusbsbs / matheus-bagliano / commits / e1afca4fd3
Fork 0

write_index(): update index_state->timestamp after flushing to disk

Since this timestamp is used to check for racy-clean files, it is important to keep it uptodate. For the 'git checkout' command without the '-q' option, this make a huge difference. Before, each and every file which was updated, was racy-clean after the call to unpack_trees() and write_index() but before the GIT process ended. And because of the call to show_local_changes() in builtin-checkout.c, we ended up reading those files back into memory, doing a SHA1 to check if the files was really different from the index. And, of course, no file was different. With this fix, 'git checkout' without the '-q' option should now be almost as fast as with the '-q' option, but not quite, as we still do some few lstat(2) calls more without the '-q' option. Below is some average numbers for 10 checkout's to v2.6.27 and 10 to v2.6.25 of the Linux kernel, to show the difference: before (git version 1.6.2.rc1.256.g58a87): 7.860 user 2.427 sys 19.465 real 52.8% CPU faults: 0 major 95331 minor after: 6.184 user 2.160 sys 17.619 real 47.4% CPU faults: 0 major 38994 minor Signed-off-by: Kjetil Barvik <barvik@broadpark.no> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kjetil Barvik committed Feb 23, 2009 at 19:02 UTC e1afca4fd3e7cb4000874e991277f10119de4ad2
2 files changed +11 -3
cache.h
+1 -1
@@ -430,7 +430,7 @@ extern int read_index_preload(struct index_state *, const char **pathspec);
430 extern int read_index_from(struct index_state *, const char *path);
431 extern int is_index_unborn(struct index_state *);
432 extern int read_index_unmerged(struct index_state *);
433 -extern int write_index(const struct index_state *, int newfd);
433 +extern int write_index(struct index_state *, int newfd);
434 extern int discard_index(struct index_state *);
435 extern int unmerged_index(const struct index_state *);
436 extern int verify_path(const char *path);
read-cache.c
+10 -2
@@ -1528,13 +1528,14 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)
1528 return ce_write(c, fd, ondisk, size);
1529 }
1530
1531 -int write_index(const struct index_state *istate, int newfd)
1531 +int write_index(struct index_state *istate, int newfd)
1532 {
1533 git_SHA_CTX c;
1534 struct cache_header hdr;
1535 int i, err, removed, extended;
1536 struct cache_entry **cache = istate->cache;
1537 int entries = istate->cache_nr;
1538 + struct stat st;
1539
1540 for (i = removed = extended = 0; i < entries; i++) {
1541 if (cache[i]->ce_flags & CE_REMOVE)
@@ -1578,7 +1579,14 @@ int write_index(const struct index_state *istate, int newfd)
1579 if (err)
1580 return -1;
1581 }
1581 - return ce_flush(&c, newfd);
1582 +
1583 + if (ce_flush(&c, newfd) || fstat(newfd, &st))
1584 + return -1;
1585 + istate->timestamp.sec = (unsigned int)st.st_ctime;
1586 +#ifdef USE_NSEC
1587 + istate->timestamp.nsec = (unsigned int)st.st_ctim.tv_nsec;
1588 +#endif
1589 + return 0;
1590 }
1591
1592 /*