Reputation: 241
I've come back to some code I was working on a few weeks ago (before the holidays). I've made changes based on some comments left in a merge request.
I went to push my changes and I get the error:
! [rejected] my_branch -> my_branch (non-fast-forward)
error: failed to push some refs to '<remote>:my_repo.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.
I recognize this as the message I get when I try to push after a rebase (needing to force push); however, I don't remember rebasing (I might have, I just don't remember).
I'm hesitant to force push when I don't really know what I'm pushing.
So my questions: Is there a way to check if my branch (specifically my local) has been rebased? Is there something other than a rebase that could likely cause this error (if not then I can probably assume that I did just rebase a few weeks ago and that it's probably safe to force push)? Any other suggestions on how to safely deal with this situation?
Upvotes: 1
Views: 444
Reputation: 28934
The message you received usually1 means your branch is diverged with its remote counterpart. The most common scenarios for this are:
origin/main
, by rebasing your branch onto the newer version of it.It's important to know which it is because the action you should take for #1 and #2 is a force push, whereas the action you should take for #3 is to pull (with merge or rebase), or rebase your branch onto the remote version- see phd's answer for details on resolving Scenario #3.
You definitely don't want to get it wrong though in either case, because:
So it's important to get it right. Based on your first sentence:
I've come back to some code I was working on a few weeks ago (before the holidays). I've made changes based on some comments left in a merge request.
I think it's safe to assume two things:
Now let's see what happened:
This happens to me quite frequently. I switch to one of my personal branches I wish to work on, I type git status
and see that my branch has diverged from the remote, and for example it tells me I'm 300 commits ahead and 2 behind. In this case I know I rebased, but I might still look anyway:
git log @{u} -n3 # show me the top 3 commits of my remote branch
git log @ -n3 # show me the top 3 commits of my local branch
I expect to see the same 2 commits with the same author (me) and author dates, but with different commit IDs. The 3rd commit should be newer on my local branch meaning I simply rebased onto a newer version of the base branch. (Scenario #1)
Note if my divergence numbers are 2 and 2, and the 3rd commits are the same ID, then this means instead of rebasing onto a target, I probably did an interactive rebase or amend (Scenario #2), and this makes it easy to view the diff:
git diff @{u} @
In general, I tend to always use git push --force-with-lease
so I'm confident after looking that I can push. If the --force-with-lease
still fails, I simply git fetch
, then git status
, and repeat the above steps to see what I'm missing.
If when comparing the logs you see someone else's commit on the remote branch, then you know someone else pushed a commit and you need to bring it into your branch so you don't blow it away. If you're in Scenario #1 and/or #2, and also Scenario #3, meaning someone pushed a commit to your old version of the branch, then you might need to do a little surgery on your branch using the rebase --onto
option.
1 Another possible way to get this message is if you aren't diverged and instead are only behind the remote branch. In that case though you don't have any new commits to push and instead you could simply do git merge
or git pull
or git reset --hard @{u}
, or even git rebase @{u}
all of which would have the same effect.
Upvotes: 1
Reputation: 94425
Non-fast-forward error could be a result of you trying to push new commits when another contributor just pushed different new commits. The way to check for it is git fetch
, git diff origin/my_branch
and git log origin/my_branch..my_branch
. The way to remedy is git pull --rebase origin my_branch
or
git fetch origin
git rebase origin/my_branch my_branch
git push origin my_branch
Upvotes: 3