Interactive rebase
Tags: git, rebase
Published: 2021-11-15 23:07:21

---
title: Interactive rebase
published: true
date: 2021-10-21 00:00:00 UTC
tags: git,rebase
canonical_url: https://insight-services-apac.github.io/2021/10/21/interactive-rebase.html
---

The purpose of this article is to document the steps involved in performing an interactive rebase as an easy reference for clients without paid tools to simplify the process. By the end a git novice should be able to follow along unassisted.

### Pre-requisites

Rebase can be executed from Visual Studio Code, many IDEs or the command line. The following tools can be used to simplify the process:

- Git graph viewer: VS Code with [mhutchie.git-graph extention](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)
- Some means of doing git commands from the CLI [from here](https://git-scm.com/downloads)

### What is Rebase

A rebase is a way of integrating work to branches as an alternative to using a standard merge. The difference between the two is as time goes on normal merges can lead to a very messy git graph and make it difficult or impossible to find how work was merged. The way that rebase simplifies this issue is by actually re-writing the history so that it is as though the changes were made right on top of some later commit.

Unfortunately rebases can be more complicated making many people scared of them despite the advantages. But a rebase can be as simple as a couple of commands which I’ll put below before I get into the more complicated topic of the interactive rebase. To do a standard rebase:

1. Checkout the branch to be rebased
2. Run `git rebase origin/target-branch`
3. If there are no conflicts and the process completes run `git push origin --force`

A lot of the time those two commands are all that is required. However many commits you have made are replayed on top of the target branch. When complete it will look like you have made your changes starting from the last commit of your target branch rather than some earlier point in the history.

### Guide to interactive rebase

Chances are that you will always try to do it the easy way first as above. The first thing is to cancel the rebase using `git rebase --abort`.

The next thing you should do is check the graph to see what work is actually yours. It may take time to learn this part but eventually you should be able to quickly glance through the nodes of your branch and determine what is your work vs. stuff that you have merged in.

Now comes the fun bit. You run `git rebase --interactive origin/target-branch` while on your branch. This will open a _vim_ editor in your terminal. To make life easier here are some commands that will help make use of it.

| Vim commands | Description |
| --- | --- |
| **i** | Press the _i_ key when not in interactive mode to enter interactive mode and edit the commits list. |
| **Esc** | Press the _Esc_ key when in interactive mode to exit and use other key commands. |
| **:wq** | While **NOT** in interactive mode press this key sequence to save changes and close the vim editor. |
| **:q!** | While **NOT** in interactive mode press this key sequence to close vim without saving changes. This is useful in case the edits do not look correct. |

So in the vim editor that opens you will see something that looks like the following example. It is already telling you how to do a few interesting things, but your changes will ultimately come down to putting a _d_ or _drop_ next to the commits that you don’t want to be rebased. **NOTE** When you run the rebase there will be instructions as well which I’ve omitted for brevity, but read it through for a full understanding of what can be done in an interactive rebase.

```
pick 442a48288 Adding publication form
pick 9e4588745 Publication date component
pick b503173d8 Test updates for form
pick 460c79b2f Portal settings integration with publication dates service

# Rebase e7403349a..460c79b2f onto e7403349a (4 commands)

```

In the example above the branch that is being rebased consists of 4 different commits and will default to rebasing all commits. But if the target branch already had the final commit I could do the following:

1. Start the interactive rebase from the branch to rebase. This will open a vim session in the CLI
2. You will see something resembling the example above. Press _i_ to enter interactive mode
3. Update the commits that are no longer required with _drop_ e.g. `drop 460c79b2f Portal settings integration with publication dates service`
4. Press _Esc_ to return to command mode
5. Press _:wq_ to close the editor and save the changes
6. The rebase will now continue automatically
7. If there are conflicts you will need to resolve them

As many commits as are necessary can be dropped from the rebase. Identifying those that are already committed in the target should be fairly trivial in a lot of cases. To help use a git graph tool to look at the commits and identify commits that can be dropped without issue.

### What about conflicts

If you have conflicts then they will need to be resolved. To do this you need some tool to compare the changes in your branch and the target and decide how to resolve it. Broadly there are 4 options to resolve it:

When you have a conflict in a file you should be able to see it in the git tab of VS Code. If you click on the file there you will see a diff of the file with the conflicts highlighted in blocks like this:

![Top of the conflict block](https://insight-services-apac.github.io/assets/images/interactive-rebase/conflict_top.png "Top of the conflict block")The current commit of the rebased branch’s changes will be here.

The current state of the target branch’s changes including previous rebased commits. ![Bottom of the conflict block](https://insight-services-apac.github.io/assets/images/interactive-rebase/conflict_bottom.png "Bottom of the conflict block")

| Command option | Description |
| --- | --- |
| Accept Current Change | Take just the change in the target branches changes. **Remember** that this will include any rebased commits that are already done |
| Accept Incoming Change | Take just the change from the current commit being rebased |
| Accept Both Changes | Take both of the above changes. **NOTE** this will often require additional editing |

You can also use git commands to progress the rebase. Typically you will run the continue command after selecting one of the options above but other commands are listed below. It will then open a vim editor with that commit’s message. If you aren’t changing it just use the vim close command.

Below are commands that can be typed in the git rebase terminal to continue actions.

| Command | Description |
| --- | --- |
| git rebase --continue | Continue to the next commit of the branch to be rebased. All conflicts must be resolved for this to succeed |
| git rebase --skip | Skips the current commit from the branch being rebased |
| git rebase --abort | Abort the rebase and return the branch to its pre rebased state |

### When not to Rebase

Just because you can do something doesn’t mean that you should. 99% of the time you should **NOT** rebase a branch that is used by multiple people. The reason for this is that the re-write in the history will make it as though the branches diverged and make the other developers lives more difficult as a result. If you only rebase your own branches then you should never run into issues.

### How can it go wrong?

Occasionally you will have to take a change from another branch such as some API updates possibly before they are completed to the target branch. When you eventually go to PR your changes if those changes are already merged before that you will get conflicts. But this can be avoided using the interactive rebase.

Even if you haven’t merged from another branch sometimes someone will happen to alter code in the same area as you.

So you do a rebase and you get conflicts. If you know that you have merged other changes into your branch that have already made their way into your target then you would be better doing an interactive rebase to at least avoid those conflicts. Otherwise you can resolve the conflicts as normal.

### References

If you would like to read further on the above topics you can find further info at:

- [git rebase](https://git-scm.com/docs/git-rebase)