{"thread":{"id":"5283","subject":"[PATCH 2/6] Solaris does not support C99 format strings before version 10","startedAt":"2006-08-15T09:00:31Z","lastAt":"2006-08-15T20:12:33Z","messageCount":10,"participants":["Dennis Stosberg","Junio C Hamano","Alex Riesen"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"25347","messageId":"20060815090031.5223.27458.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":null,"subject":"[PATCH 0/6] Configuration tweaks for Solaris","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:00:31Z","receivedAt":"2006-08-15T09:00:31Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"Hello,\n\nThe current configure script fails to generate a working configuration\non Solaris for a number of different reasons.  With these patches on the\n\"next\" branch \"gmake clean configure && ./configure && gmake all test\"\ncompletes on Solaris 9 with Sun CC 5.8 without errors.\n\nThe second patch may be suitable for the \"maint\" branch as well. Without\nit, at least t3800-mktag.sh fails.\n\nRegards,\nDennis\n"},{"id":"25348","messageId":"20060815090120.5223.47263.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 1/6] Solaris has strlcpy() at least since version 8","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:20Z","receivedAt":"2006-08-15T09:01:20Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"See http://docs.sun.com/app/docs/doc/816-3321/6m9k23sjk?a=view\n\nSigned-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n Makefile |    1 -\n 1 files changed, 0 insertions(+), 1 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 66c4fcc..495631a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -338,7 +338,6 @@ ifeq ($(uname_S),SunOS)\n \tNEEDS_NSL = YesPlease\n \tSHELL_PATH = /bin/bash\n \tNO_STRCASESTR = YesPlease\n-\tNO_STRLCPY = YesPlease\n \tifeq ($(uname_R),5.8)\n \t\tNEEDS_LIBICONV = YesPlease\n \t\tNO_UNSETENV = YesPlease\n"},{"id":"25345","messageId":"20060815090122.5223.85031.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 2/6] Solaris does not support C99 format strings before version 10","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:22Z","receivedAt":"2006-08-15T09:01:22Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"Signed-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n Makefile |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 495631a..3cb6531 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -342,10 +342,12 @@ ifeq ($(uname_S),SunOS)\n \t\tNEEDS_LIBICONV = YesPlease\n \t\tNO_UNSETENV = YesPlease\n \t\tNO_SETENV = YesPlease\n+\t\tNO_C99_FORMAT = YesPlease\n \tendif\n \tifeq ($(uname_R),5.9)\n \t\tNO_UNSETENV = YesPlease\n \t\tNO_SETENV = YesPlease\n+\t\tNO_C99_FORMAT = YesPlease\n \tendif\n \tINSTALL = ginstall\n \tTAR = gtar\n"},{"id":"25349","messageId":"20060815090125.5223.70700.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 3/6] Look for sockaddr_storage in sys/socket.h","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:25Z","receivedAt":"2006-08-15T09:01:25Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"On Solaris and the BSDs the definition of \"struct sockaddr_storage\"\nis not available from \"netinet/in.h\".  On Solaris \"sys/socket.h\" is \nenough, at least OpenBSD needs \"sys/types.h\", too.\n\nUsing \"sys/types.h\" and \"sys/socket.h\" seems to be a more portable\nway.\n\nSigned-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n configure.ac |    6 ++++--\n 1 files changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/configure.ac b/configure.ac\nindex e890131..0321d43 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -181,8 +181,10 @@ # Define NO_SOCKADDR_STORAGE if your pla\n # sockaddr_storage.\n AC_CHECK_TYPE(struct sockaddr_storage,\n [NO_SOCKADDR_STORAGE=],\n-[NO_SOCKADDR_STORAGE=YesPlease],\n-[#include <netinet/in.h>])\n+[NO_SOCKADDR_STORAGE=YesPlease],[\n+#include <sys/types.h>\n+#include <sys/socket.h>\n+])\n AC_SUBST(NO_SOCKADDR_STORAGE)\n #\n # Define NO_IPV6 if you lack IPv6 support and getaddrinfo().\n"},{"id":"25351","messageId":"20060815090127.5223.89277.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 4/6] Fix detection of ipv6 on Solaris","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:27Z","receivedAt":"2006-08-15T09:01:27Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"The configuration script detects whether linking with -lsocket is\nnecessary but doesn't add -lsocket to LIBS.  This lets the ipv6 test\nfail.\n\nSigned-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n configure.ac |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/configure.ac b/configure.ac\nindex 0321d43..36f9cd9 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -154,6 +154,7 @@ AC_CHECK_LIB([c], [socket],\n [NEEDS_SOCKET=],\n [NEEDS_SOCKET=YesPlease])\n AC_SUBST(NEEDS_SOCKET)\n+test -n \"$NEEDS_SOCKET\" && LIBS=\"$LIBS -lsocket\"\n \n \n ## Checks for header files.\n"},{"id":"25346","messageId":"20060815090129.5223.17174.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 5/6] On Solaris nanosleep() is not in libc but in librt","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:29Z","receivedAt":"2006-08-15T09:01:29Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"Signed-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n Makefile      |   11 +++++++++--\n config.mak.in |    1 +\n configure.ac  |   10 ++++++++--\n 3 files changed, 18 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 3cb6531..d352901 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -67,8 +67,10 @@ # Define NEEDS_SSL_WITH_CRYPTO if you ne\n #\n # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).\n #\n-# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,\n-# Patrick Mauritz).\n+# Define NEEDS_SOCKET if linking with libc is not enough for socket()\n+# (SunOS, Patrick Mauritz).\n+#\n+# Define NEEDS_RT if linking with libc is not enough for nanosleep() (SunOS)\n #\n # Define NO_MMAP if you want to avoid mmap.\n #\n@@ -336,6 +338,7 @@ endif\n ifeq ($(uname_S),SunOS)\n \tNEEDS_SOCKET = YesPlease\n \tNEEDS_NSL = YesPlease\n+\tNEEDS_RT = YesPlease\n \tSHELL_PATH = /bin/bash\n \tNO_STRCASESTR = YesPlease\n \tifeq ($(uname_R),5.8)\n@@ -479,6 +482,10 @@ ifdef NEEDS_NSL\n \tEXTLIBS += -lnsl\n \tSIMPLE_LIB += -lnsl\n endif\n+ifdef NEEDS_RT\n+\tEXTLIBS += -lrt\n+\tSIMPLE_LIB += -lrt\n+endif\n ifdef NO_D_TYPE_IN_DIRENT\n \tBASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT\n endif\ndiff --git a/config.mak.in b/config.mak.in\nindex 369e611..038767e 100644\n--- a/config.mak.in\n+++ b/config.mak.in\n@@ -29,6 +29,7 @@ NO_CURL=@NO_CURL@\n NO_EXPAT=@NO_EXPAT@\n NEEDS_LIBICONV=@NEEDS_LIBICONV@\n NEEDS_SOCKET=@NEEDS_SOCKET@\n+NEEDS_RT=@NEEDS_RT@\n NO_D_INO_IN_DIRENT=@NO_D_INO_IN_DIRENT@\n NO_D_TYPE_IN_DIRENT=@NO_D_TYPE_IN_DIRENT@\n NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@\ndiff --git a/configure.ac b/configure.ac\nindex 36f9cd9..6f1d87a 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -148,13 +148,19 @@ AC_CHECK_LIB([c], [iconv],\n [NEEDS_LIBICONV=YesPlease])\n AC_SUBST(NEEDS_LIBICONV)\n #\n-# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,\n-# Patrick Mauritz).\n+# Define NEEDS_SOCKET if linking with libc is not enough for socket()\n+# (SunOS, Patrick Mauritz).\n AC_CHECK_LIB([c], [socket],\n [NEEDS_SOCKET=],\n [NEEDS_SOCKET=YesPlease])\n AC_SUBST(NEEDS_SOCKET)\n test -n \"$NEEDS_SOCKET\" && LIBS=\"$LIBS -lsocket\"\n+#\n+# Define NEEDS_RT if linking with libc is not enough for nanosleep (SunOS)\n+AC_CHECK_LIB([c], [nanosleep],\n+[NEEDS_RT=],\n+[NEEDS_RT=YesPlease])\n+AC_SUBST(NEEDS_RT)\n \n \n ## Checks for header files.\n"},{"id":"25350","messageId":"20060815090131.5223.62594.stgit@leonov.stosberg.net","threadId":"5283","inReplyTo":"20060815090031.5223.27458.stgit@leonov.stosberg.net","subject":"[PATCH 6/6] Fix compilation with Sun CC","fromName":"Dennis Stosberg","fromEmail":"dennis@stosberg.net","sentAt":"2006-08-15T09:01:31Z","receivedAt":"2006-08-15T09:01:31Z","isPatch":true,"sender":{"key":"dennis@stosberg.net","avatar":null},"body":"- Add the CFLAGS variable to config.mak.in to override the Makefile's\n  default, which is gcc-specific and won't work with Sun CC.\n- Prefer \"cc\" over \"gcc\", because Pasky's Git.pm will not compile with gcc\n  on Solaris at all. On Linux and the free BSDs \"cc\" is linked to \"gcc\"\n  anyway.\n- Set correct flag to generate position-independent code.\n- Add \"-xO3\" (= use default optimization level) to CFLAGS.\n\nSigned-off-by: Dennis Stosberg <dennis@stosberg.net>\n---\n\n Makefile      |    6 +++++-\n config.mak.in |    2 ++\n configure.ac  |    9 ++++++++-\n 3 files changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex d352901..aeefc4e 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -114,6 +114,7 @@ uname_P := $(shell sh -c 'uname -p 2>/de\n # CFLAGS and LDFLAGS are for the users to override from the command line.\n \n CFLAGS = -g -O2 -Wall\n+PIC_FLAG = -fPIC\n LDFLAGS =\n ALL_CFLAGS = $(CFLAGS)\n ALL_LDFLAGS = $(LDFLAGS)\n@@ -408,6 +409,9 @@ endif\n ifneq (,$(findstring arm,$(uname_M)))\n \tARM_SHA1 = YesPlease\n endif\n+ifeq ($(uname_M),sun4u)\n+\tUSE_PIC = YesPlease\n+endif\n ifeq ($(uname_M),x86_64)\n \tUSE_PIC = YesPlease\n endif\n@@ -554,7 +558,7 @@ endif\n endif\n endif\n ifdef USE_PIC\n-\tALL_CFLAGS += -fPIC\n+\tALL_CFLAGS += $(PIC_FLAG)\n endif\n ifdef NO_ACCURATE_DIFF\n \tBASIC_CFLAGS += -DNO_ACCURATE_DIFF\ndiff --git a/config.mak.in b/config.mak.in\nindex 038767e..1fd5f7e 100644\n--- a/config.mak.in\n+++ b/config.mak.in\n@@ -2,6 +2,8 @@ # git Makefile configuration, included i\n # @configure_input@\n \n CC = @CC@\n+CFLAGS = @CFLAGS@\n+PIC_FLAG = @PIC_FLAG@\n AR = @AR@\n TAR = @TAR@\n #INSTALL = @INSTALL@\t\t# needs install-sh or install.sh in sources\ndiff --git a/configure.ac b/configure.ac\nindex 6f1d87a..427ac23 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -95,7 +95,14 @@ AC_SUBST(PYTHON_PATH)\n ## Checks for programs.\n AC_MSG_NOTICE([CHECKS for programs])\n #\n-AC_PROG_CC\n+AC_PROG_CC([cc gcc])\n+if test -n \"$GCC\"; then\n+\tPIC_FLAG=\"-fPIC\"\n+else\n+\tAC_CHECK_DECL(__SUNPRO_C, [CFLAGS=\"$CFLAGS -xO3\"; PIC_FLAG=\"-KPIC\"])\n+fi\n+AC_SUBST(PIC_FLAG)\n+\n #AC_PROG_INSTALL\t\t# needs install-sh or install.sh in sources\n AC_CHECK_TOOL(AR, ar, :)\n AC_CHECK_PROGS(TAR, [gtar tar])\n"},{"id":"25354","messageId":"7vzme670dm.fsf@assigned-by-dhcp.cox.net","threadId":"5283","inReplyTo":"20060815090129.5223.17174.stgit@leonov.stosberg.net","subject":"Re: [PATCH 5/6] On Solaris nanosleep() is not in libc but in librt","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T10:35:01Z","receivedAt":"2006-08-15T10:35:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dennis Stosberg <dennis@stosberg.net> writes:\n\n> -# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,\n> -# Patrick Mauritz).\n> +# Define NEEDS_SOCKET if linking with libc is not enough for socket()\n> +# (SunOS, Patrick Mauritz).\n> +#\n> +# Define NEEDS_RT if linking with libc is not enough for nanosleep() (SunOS)\n\nAh, nanosleep(2) was my fault, and we should be able to just use\nstraight sleep(3) there.  The purpose of the loop is to wait\nuntil the next filesystem timestamp granularity, and the code\nuses subsecond sleep in the hope that it can shorten the delay\nto 0.5 seconds on average instead of a full second.\n\nHow exotic is -lrt on SunOS?  I suspect it is not worth\ndepending on it only for that single use in read-cache.c\n\nWe might want to yank out the whole \"racy-git avoidance is\ncostly later so let's delay writing the index out\" codepath\nlater, but that is a separate issue and needs some testing on\nlarge trees to figure it out.  After playing with the kernel\ntree, I have a feeling that the whole thing may not be worth\nit.\n\nIn any case, an obvious tentative patch is here.\n\ndiff --git a/read-cache.c b/read-cache.c\nindex b18f9f7..ec4dd5a 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -5,7 +5,6 @@\n  */\n #include \"cache.h\"\n #include \"cache-tree.h\"\n-#include <time.h>\n \n /* Index extensions.\n  *\n@@ -1033,11 +1032,8 @@ #if 0\n \t\t\tfprintf(stderr, \"now        %lu\\n\", now);\n #endif\n \t\t\twhile (!fstat(newfd, &st) && st.st_mtime <= now) {\n-\t\t\t\tstruct timespec rq, rm;\n \t\t\t\toff_t where = lseek(newfd, 0, SEEK_CUR);\n-\t\t\t\trq.tv_sec = 0;\n-\t\t\t\trq.tv_nsec = 250000000;\n-\t\t\t\tnanosleep(&rq, &rm);\n+\t\t\t\tsleep(1);\n \t\t\t\tif ((where == (off_t) -1) ||\n \t\t\t\t    (write(newfd, \"\", 1) != 1) ||\n \t\t\t\t    (lseek(newfd, -1, SEEK_CUR) != where) ||\n"},{"id":"25355","messageId":"81b0412b0608150418g3fc8efd7n51f1095a98a3d08f@mail.gmail.com","threadId":"5283","inReplyTo":"7vzme670dm.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 5/6] On Solaris nanosleep() is not in libc but in librt","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2006-08-15T11:18:17Z","receivedAt":"2006-08-15T11:18:17Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"On 8/15/06, Junio C Hamano <junkio@cox.net> wrote:\n> > -# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,\n> > -# Patrick Mauritz).\n> > +# Define NEEDS_SOCKET if linking with libc is not enough for socket()\n> > +# (SunOS, Patrick Mauritz).\n> > +#\n> > +# Define NEEDS_RT if linking with libc is not enough for nanosleep() (SunOS)\n>\n> Ah, nanosleep(2) was my fault, and we should be able to just use\n> straight sleep(3) there.  The purpose of the loop is to wait\n> until the next filesystem timestamp granularity, and the code\n> uses subsecond sleep in the hope that it can shorten the delay\n> to 0.5 seconds on average instead of a full second.\n\nWas it not SunOS where sleep was implemented by means of SIGALRM?\nBesides, we still can shorten the delay by using select(2).\n"},{"id":"25377","messageId":"7vhd0d7o7i.fsf_-_@assigned-by-dhcp.cox.net","threadId":"5283","inReplyTo":"7vzme670dm.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Documentation/technical/racy-git.txt","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T20:12:33Z","receivedAt":"2006-08-15T20:12:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n   Junio C Hamano <junkio@cox.net> writes:\n\n   > We might want to yank out the whole \"racy-git avoidance is\n   > costly later so let's delay writing the index out\" codepath\n   > later, but that is a separate issue and needs some testing on\n   > large trees to figure it out.  After playing with the kernel\n   > tree, I have a feeling that the whole thing may not be worth\n   > it.\n\n   Addressed to Linus because he originally brought up this issue\n   in <Pine.LNX.4.64.0607310945490.4168@g5.osdl.org>, Johannes\n   CC'ed because he had some comments earlier on the same topic\n   and he is generally a good person to talk to when I have\n   doubts on issues ;-).\n\n Documentation/technical/racy-git.txt |  193 ++++++++++++++++++++++++++++++++++\n 1 files changed, 193 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt\nnew file mode 100644\nindex 0000000..7597d04\n--- /dev/null\n+++ b/Documentation/technical/racy-git.txt\n@@ -0,0 +1,193 @@\n+Use of index and Racy git problem\n+=================================\n+\n+Background\n+----------\n+\n+The index is one of the most important data structure in git.\n+It represents a virtual working tree state by recording list of\n+paths and their object names and serves as a staging area to\n+write out the next tree object to be committed.  The state is\n+\"virtual\" in the sense that it does not necessarily have to, and\n+often does not, match the files in the working tree.\n+\n+There are cases git needs to examine the differences between the\n+virtual working tree state in the index and the files in the\n+working tree.  The most obvious case is when the user asks `git\n+diff` (or its low level implementation, `git diff-files`) or\n+`git-ls-files --modified`.  In addition, git internally checks\n+if the files in the working tree is different from what are\n+recorded in the index to avoid stomping on local changes in them\n+during patch application, switching branches, and merging.\n+\n+In order to speed up this comparison between the files in the\n+working tree and the index entries, the index entries record the\n+information obtained from the filesystem via `lstat(2)` system\n+call when they were last updated.  When checking if they differ,\n+git first runs `lstat(2)` on the files and compare the result\n+with this information (this is what was originally done by the\n+`ce_match_stat()` function, which the current code does in\n+`ce_match_stat_basic()` function).  If some of these \"cached\n+stat information\" fields do not match, git can tell that the\n+files are modified without even looking at their contents.\n+\n+Note: not all members in `struct stat` obtained via `lstat(2)`\n+are used for this comparison.  For example, `st_atime` obviously\n+is not useful.  Currently, git compares the file type (regular\n+files vs symbolic links) and executable bits (only for regular\n+files) from `st_mode` member, `st_mtime` and `st_ctime`\n+timestamps, `st_uid`, `st_gid`, `st_ino`, and `st_size` members.\n+With a `USE_STDEV` compile-time option, `st_dev` is also\n+compared, but this is not enabled by default because this member\n+is not stable on network filesystems.  With `USE_NSEC`\n+compile-time option, `st_mtim.tv_nsec` and `st_ctim.tv_nsec`\n+members are also compared, but this is not enabled by default\n+because the value of this member becomes meaningless once the\n+inode is evicted from the inode cache on filesystems that do not\n+store it on disk.\n+\n+\n+Racy git\n+--------\n+\n+There is one slight problem with the optimization based on the\n+cached stat information.  Consider this sequence:\n+\n+  $ git update-index 'foo'\n+  : modify 'foo' in-place without changing its size\n+\n+The first `update-index` computes the object name of the\n+contents of file `foo` and updates the index entry for `foo`\n+along with the `struct stat` information.  If the modification\n+that follows it happens very fast so that the file's `st_mtime`\n+timestamp does not change, after this sequence, the cached stat\n+information the index entry records still exactly match what you\n+can obtain from the filesystem, but the file `foo` is modified.\n+This way, git can incorrectly think files in the working tree\n+are unmodified even though they actually are.  This is called\n+the \"racy git\" problem (discovered by Pasky), and the entries\n+that appear clean when they may not be because of this problem\n+are called \"racily clean\".\n+\n+To avoid this problem, git does two things:\n+\n+. When the cached stat information says the file has not been\n+  modified, and the `st_mtime` is the same as (or newer than)\n+  the timestamp of the index file itself (which is the time `git\n+  update-index foo` finished running in the above example), it\n+  also compares the contents with the object registered in the\n+  index entry to make sure they match.\n+\n+. When the index file is updated that contains racily clean\n+  entries, cached `st_size` information is truncated to zero\n+  before writing a new version of the index file.\n+\n+Because the index file itself is written after collecting all\n+the stat information from updated paths, `st_mtime` timestamp of\n+it is usually the same as or newer than any of the paths the\n+index contains.  And no matter how quick the modification that\n+follows `git update-index foo` finishes, the resulting\n+`st_mtime` timestamp on `foo` cannot get the timestamp earlier\n+than the index file.  Therefore, index entries that can be\n+racily clean are limited to the ones that have the same\n+timestamp as the index file itself.\n+\n+The callers that want to check if an index entry matches the\n+corresponding file in the working tree continue to call\n+`ce_match_stat()`, but with this change, `ce_match_stat()` uses\n+`ce_modified_check_fs()` to see if racily clean ones are\n+actually clean after comparing the cached stat information using\n+`ce_match_stat_basic()`.\n+\n+The problem the latter solves is this sequence:\n+\n+  $ git update-index 'foo'\n+  : modify 'foo' in-place without changing its size\n+  : wait for enough time\n+  $ git update-index 'bar'\n+\n+Without the latter, the timestamp of the index file gets a newer\n+value, and falsely clean entry `foo` would not be caught by the\n+timestamp comparison check done with the former logic anymore.\n+The latter makes sure that the cached stat information for `foo`\n+would never match with the file in the working tree, so later\n+checks by `ce_match_stat_basic()` would report the index entry\n+does not match the file and git does not have to fall back on more\n+expensive `ce_modified_check_fs()`.\n+\n+\n+Runtime penalty\n+---------------\n+\n+The runtime penalty of falling back to `ce_modified_check_fs()`\n+from `ce_match_stat()` can be very expensive when there are many\n+racily clean entries.  An obvious way to artificially create\n+this situation is to give the same timestamp to all the files in\n+the working tree in a large project, run `git update-index` on\n+them, and give the same timestamp to the index file:\n+\n+  $ date >.datestamp\n+  $ git ls-files | xargs touch -r .datestamp\n+  $ git ls-files | git update-index --stdin\n+  $ touch -r .datestamp .git/index\n+\n+This will make all index entries racily clean.  The linux-2.6\n+project, for example, there are over 20,000 files in the working\n+tree.  On my Athron 64X2 3800+, after the above:\n+\n+  $ /usr/bin/time git diff-files\n+  1.68user 0.54system 0:02.22elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k\n+  0inputs+0outputs (0major+67111minor)pagefaults 0swaps\n+  $ git update-index MAINTAINERS\n+  $ /usr/bin/time git diff-files\n+  0.02user 0.12system 0:00.14elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k\n+  0inputs+0outputs (0major+935minor)pagefaults 0swaps\n+\n+Running `git update-index` in the middle checked the racily\n+clean entries, and left the cached `st_mtime` for all the paths\n+intact because they were actually clean (so this step took about\n+the same amount of time as the first `git diff-files`).  After\n+that, they are not racily clean anymore but are truly clean, so\n+the second invocation of `git diff-files` fully took advantage\n+of the cached stat information.\n+\n+\n+Avoiding runtime penalty\n+------------------------\n+\n+In order to avoid the above runtime penalty, the recent \"master\"\n+branch (post 1.4.2) has a code that makes sure the index file\n+gets timestamp newer than the youngest files in the index when\n+there are many young files with the same timestamp as the\n+resulting index file would otherwise would have by waiting\n+before finishing writing the index file out.\n+\n+I suspect that in practice the situation where many paths in the\n+index are all racily clean is quite rare.  The only code paths\n+that can record recent timestamp for large number of paths I\n+know of are:\n+\n+. Initial `git add .` of a large project.\n+\n+. `git checkout` of a large project from an empty index into an\n+  unpopulated working tree.\n+\n+Note: switching branches with `git checkout` keeps the cached\n+stat information of existing working tree files that are the\n+same between the current branch and the new branch, which are\n+all older than the resulting index file, and they will not\n+become racily clean.  Only the files that are actually checked\n+out can become racily clean.\n+\n+In a large project where raciness avoidance cost really matters,\n+however, the initial computation of all object names in the\n+index takes more than one second, and the index file is written\n+out after all that happens.  Therefore the timestamp of the\n+index file will be more than one seconds later than the the\n+youngest file in the working tree.  This means that in these\n+cases there actually will not be any racily clean entry in\n+the resulting index.\n+\n+So in summary I think we should not worry about avoiding the\n+runtime penalty and get rid of the \"wait before finishing\n+writing\" code out.\n-- \n1.4.2.g59bb\n"}]}