# Matthieu Vergne's Homepage

Last update: 07/01/2022 18:22:19

# How to Rebase a Git Branch Iteratively?

## Context

While we work on our own branch, other changes might be merged in the main branch. At some point, we might want to rebase our work on them, at least before to merge. If our branch lives a long time, it is better to do it on a regular basis to avoid having to rebase on a lot of changes at once. However, it sometimes happens that we have to rebase an old branch on many commits, like a forgotten branch that we want to update.

## Question

The main issue is the heavy effort required to integrate a lot of changes at once. Instead, we would like to integrate a small piece of it, one at a time. It would allow to go one easy step after another, and stop at some point to continue later. In other words : how to rebase a Git branch iteratively?

## Method

Before to go, identify the branch or commit to rebase on:


BASE=<branch or commit>


If it is a remote branch, don't forget to get its last commits with git fetch (not git pull, which is a fetch+merge).

It is possible to rebase your branch on this base one step at a time, in a controled way. To do so, instead of rebasing all at once, we can rebase one commit (or some of them) at a time. We can repeat the operation until we reach the most recent commit. There is, however, two ways to understand an "iterative" rebase:

1. iterate your own branch: rebase one commit of your branch on the most recent commit of the base branch
2. iterate the base branch: rebase all your branch on the immediately next commit of the base branch

The point 1 is not what we will focus on in this article. Indeed, this is the usual way to go and how Git works, so there is plenty of support for that elsewhere if you are interested. By using a classical rebase, Git helps you to redo each of your commits on the base branch. However, you will remain stuck in the rebase process until all your branch is rebased. Instead, you can create a temporary branch on the base and cherry-pick your commits one at a time. It allows you to stop and continue later if needed, but you will have to deal with the new commits added to the base branch, enforcing you to redo it. In any case, you rebase on a lot of commits at once, meaning you have to integrate a lot of changes in your branch in a single pass.

Here, we deal with point 2. The difference is that we assume that you master the content of your own branch, but discover progressively the new commits of the base branch. You can clean your branch to reduce the conlicts resolution efforts, but then you go for rebasing all of it on a single (or few) new commit(s). If new commits are added to the base branch during the process, it changes nothing to the procedure, just executing more iterations of it. Here is the procedure to repeat until the rebase is complete:

Step Goal Command
1 Display the remaining commits to rebase on
git log --oneline HEAD..${BASE} 2 Identify the target commit to rebase on  COMMIT=$(git log --pretty=format:"%h" HEAD..${BASE} | tail -1) # Retrieves the next commit of the base branch git log --oneline${COMMIT} | head -1                          # Confirm the target commit


We can use a more recent commit from the list provided in the previous step to rebase on several commits at once. The critical point is to target a commit that passes all the tests.

3 Analyse the changes brought by the target commit to estimate the potential conflicts and other required actions
git diff $(git merge-base HEAD${BASE}) ${COMMIT} 4 Rebase your branch on the target commit and resolve potential conflicts git rebase${COMMIT}
5 Update submodules if you use them
git submodule update
6 Validate the rebase
mvn clean test # If you use Maven

Adapt this step to your context. If you have automated or manual tests that can be executed, do it. If other tests are adapted to a more recent state and are expected to fail for now, ignore them. If you are on the last iteration and the rebase is complete, all the tests should be executed.