• Show log

    Commit

  • Hash : 3f201f75
    Author : Patrick Steinhardt
    Date : 2020-05-16T13:48:04

    checkout: fix file being treated as unmodified due to racy index
    
    When trying to determine whether a file changed, we try to avoid heavy
    operations by fist taking a look at the index, seeing whether the index
    entry is modified already. This doesn't seem to cut it, though, as we
    currently have the racy checkout::index::can_disable_pathspec_match test
    case: sometimes the files get restored to their original contents,
    sometimes they aren't.
    
    The issue is caused by a racy index [1]: in case we modify a file, add
    it to the index and then modify it again in-place without changing its
    file, then we may end up with a modified file that has the same stat(3P)
    info as we've currently got it in its corresponding index entry. The
    mitigation for this is to treat files with the same mtime as the index
    are treated as racily modified. We already have this logic in place for
    the index, but not when doing a checkout.
    
    Fix the issue by only consulting the index entry in case it has an older
    mtime as the index. Previously, the following script reliably had at
    least 20 failures, while now there is no failure to be observed anymore:
    
    ```bash
    j=0
    for i in $(seq 100)
    do
    	if ! ./libgit2_clar -scheckout::index::can_disable_pathspec_match >/dev/null
    	then
    		j=$(($j + 1))
    	fi
    done
    echo "Failures: $j"
    ```
    
    [1]: https://git-scm.com/docs/racy-git