Reputation: 30297
I have a feature branch branchX
that is using some-remote/base-branch
as its upstream branch. I just discovered that some-remote/base-branch
got its history rewritten by a force-push. What are the problems involved and how can I work around it?
Upvotes: 3
Views: 407
Reputation: 30297
The biggest problem that this brings is that you should get rid of the revisions that were rewritten from the old upstream branch so that when you push your feature branch, they are no longer there.
If you tried rebasing your branch on top of the new branch (say, git checkout branchX; git fetch some-remote; git rebase some-remote/base-branch
) git will not only rebase the revisions of your feature branch but also the revisions that have already been moved out of the new rewritten branch... which is a no go. Same thing if merging. So a simple git pull
(merging or rebasing) won't get you out of the mess... actually, you might very well dig yourself deeper into the mess.
If you decided to keep them as if nothing happened, you will get into the history of the new upstream branch, revisions that have already been removed from it and, more than likely, there is no need to keep them (because.... why was the history of the branch rewritten in the first place, right? If it was rewritten, those old revisions are not to be seen anymore).
It might seem like it is a big deal, but quite frankly, it is not that hard to get out of the situation. The trick is to move only revisions of your feature branch on top of the new rewritten branch leaving behind the old branch. So, this is the procedure, assuming that the branch for your feature is a straight line with no merges:
Find out in the history of your feature branch (say, with git log
or gitk
or any other means necessary), the last revision from the old upstream branch that is in your feature branch. Say you get the ID of that revision and let's call it old-base-rev
.
Fetch from the remote to get the new rewritten history of the upstream branch.
git fetch some-remote # adjust to the name of your remote, of course
This is where the magic happens:
git rebase --onto some-remote/base-branch old-base-rev branchX
This way git will only rebase the revisions that actually make up the work on the feature branch itself and not the old upstream branch.
And that's it. You are free to continue working on your branch as if nothing happened.
If you are dealing with a feature branch that is not straight (it has had merges of the upstream branch instead of rebasing it), you might use the same recipe I provided, however, if you had to solve conflicts when merging the upstream branch, that will be tricky. If you want to avoid having to deal with the conflicts again, perhaps the best you could try is to get your changes for your feature branch into a single revision and then attempt the magic trick. After having found what the last ID of the old base branch is in your feature branch:
git reset --soft old-base-rev
git commit -m "Single revision for feature X"
Now all your changes have been collapsed into a single revision on top of old-base-rev
. Then you can follow the recipe with the fetch/rebase steps.
git fetch some-remote
git rebase --onto some-remote/base-branch old-base-rev branchX
Upvotes: 8