I try to understand what I am doing wrong but nothing. I am totally confused. I know that another way to merge branches (or commits) is to use "git rebase". I have 3 branches: master and 2 others for different features. Let's talk about master, f1 and f2. I am working on my f1, and I need another feature, so I create f2. when I finish with f1, master has already another changes. I want to rebase f1 on master. I did it, and I see 144 steps. I try to fix all commits and I push the changes. Now I apply my f2 commits to f1 and decide to do a pull request to master. I try to rebase f1 on master and I get 244 steps. or it is just 4 new commits on master. And I already get them on my local master.
I am so confused. Everytimes I want to use rebase, it seems I get more steps that commits really done.
I must tell that in the beginning I was just doing merges with "git merge" but I was asked to do them with "git rebase".
I try to search why I have too much steps, I followed tutorials again, but I cannot try to fix more that 200 steps again. It is boring and needs time. Can you explain me more and help to fix this situation, please? I do not want to fix this now and get more than 300 later. thanks
The golden rule of git rebase is to never use it on public branches. The rebase moves all of the commits in main onto the tip of feature . The problem is that this only happened in your repository. All of the other developers are still working with the original main .
That is a misunderstanding of what rebase does, and I believe this is what has created this very frustrating situation.
What might have happened
Suppose you have the follow situation (which I believe is what you described).
master o---o---o---o---o---o
\
feature1 A---B---C
\
feature2 X---Y---Z
You're done with work on feature1
, but there are some commits on master that haven't been tested with the feature1
changes. So, to update feature1
you do the following:
git checkout feature1
git rebase master
This results in the following situation:
master o---o---o---o---o---o
\ \
feature1 \ A'---B'---C'
\
feature2 A---B---C---X---Y---Z
Wait, what? Why are there two copies of A-B-C
!?
That's what rebase
does. Rebase
makes NEW commits starting from the base given in the command (master
in this situation).
What probably happened next
Now that feature1
has been updated with the latest from master
, you need to update feature2
. So, you follow the same process:
git checkout feature2
git rebase feature1
This results in the following situation:
master o---o---o---o---o---o
\
feature1 A'---B'---C'
\
feature2 A"---B"---C"---X---Y---Z
Uh oh.
As you can see, after a few times through this cycle you end up in a very bad place where you have to resolve "conflicts" that are just applying the same changes over and over.
How to fix the current mess
Just bite the bullet and use merge
. Seriously, this is the fastest way to deal with it. Update the feature branches from master
with git merge master
and then merge
the feature branches back into master (when appropriate).
Alternatively, you can delve into the dark magic that is interactive rebase. Use the -i
flag when running git rebase
and you will see a list of all commits it is attempting to reapply. Remove the duplicates and carry on your merry way. I don't like this approach because it's easy to make a mistake, and it's a PIA to recover from these mistakes.
How to avoid this going forward
Detailed article
In short, you need to tell git to ignore the duplicated commits. Updating feature1
using rebase
was fine, the problem happened with feature2
.
git checkout feature2
git rebase --onto feature1 feature1@{1} feature2
Which gets us
master o---o---o---o---o---o
\
feature1 A'---B'---C'
\
feature2 X'---Y'---Z'
Exactly what we wanted!
So, what is this command doing?
git rebase --onto feature1 feature1@{1} feature2
--onto feature1
- we're going move these commits onto the branch feature1
feature1@{1}
- We just rebase
'd feature1
, so we need to get the previous commit (IE the one before the rebase). This is the start of the commit range we're movingfeature2
- This is the end of the commit range we're movingNOTE: feature1@{1}
will work when used as part of the process described in the article, but may not be correct if other git commands are run between updating feature1
and feature2
. In this instance, you can substitute this for the raw commit id - obtained by reviewing the output from git log
while on feature2
and selecting the last commit from feature1
("C" in the example given here).
Other Good Reading:
Atlassian article: Merging vs Rebasing
When do you use Git rebase instead of Git merge?
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