Rebase a branch onto a different branch in Git

To avoid using merge commits, you can opt for an alternative method that involves enabling git rerere. This technique, as explained in this article, allows you to perform intermediate merges, resolve conflicts, and then reset the merge commit. You can either go for option 1, which entails merging the develop branch into feature branch, or option 2, originally introduced by Klas Mellbourn, which involves rebasing the feature branch onto develop. While the latter option creates a more streamlined history, it can pose challenges if there are other commits based on the feature branch.


Solution 1:

Provided ‘feature’ is a local branch, my suggestion would be to base it on ‘develop’.

Combining ‘develop’ and ‘feature’ results in an unnecessary merge commit. However, opting for a rebase allows for the assimilation of all updates from the master branch and enables conflict resolution before merging ‘feature’ with ‘develop’, sans any additional commit creation.

While there may be dissenting opinions, I personally prefer a clear and easily understandable history. To achieve this, after completing a feature, I first perform

rebase

and then proceed to

merge --no-ff

. This ensures that the history reflects the existence of a feature branch in a concise manner.

- * - * - - - - - - - * - * -
                    /
        * - * - * - *

My approach towards conflict resolution involves addressing them “continuously” and early on to prevent any further complications. This aligns with the principles of continuous integration. However, if I were to frequently merge, it would result in numerous merge commits. To avoid this, I prefer to utilize frequent rebases.

Git rerere can be enabled as an alternative approach to employ merging without merge commits.

git config --global rerere.enabled true

This article explains that after completing intermediate merges and resolving conflicts, you can reset the merge commit. By using the rerere feature, Git will remember the conflict resolution for the final merge of the ‘feature’ branch.


Solution 2:

Adding all the commits to

feature


The commits made on the “develop” branch following the split will be applied to the “feature” branch without any impact on the “develop” branch.

Current state:

M1---M2---D1--D2--T1--T2  develop
      
       F1--F2  feature

The first option is to combine the “develop” section with the “feature” section, as shown in

git checkout feature; git merge develop

.

M1---M2---D1--D2--T1--T2  develop
                      
       F1--F2-----------F3  feature

Klas Mellbourn’s suggestion, which is Option 2, proposes to rebase the feature onto the develop branch. This can be implemented using the following MSDTHOT code:

git checkout feature; git rebase develop

M1---M2---D1--D2--T1--T2  develop
                       
                        F1'--F2'  feature

Using

rebase

results in a more pleasant history, but it can pose issues if other commits rely on the same feature. Fortunately, this is not a concern in your situation as there are no such commits.

Adding some commits to

feature

In case the commits labeled as

D1

and

D2

are not yet prepared to be included in the feature, you can still perform the task by making use of

git cherry-pick

to duplicate the commits into the feature.

M1---M2---D1--D2--T1--T2  develop
      
       F1--F2--T1'--T2'  feature

The execution of

git rebase

will result in the transfer of commits rather than duplicating them.

Separate topic branch

Another approach is to create a separate topic branch that relies on an earlier shared ancestor when creating new commits.

       T1--T2  topic
      /
M1---M2---D1--D2  develop
      
       F1--F2  feature

By utilizing the graph, the topic can be integrated into both the development and feature branches, while avoiding the inclusion of redundant or unnecessary commits.

Frequently Asked Questions

Posted in Git