There is a Git repository on a server that my colleague and I both push to and pull from. It works fine as long as we pull before committing.
However, if he has pushed to the master branch, and in the mean time I have made a local commit, when I try to pull I get this:
! [rejected] master -> master (non-fast-forward)
But I know that there should be no conflict.
The way I get around it is by pulling into a new temporary branch and then merging that into my master like this:
% git pull origin master:temp
From ssh://example.com/home/my/remote/repo
* [new branch] master -> temp
Already up-to-date.
% git merge temp
Already up-to-date.
% git push origin master:master
Notice that Git acts like I’m not doing anything, but really I have shaken it into submission.
Recently I realized that instead of trying to to “convince” Git that it’s OK for me to pull. I can just pretend that I haven’t committed yet with git reset --soft HEAD^ and git stash and then do the pull and commit on top of that.
What might be causing this strangely finicky behavior?
I was able to reproduce this problem all on my local machine. Here’s what I did:
First I made the first “local” repository and added a file.
% cd
% mkdir local-1
% cd local-1/
% mkdir website
% cd website/
% git init
Initialized empty Git repository in /Users/jason/local-1/website/.git/
% touch file
% git add .
% git commit -m 'added file'
[master (root-commit) 6d4b322] added file
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file
Then I made the “remote” repository.
% cd
% mkdir remote
% cd remote
% mkdir website.git
% cd website.git/
% git init --bare
Initialized empty Git repository in /Users/jason/remote/website.git/
Then I went back to the local, created a ref and pushed to the remote.
% cd ~/local-1/website/
% git remote add web ~/remote/website.git
% git push web +master:refs/heads/master
Counting objects: 3, done.
Writing objects: 100% (3/3), 207 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /Users/jason/remote/website.git
* [new branch] master -> master
After that I cloned the remote into a second local.
% cd
% mkdir local-2
% cd local-2
% git clone ~/remote/website.git
Cloning into website...
done.
Then I created a ref to the remote from the second local and pushed (this is where I am creating the problem I think).
% cd website/
% git remote add web ~/remote/website.git
% git push web +master:refs/heads/master
Everything up-to-date
Then I made a change to local-2, committed, and pushed.
% touch another
% git add .
% git commit -m 'added another'
[master be91180] added another
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 another
% git push web
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 238 bytes, done.
Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done.
To /Users/jason/remote/website.git
6d4b322..be91180 master -> master
Finally, I made a different change to local-1, committed, and tried to push.
% cd ~/local-1/website/
% touch something
% git add .
% git commit -m 'added something'
[master 3984529] added something
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 something
% git push web
To /Users/jason/remote/website.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '/Users/jason/remote/website.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
Blast! How about a pull?
% git pull web master:master
From /Users/jason/remote/website
! [rejected] master -> master (non-fast-forward)
OK, so there’s the problem. How do I fix it?
You probably meant to do:
Using
master:masteris trying to directly update you localmasterbranch in the fetch stage of the pull which is causing the non fast-forward error.If you’re on a branch that is set up to track
web/masterthen you only needgit pull weband this will update your remote tracking branches as well.