2

I rebased changes from a remote repo upstream master into my local dev branch and then tried pushing the changes to my repo using these commands:

git pull --rebase upstream master
git push origin dev

but the later command resulted into that error:

error: failed to push some refs to 'https://github.com/m-adil/some_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.

This is what that I'm facing for the third time but didn't come across with a perfect solution yet. Doing git pull ... as suggested in second last line of error, results in producing all the conflicts again that ruins the recent git pull --rebase .... In such cases git reset --hard HEAD@{1} remediates but what is the best approach in this case to push your changes?

I explored this and found several similar questions here but with some minute distinctions that don't clarify this issue to me. Most of the selected answers suggests to do git push --force origin my_branch but it has cons as well and one can lose his changes in remote so this can't be suggested. The best thing I came to know yet is to create & checkout to a new branch which is better than many other answers/solutions. But this is more like a trick to escape from this issues rather than a right approach to deal with that situation. So can any body please clarify by sharing the right approach in this case?

Community
  • 1
  • 1
Adil
  • 21,278
  • 7
  • 27
  • 54
  • 2
    Why did you rebase `upstream/master`? This rewrites your local history in a way that is incompatible with `origin/master`, which is why you're seeing errors. You should only `pull --rebase` when you're sure that it won't cause such historical conflicts (e.g., when there's only one remote). – Will Vousden Apr 27 '17 at 08:32
  • What branch were you actually on when doing these commands? Do you really have the same branch across two different remotes? – Tim Biegeleisen Apr 27 '17 at 08:36
  • @WillVousden Sorry I didn't get exactly what you mean, can you please explain it bit more? I'm working with a remote repo i.e. upstream master. My coworker did some changes in his repo (upstream repo) and I wanna rebase his changes with my local repo. – Adil Apr 27 '17 at 09:05
  • @TimBiegeleisen Is that necessary to be on a same named repo? That could be the issue if so. I'm working on `dev` branch and want to rebase changes from `upstream master` – Adil Apr 27 '17 at 09:05
  • I had deleted an earlier comment which basically said that if you rebased a local `master` branch on the remote `master` and then pushed to the same remote, you should _not_ be getting these errors. There isn't anything wrong with using rebase in this way AFAIK. Update your question with what you are really doing. – Tim Biegeleisen Apr 27 '17 at 09:06
  • @TimBiegeleisen please give it a look now, I updated fist line of my question, hopefully that would be clear now. – Adil Apr 27 '17 at 09:09
  • Last question: Is the `dev` branch public or shared by anyone other than yourself? – Tim Biegeleisen Apr 27 '17 at 09:10
  • Nope its private and just me alone is working on `dev` branch – Adil Apr 27 '17 at 09:11

1 Answers1

4

Since your dev branch is private and you are the only one using it at the moment, then there is nothing inherently wrong with rewriting its history and then doing a force push. As you noted, the way to get around the error you are getting is to force push to the remote, e.g.

git push --force origin dev

This would overwrite the remote dev branch with what you had locally. But since no one else can see this other than yourself, it should be safe to do.

By way of diagrams, consider that dev starts off on the remote with one additional commit beyond what master has:

master: ... A -- B -- C
                       \
dev:                    D

Now, someone else has done some work in master, and pushed that work. Let's say it's just a single commit, leaving us with this:

master: ... A -- B -- C -- E
                       \
dev:                    D

Locally, you did a rebase of dev on master, which gives us the following branches (note that one dev is marked as local):

master:    ... A -- B -- C -- E
                          \    \
dev:                       D    \
                                 \
local-dev:                        D'

But now, when you try to push local-dev to the remote dev, Git gets confused. It is confused because what is has remotely is the D commit on top of C. But your local branch, which you are trying to push, has commits E--D' on top of C. It can't resolve this automatically, so it fails. Doing the force push gets around this, which in your situation should be an acceptable thing to do.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360