Subject: Re: `make profile-install` fails in 2.9.3

From: Thomas Gummerer <[email-masked]>
Date: Thu, 1 Sep 2016 21:07:00 +0100

[+cc Edward Thomson, Ingo Brückl]

Hi,

On 09/01, Jan Keromnes wrote:

[.. snip the parts others are more qualified to answer ..]
> 
> Related problem: `t3700-add.sh` currently fails in 2.9.3. I can
> provide more debug information if you don't already know this problem.

I noticed this problem as well, when I'm compiling with USE_NSEC = 1
in my config.mak.

Tracking this problem down a bit, it happens because the --chmod=[+-]x
option introduced in 4e55ed32 ("add: add --chmod=+x / --chmod=-x
options") only works if the file on disk is modified.  When the test
was changed to work on one single file, instead of doing chmod=+x on
one file and chmod=-x on another file in b38ab197c ("t3700: merge two
tests into one"), this test started breaking when the mtime of the
file and the index file weren't the same (in other words, if the file
was not racily clean and thus was not smudged).

When the file is racily clean, git detects that the contents changed,
and everything is happy, but if it isn't, git incorectly thinks the
file wasn't modified (which it wasn't, but from gits view it should be
viewed as modified because the mode does not match up anymore).

One possible fix for the test is to smudge the entry as showed below,
though I'm not sure it's the right fix.  The other way I can think of
is to change the file in the index regardless of whether the file was
changed in some other way before issuing the git add command, as that
might fit the user expectation better.  Thoughts?

diff --git a/read-cache.c b/read-cache.c
index 491e52d..f2e7986 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -656,11 +656,13 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 	else
 		ce->ce_flags |= CE_INTENT_TO_ADD;
 
-	if (S_ISREG(st_mode) && force_mode)
+	if (S_ISREG(st_mode) && force_mode) {
 		ce->ce_mode = create_ce_mode(force_mode);
-	else if (trust_executable_bit && has_symlinks)
+		ce->ce_stat_data.sd_size = 0;
+	} else if (trust_executable_bit && has_symlinks) {
 		ce->ce_mode = create_ce_mode(st_mode);
-	else {
+	} else {
 		/* If there is an existing entry, pick the mode bits and type
 		 * from it, otherwise assume unexecutable regular file.
 		 */

> Thanks,
> Jan Keromnes
> 
> ---
> 
> Steps to reproduce:
> 
>     curl https://www.kernel.org/pub/software/scm/git/git-2.9.3.tar.xz | tar xJ \
>      && cd git-2.9.3 \
>      && make prefix=/usr profile-install install-man -j18
> 
> Expected result:
> 
>     - runs all tests to get a profile (ignoring occasional failures)
>     - rebuilds Git with the profile
>     - installs Git
> 
> Actual result:
> 
>     - runs all tests to get a profile
>     - at least one test fails, interrupting the whole process
>     - Git is not installed
> 
> Failure log:
> 
>     # failed 1 among 40 test(s)
>     1..40
>     Makefile:43: recipe for target 't3700-add.sh' failed
>     make[3]: *** [t3700-add.sh] Error 1
>     make[3]: Leaving directory '/tmp/git/git-2.9.3/t'
>     Makefile:36: recipe for target 'test' failed
>     make[2]: Leaving directory '/tmp/git/git-2.9.3/t'
>     make[2]: *** [test] Error 2
>     Makefile:2221: recipe for target 'test' failed
>     make[1]: *** [test] Error 2
>     make[1]: Leaving directory '/tmp/git/git-2.9.3'
>     Makefile:1633: recipe for target 'profile' failed
>     make: *** [profile] Error 2
>     The command '/bin/sh -c mkdir /tmp/git  && cd /tmp/git  && curl
> https://www.kernel.org/pub/software/scm/git/git-2.9.3.tar.xz | tar xJ
> && cd git-2.9.3  && make prefix=/usr profile-install install-man -j18
> && rm -rf /tmp/git' returned a non-zero code: 2

-- 
Thomas