A recent change in this function sometimes causes a crash when
pushing a commit. This happens in a situation such as the following:
The user has a repository that looks like this:
<root>/
subdir/
.gitattributes
sub_sub_dir/
.gitattributes
some_file
If the user creates a commit which modifies some_file, the git_attribute
function will be passed a list of files which includes:
subdir/sub_sub_dir/some_file
It will process that file by first looking at subdir/sub_sub_dir,
check if there is a .gitattributes in it (yes), so create that
directory, add it to the dirs_with_changes "list" so we know
we've already processed that directory. So far, so good.
Loop again, this time with os.path.dirname('subdir/sub_sub_dir'),
thus with 'subdir'. Is that directory in dirs_with_changes? No.
Does it have a .gitattribute in it? Yes. So, rince-repeat, which
means first creating the subdir. That leads to the crash, since
we already just created it as a side-effect of creating its subdir.
This patch fixes the issue by simply remembering when a directory
has been created for a given file in filename_list. Once that's
done, we know that the next iterations on the dir_path loop are
necessarily for parent directories, which have therefore been
created, even if they are not listed in the dirs_with_changes
"list" yet.
Another possible fix, which would be safer, would be to just
check the filesystem directly. But this code can be a hot-spot
in terms of performance, so we'll try really hard to avoid it.
Fixes P601-011.
Related to P531-036.
For a commit for which there are 4,500 files being modified and
for which all files have the no-precommit-check attribute set,
this reduces the amount of time it takes for the update hook
to process that commit from 20-25 seconds down to less than a second.
For P531-036.
The comment I added in function git_attributes to explain why we may
have to create the "info/" directory was not quite correct. This
patch improves it, now that we have a little more info about the
source of the condition (most likely differences in git versions).
Part of MC16-012.
This is another attempt at fixing the error raised when trying
to overwrite the info/attributes file when this file was left
by another user during the previous update.
For M116-004.
It turns out that making info/attributes group-writable is not
sufficient: A second user is allowed to overwrite the file, but
then the hooks fail when trying to change the file permissions
to make it group-writable.
We will use a different approach which should not need this anymore.
Part of M116-004.
A user needs to be able to overwrite this file, so we make it
group-writable.
Update the testsuite to verify this requirement for both
a repository's .gitattribute file, as well as the bare
repository's default_attribute file.
Experience shows that this is a very repetive operations, involving
multiple calls for each file being changed (the number of calls
per file being changed is equal to the depth of the file, in terms
of number of sub-directories). Caching it this way has been measured
to reduce the amount of time spent by about 10% for small commits
in the GDB repository (12 files changed). For commits involving
a larger number of files (3717), it improves performance by about 60%!