Remove other peoples' commits on my branch after rebase gone wrong
What's the best approach to clean this up? Everything is suggesting to use git rebase, however, I was advised not to use rebase.
Even though the team does not use a rebase workflow themselves, it might be the better approach to fix unmerged branches. As long as you are sure that no one else is using and you are aware of the possible implications if that's not the case.
Note: I assume your remote is named origin and that the branch was created on master. If that's not the case, just replace them with the appropriate ones.
Before anything, stash all modifications (if any):
git stash save
And checkout to your branch:
git checkout mybranch
(Recommended) Backup the branch as is with a temporary tag:
git tag mybranch_bkp_rebase
Rebase
As mentioned, you can rebase to the point where the branch was created and delete the lines whose commits are not relevant to your branch.
git rebase -i "$(git merge-base origin/master HEAD)"
With that, the only commits left in your branch will be the ones that already were there when you created the branch, plus the commits from the lines that weren't deleted.
(Optional) After checking that everything is in order, you can rebase to the current master:
git rebase origin/master
Reset
If you don't want to rebase, you could just reset to a previous known good state. That could be either a commit in your own branch, the commit it was created on or the current master:
# Pick one
last_known_good_rev=hash_of_last_good_commit
last_known_good_rev="$(git merge-base origin/master HEAD)"
last_known_good_rev='origin/master'
git reset --hard "$last_known_good_rev"
Then check with git log
for commits that might be missing:
git log --oneline mybranch_bkp_rebase..HEAD
And cherry-pick
them:
git cherry-pick hash1 hash2 hash3
Your best bet to clean stuff up is probably to use git rebase -i
to rebase on a previous change already in you branch1 before all the stuff you want to clean up, and then delete the changes you don't want from the list of changes in the editor (leaving just the changes you do want). That will rewrite the changes to include just your changes and get you back into a "clean" (relatively) state.
Once you've done that, you can then git merge
from master (or wherever) as recommended by your git flow.
1Possibly the change you originally branched from if you want to clean out everything you prevously rebased/merged into your branch, or possibly some later refpoint. The earlier the point you choose, the more stuff you (can) clean out, but also potentially the more work you need to do.
// from feature_branch make some changes git commit -am "New changes" git checkout master git checkout feature_branch git rebase origin/master git push feature_branch
Once I did this, I noticed my PR (on Github) picked up someone elses' commit.
If all you did was rebase on top of origin/master
that should not have been possible.
However, this sequence is a bit fishy. You never do a git fetch
so origin/master
is not known to be up to date. If a rebase did happen, git push feature_branch
should have failed because a rebase cannot be fast forwarded. You would have had to use git push -f feature_branch
.
I suspect something else went wrong that you're not showing us. A complete history of your commands would help.
The proper sequence for updating a branch with rebase is this.
# Update all your remotes
git fetch
# Rebase your branch on top of origin/master
git checkout feature_branch
git rebase origin/master
# Force push the branch
git push -f
Fortunately your old commits are not lost after a rebase, they're just not connected to anything. To find them, use git reflog
. This will show every time HEAD
(ie. your current checkout) changed.
In the reflog, look for something like this...
081abed HEAD@{8}: rebase finished: returning to refs/heads/feature_branch
081abed HEAD@{9}: rebase: the last commit message from your branch
0a5b366 HEAD@{10}: rebase: another commit message
e9c4d18 HEAD@{11}: rebase: the first commit message from your branch
e6780bf HEAD@{13}: rebase: checkout origin/master
0ee63b1 HEAD@{14}: checkout: moving from master to feature_branch
0ee63b1 will be your old branch tip. git reset --hard 0ee63b1
and you've undone the rebase.
There's an alternative explanation: that you've made your PR against the wrong branch. Double check that.