rename_tmp_log(): handle a possible mkdir/rmdir race
commitae4a283e3b4cdc99a548d215739539c3a690f290
authorMichael Haggerty <mhagger@alum.mit.edu>
Sat, 18 Jan 2014 22:48:59 +0000 (18 23:48 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Jan 2014 21:47:13 +0000 (21 13:47 -0800)
tree5aafdb37d7e651c7038bbe2d40f4dd79a3ddeb1e
parentfa59ae7971498157370d935adbb2bfc28012aa9f
rename_tmp_log(): handle a possible mkdir/rmdir race

If a directory vanishes while renaming the temporary reflog file,
retry (up to 3 times).  This could happen if another process deletes
the directory created by safe_create_leading_directories() just before
we rename the file into the directory.

As far as I can tell, this race could not occur internal to git.  The
only time that a directory under $GIT_DIR/logs is deleted is if room
has to be made for a log file for a reference with the same name;
for example, in the following sequence:

    git branch foo/bar    # Creates file .git/logs/refs/heads/foo/bar
    git branch -d foo/bar # Deletes file but leaves .git/logs/refs/heads/foo/
    git branch foo        # Deletes .git/logs/refs/heads/foo/

But the only reason the last command deletes the directory is because
it wants to create a file with the same name.  So if another process
(e.g.,

    git branch foo/baz

) wants to create that directory, one of the two is doomed to failure
anyway because of a D/F conflict.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs.c