src-d / go-git

Project has been moved to: https://github.com/go-git/go-git
https://github.com/go-git/go-git
Apache License 2.0
4.91k stars 541 forks source link

"reference has changed concurrently" when using examples/pull #1230

Open psidex opened 4 years ago

psidex commented 4 years ago

To reproduce:

I get this output:

git pull origin
error: reference has changed concurrently

After the above error occurs, running the command git pull using my installed version of git on the repo shows this:

error: cannot lock ref 'refs/remotes/origin/master': unable to resolve reference 'refs/remotes/origin/master': reference broken

If the repository is not updated on Github (so has nothing to pull), it runs successfully and returns already up-to-date


This is the full output if I change the code to send the progress tostdout:

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Compressing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
error: reference has changed concurrently

Compared to the output of the actual git command on my system:

C:\folder> git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.

Something seems to definitely be going wrong.


Versions:


After some more testing I was doing the same thing with a different repository and it was giving me another error, worktree contains unstaged changes.

This seems to be some sort of an incompatibility between the git tool and the go-git library, as cloning & pulling with just go-git works, but cloning with git and then pulling with go-git does not seem to work.

Ringeltier commented 4 years ago

I have the exact same problem with go-git.v4 and go1.13.1

michaeldv-pg commented 4 years ago

I have these problems too, hope the author can give some input here. go-git.v4 go 1.13.4 linux/amd64

nathanhack commented 4 years ago

Looking at this issue I did a couple of variations to see when this occurs. Anything with git before it was done on the command line using git, otherwise it was done with go-git.

git clone, remote change, fetch(bad)
git clone, fetch, remote change, fetch(bad)
git clone, git fetch, remote change, fetch(bad)
git clone, git pull, remote change, fetch(bad)

git clone, fetch(good)
git clone, remote change, git fetch, remote change, fetch(good)
git clone, remote change, git pull, remote change, fetch(good)

Note the git clone wasn't a new repo. Additionally the issue seems to not effect fetches after the first pull or fetch(good or bad).

Tracking down the issue it seems to be related to the following function in storage/filesystem/dotgit/dotgit_setref.go.

func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) (err error) {
    if billy.CapabilityCheck(d.fs, billy.ReadAndWriteCapability) {
        return d.setRefRwfs(fileName, content, old)
    }

    return d.setRefNorwfs(fileName, content, old)
}

Simply removing the if statement seems to fix the issue (see example below).

func (d *DotGit) setRef(fileName, content string, old *plumbing.Reference) (err error) {
    return d.setRefNorwfs(fileName, content, old)
}

This would imply the issue is with billy.CapabilityCheck. Looks like it doesn't properly detect opening files in RDWD mode on my system.

I don't believe removing the capability check is the correct fix. But this may help other until there is an actual fix for this.

System notes: Ubuntu 19.04 Linux/AMD64 go-git.v4@v4.13.1

EDIT: I've added an issue ticket on go-billy.

m9rco commented 4 years ago

I have these problems too, hope the author can give some input here.

go-git.v4

go version go1.13.4 darwin/amd64