Home > Software design >  Did I git rebase?
Did I git rebase?

Time:01-10

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?

CodePudding user response:

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

CodePudding user response:

The message you received usually1 means your branch is diverged with its remote counterpart. The most common scenarios for this are:

  1. After previously pushing your branch, you integrated the latest changes from a remote base branch, perhaps origin/main, by rebasing your branch onto the newer version of it.
  2. After previously pushing your branch, you interactive rebased your own branch or amended your tip commit.
  3. Someone else pushed commits to your branch.

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:

  • If you're in scenario #1 or #2, pulling with merge will bring back in your old commits. (This is bad if you don't notice.)
  • Rebasing onto the remote in scenario #1 will rewrite all of the new commits from the shared branch! (This is really bad if you don't notice.)
  • Force pushing in scenario #3 will blow away someone else's commits. (This ranges from bad to really bad if you don't notice depending on how nice that person is.)

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:

  1. You're using GitLab. (I only know this because you said MR instead of PR, and this is of course irrelevant...)
  2. You changed something about your code, based on a suggestion. If you amended your tip commit this leads to scenario #2. If you created a new commit with the changes, then any of the 3 scenarios is possible (if you did #1 or #2 weeks ago without pushing) and/or someone added a new commit to your branch.

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.

  • Related