At some point when pushing your code to a remote server (e.g. GitHub, Bitbucket, GitLab) you’re going to see an error like the following
To github.com:salcode/myrepo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:salcode/myrepo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
The important part here is “Updates were rejected because the tip of your current branch is behind its remote counterpart.”
How did this happen?
Typically, someone else has pushed code to your remote server that you do not yet have.
What you wanted to happen
Imagine the commits for both your local master
branch and the remote server origin/master
branch look something like
master origin/master
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
(If viewing your Git branch as a list of commits like this seems unfamiliar, I suggest checking out my post on How to Improve Git Log)
Once you’re comfortable with the commits above, you add a new commit (dg34mp
) to your local (master
) branch.
master origin/master
dg34mp
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
Then you use
git push
and the remote server origin/master
is brought up-to-date.
master origin/master
dg34mp dg34mp
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
This is what we wanted to happen.
What really happened
While you were creating your new commit (dg34mp
) on your local (master
) branch, someone else added their own commit (zyx911
) to the remote server
master origin/master
dg34mp zyx911
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
Now when you use
git push
Git says, “Whoa, hold on! I can’t add the dg34mp
commit because there is an extra commit on the remote server we haven’t taken into account!” (a.k.a. I don’t know how to handle zyx911
, “failed to push some refs”).
What do we do?
First, we make a backup copy of our master
branch, in case something goes wrong. (This isn’t strictly necessary because of git reflog, but I find making a backup branch quicker and involving less thought). Once we make this backup branch we’re going to ignore it and ultimately when we’re done with this process we can delete it.
git branch bkup
Now, we rebase our master
branch with the remote branch origin/master
.
git rebase origin/master
This replaces our local master
branch with the remote origin/master
and then adds our new commit (dg34mp
) on top.
master origin/master
dg34mp
zyx911 zyx911
cem32k cem32k
b4d2o1 b4d2o1
abc123 abc123
Now we can push our changes to the remote server (origin/master
)
git push
and there is no problem because we are simply adding our new commit (dg34mp
) to the remote branch.
thanks for this information. it took me a while to understand that.
Thanks for this explanation. Really helped me when I had pushed a change and then needed to do a change to the same branch. I appreciate it!
Yeah …that solves it!!!!
thanks for sharing