race condition after calling git reset --keep

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

trying to wrap git, I ran into this problem using git 2.17.1 on Ubuntu 18.04.1.
When fast-forwarding like this:

    git reset --keep remotes/origin/master

sometimes git returns an error like:

    error: Entry 'foo.txt' not uptodate. Cannot merge.
    fatal: Could not reset index file to revision 'remotes/origin/master'.

...in situations where fast-forward would seem possible at a glance.

This can have different root causes as mentioned in
* https://stackoverflow.com/questions/1248029
* https://stackoverflow.com/questions/878554

We are not sure what causes this for our users, one contributing
factor seems to be git repositories that have not been updated in a
long time (maybe last update with a different git version).

In our case this can apparently often be prevented by calling e.g.

    git update-index -q --refresh

When trying to unit-test our solution I found a way to reproduce the
symptom, but I ran into what looks like a race-condition.

To reproduce, on a file that is changed on the remote branch, I run

    chmod u+x file
    git reset --keep ...
    chmod u-x file
    git reset --keep ...

This makes the both git commands fail, though occasionally the second
one succeeds (hence I assume a race condition).
I am posting this here not because I need an urgent patch, but because
this might not be intentional and thus possibly a bug, and as shown in
the stackoverflow question other users may be affected, and the
non-deterministic behavior on race conditions is of course making
matters worse.

To reproduce a git error below, a sleep is required after a first call
to git reset --keep, so that the next call to git reset --keep after a
file permission change fails.

    #! /usr/bin/env sh

    set -e

    # this script shows a race condition in git reset --keep
    # It can be repeatedly run without manual cleanup
    # it creates / deletes folders 'parent' and 'child' in /tmp

    # setup origin with two commits on file foo.txt
    cd /tmp
    git init parent
    cd parent/
    touch foo.txt
    git add foo.txt
    git commit -m foo || true
    echo 'hello' > foo.txt
    git add foo.txt
    git commit -m foo2 || true

    cd ..
    rm -rf child # cleanup previous runs

    # Clone repo master branch, reset hard to first commit, mess with
file permissions
    git clone parent child
    cd child/
    git reset --hard HEAD~1
    chmod u+x foo.txt
    # next line always fails, which seems legit
    git reset --keep remotes/origin/master || true
    # This sleep is required to make the last command fail. Without
sleep, the last git command succeeds most of the time
    sleep 1
    chmod u-x foo.txt
    # Next line should fail?   Sometimes it does, sometimes not.
    git reset --keep remotes/origin/master


regards,
  Thibault Kruse



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux