Subject: Re: [PATCH] Fix update-index --refresh for submodules if stat(2) returns st_size 0

From: Junio C Hamano <[email-masked]>
Date: Tue, 22 Jul 2008 10:28:46 -0700

Johannes Sixt <[email-masked]> writes:

>> +	if ((changed & DATA_CHANGED) && (ce->ce_size != 0 || S_ISGITLINK(ce->ce_mode)))
>
> Does this mean that ce->ce_size is non-zero for gitlinks, at least on
> Unix? Is this value useful in anyway? I don't think so. Then it shouldn't
> be a random value that lstat() happens to return.

These ce_xxx fields are the values we read from lstat(2) when the user
told us to stage that working tree entity, be it a regular file, a
symlink, or a directory that is a submodule.  The only thing required for
them is that they are stable (i.e. if you haven't touched the working tree
entity, the value stays the same), and changes across modification.  The
value itself does not have to "mean" anything.

When trying to see if the user has changes in the working tree entity
since the last such staging of the path, we compare that value with what
comes back from lstat(2), before actually comparing the contents.  If the
filesize changed, they cannot be the same and the code says you have
modified it without having to look at the contents.

	Side note.  This is why you need to be careful after modifying
	autocrlf related configuration and attributes.  If you had CRLF
	contents in the working tree that was incorrectly staged as-is,
	then switch autocrlf-on, and "git add" to fix the staged copy to
	be LF-terminated, we say "it's unchanged and we do not bother
	rehashing" by comparing the ce_xxx fields without looking at the
	contents (this is an absolutely necessary optimization to make
	"git add ."  usable), because ce_size records the size of CRLF
	version you have in the working tree, and you haven't changed the
	working tree file in this sequence above.

        Removing the file and checking things out would be the most
	straightforward solution in such a case.

We used to include ce_dev (taken from struct stat.st_dev) in the list of
fields to cache and compare to detect changes, but that is now excluded
because it is not stable (see comments in read-cache.c).  If the directory
size is unstable, perhaps it would be better to force it to some fixed
magic value so that it is not used by this "quick change detection" check.

If you network-mount the same directory from POSIX and windows, the former
may give "storage size of the directory" while the latter may give 0.
This would mean that you would need a "update-index --refresh" when you
switch between such machines.