I recently rebased a branch that I was working on. The history of the tree looked something like this:
1 = 2 = 3 = 4 \ 5 = 6 = 7 \ 8
I wanted to rebase my changes (number 8 in the diagram) to be on the master branch (up to commit 4 on the diagram now). So I did the following:
git checkout my_branch git rebase master
< lots of git mergetool/git rebase --skip to resolve conflicts >
Only now when I run:
git checkout my_branch git diff master
I get zero differences. I haven't lost my branch (I can still recreate my changes from a patch that I saved) but I can't find the merge/rebase that I did. What did I do wrong? Is the rebase still there somewhere with my changes merged with the master or do I have to do it again?
Rebasing can be dangerous! Rewriting history of shared branches is prone to team work breakage. This can be mitigated by doing the rebase/squash on a copy of the feature branch, but rebase carries the implication that competence and carefulness must be employed.
rebase does not lose any history at all. Every single commit that you used to have is still there.
What is git rebase? From a content perspective, rebasing is changing the base of your branch from one commit to another making it appear as if you'd created your branch from a different commit. Internally, Git accomplishes this by creating new commits and applying them to the specified base.
If you're not seeing any difference, I suspect you lost your changes. You can likely use git reflog
to identify the branch that existed before the rebase, and use git reset --hard <my-branch-tip-before-rebase>
to get back the original branch. And yes, you'll have to run through the process again. :-(
I'm not quite sure how you ended up with them looking the same though. I would have expected to see the following with the command you gave:
1 = 2 = 3 = 4 (master) \ \ \ 5' = 6' = 8' (my_branch) \ 5 = 6 = 7
In this case, you probably should've used rebase --onto
:
git rebase --onto master <commit id for 6> my_branch
That would have left you with a graph that looked like this:
1 = 2 = 3 = 4 (master) \ \ \ 8' (my_branch) \ 5 = 6 = 7
As far as losing your changes, it does take a bit of practice dealing with merge conflicts, especially when you have a couple of big blocks that look nearly identical. I always resort to looking at the actual diff introduced by a commit, and the attempting to tease out that change and merge it with what is already on the branch in an appropriate way. I can easily see how your change may have gotten lost in there.
One thing to remember. If you don't expect a bunch of merge conflicts--because you don't feel the sources diverged enough, the seeing one is a warning flag of doing something wrong. It's good to back up, by doing a git rebase --abort
, investigating the branches and checking again if you expect a conflict. Make sure to take note of where the conflict happened (there's usually a "Applying ..." just before rebase kicks you to the command line). That's usually a great place to start.
At times, conflicts are unavoidable, and are tedious to work through. But I suspect with practice, you'll run into this problem less.
For more information on transplanting changes between branches, look at the git rebase man page. Search for "rebase --onto". The first hit should land you in a section talking about transplanting changes to another branch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With