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?
The updates were rejected because the tip of your current branch is behind error can be fixed by pushing to a remote branch. This process is called a Git push, and it debugs the errors of the current branch, which is also known as a local branch.
Just like git push --force allows overwriting remote branches, git fetch --force (or git pull --force ) allows overwriting local branches.
You need to pull before push, to make your local repository up-to-date before you push something (just in case someone else has already updated code on github.com ). This helps in resolving conflicts locally. 'origin' is a remote. You can use git remote --verbose to see all the remote configured under your git folder.
You probably meant to do:
git pull web master
Using master:master
is trying to directly update you local master
branch 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/master
then you only need git pull web
and this will update your remote tracking branches as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With