{"thread":{"id":"17974","subject":"[PATCH v2] write_index(): update index_state->timestamp after flushing to disk","startedAt":"2009-02-23T18:02:57Z","lastAt":"2009-02-23T18:02:57Z","messageCount":1,"participants":["Kjetil Barvik"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"105926","messageId":"1235412177-2255-1-git-send-email-barvik@broadpark.no","threadId":"17974","inReplyTo":null,"subject":"[PATCH v2] write_index(): update index_state->timestamp after flushing to disk","fromName":"Kjetil Barvik","fromEmail":"barvik@broadpark.no","sentAt":"2009-02-23T18:02:57Z","receivedAt":"2009-02-23T18:02:57Z","isPatch":true,"sender":{"key":"barvik@broadpark.no","avatar":null},"body":"Since this timestamp is used to check for racy-clean files, it is\nimportant to keep it uptodate.\n\nFor the 'git checkout' command without the '-q' option, this make a\nhuge difference.  Before, each and every file which was updated, was\nracy-clean after the call to unpack_trees() and write_index() but\nbefore the GIT process ended.\n\nAnd because of the call to show_local_changes() in builtin-checkout.c,\nwe ended up reading those files back into memory, doing a SHA1 to\ncheck if the files was really different from the index.  And, of\ncourse, no file was different.\n\nWith this fix, 'git checkout' without the '-q' option should now be\nalmost as fast as with the '-q' option, but not quite, as we still do\nsome few lstat(2) calls more without the '-q' option.\n\nBelow is some average numbers for 10 checkout's to v2.6.27 and 10 to\nv2.6.25 of the Linux kernel, to show the difference:\n\nbefore (git version 1.6.2.rc1.256.g58a87):\n 7.860 user  2.427 sys  19.465 real  52.8% CPU  faults: 0 major 95331 minor\nafter:\n 6.184 user  2.160 sys  17.619 real  47.4% CPU  faults: 0 major 38994 minor\n\nSigned-off-by: Kjetil Barvik <barvik@broadpark.no>\n---\n  changes since v1:\n\n  Have added some lines to the commit log message (se the before and\n  after numbers), one spellfix, and one extra blank line in the patch.\n\n\n cache.h      |    2 +-\n read-cache.c |   12 ++++++++++--\n 2 files changed, 11 insertions(+), 3 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 20446c1..7e454a7 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -430,7 +430,7 @@ extern int read_index_preload(struct index_state *, const char **pathspec);\n extern int read_index_from(struct index_state *, const char *path);\n extern int is_index_unborn(struct index_state *);\n extern int read_index_unmerged(struct index_state *);\n-extern int write_index(const struct index_state *, int newfd);\n+extern int write_index(struct index_state *, int newfd);\n extern int discard_index(struct index_state *);\n extern int unmerged_index(const struct index_state *);\n extern int verify_path(const char *path);\ndiff --git a/read-cache.c b/read-cache.c\nindex bb07371..91f1d03 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1528,13 +1528,14 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce)\n \treturn ce_write(c, fd, ondisk, size);\n }\n \n-int write_index(const struct index_state *istate, int newfd)\n+int write_index(struct index_state *istate, int newfd)\n {\n \tgit_SHA_CTX c;\n \tstruct cache_header hdr;\n \tint i, err, removed, extended;\n \tstruct cache_entry **cache = istate->cache;\n \tint entries = istate->cache_nr;\n+\tstruct stat st;\n \n \tfor (i = removed = extended = 0; i < entries; i++) {\n \t\tif (cache[i]->ce_flags & CE_REMOVE)\n@@ -1578,7 +1579,14 @@ int write_index(const struct index_state *istate, int newfd)\n \t\tif (err)\n \t\t\treturn -1;\n \t}\n-\treturn ce_flush(&c, newfd);\n+\n+\tif (ce_flush(&c, newfd) || fstat(newfd, &st))\n+\t\treturn -1;\n+\tistate->timestamp.sec = (unsigned int)st.st_ctime;\n+#ifdef USE_NSEC\n+\tistate->timestamp.nsec = (unsigned int)st.st_ctim.tv_nsec;\n+#endif\n+\treturn 0;\n }\n \n /*\n-- \n1.6.1.GIT\n"}]}