---
title: "Speeding up interactive rebase in JetBrains IDEs"
source_name: "The JetBrains Blog"
original_url: "https://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/"
canonical_url: "https://www.traeai.com/articles/0c9d92b9-be87-4114-9803-95462fbb06d7"
content_type: "article"
language: "英文"
score: 8.5
tags: ["Git","JetBrains","性能优化","IDE开发","底层原理"]
published_at: "2026-04-14T10:33:37+00:00"
created_at: "2026-04-16T08:24:35.10209+00:00"
---

# Speeding up interactive rebase in JetBrains IDEs

Canonical URL: https://www.traeai.com/articles/0c9d92b9-be87-4114-9803-95462fbb06d7
Original source: https://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/

## Summary

JetBrains 官方详解如何通过 Git 底层 plumbing 命令优化 IDE 中的交互式 rebase 性能。文章深入剖析 Git 对象模型与索引机制，提出在内存中直接构建提交树、避免操作工作区与 index 的优化方案，显著提升了大仓库下的 rebase 速度。

## Key Takeaways

- 传统 IDE 集成 Git 依赖 porcelain 命令，在大仓库中易因频繁读写 index 和工作区导致 rebase 性能瓶颈。
- 利用 git cat-file、commit-tree 和 merge-tree 等底层命令，可在内存中直接构建和合并提交树。
- 跳过 index 与工作区同步，直接通过 update-ref 原子更新分支引用，可大幅降低交互式 rebase 耗时。

## Content

Title: Speeding up interactive rebase in JetBrains IDEs | The JetBrains Platform Blog

URL Source: http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/

Markdown Content:
[![Image 1: Platform logo](https://blog.jetbrains.com/wp-content/uploads/2019/01/JetBrains-icon-1.svg)](https://blog.jetbrains.com/platform/)
Plugin and extension development for JetBrains products.

[IntelliJ Platform](https://blog.jetbrains.com/platform/category/intellij-platform/)

## Speeding up interactive rebase in JetBrains IDEs

![Image 2: Aleksandr Krasilnikov](https://blog.jetbrains.com/wp-content/uploads/2026/04/2026-04-14-11.33.13.jpg)

April 14, 2026

## Introduction

Git integration in JetBrains IDEs has been evolving for more than fifteen years, and throughout that time, we followed one guiding principle: At the lowest level, we simply run porcelain Git commands, parse their output, and avoid doing anything Git itself would not do. All user scenarios and UI are built on top of that. This approach kept the integration reliable and made it much less likely that the IDE would corrupt the repository state.

Over time, Git grew more complex, repositories grew larger, and some operations became noticeably slower. By then, the pattern was hard to miss. We saw more community projects focused on Git performance, users kept reporting slow command execution, and we could reproduce the issue ourselves. Even rewording a single commit in the IntelliJ IDEA monorepo could take tens of seconds, depending on the machine and OS.

Interactive rebase was one of the clearest pain points, along with several IDE actions built on top of it. So we decided to focus on low-level optimizations there and turn the work into a dedicated internship project.

## Interactive rebase: A technical deep dive

To see where those seconds went, we need to look at what Git actually does during an interactive rebase.

Internally, Git has three main kinds of objects, stored as files in the `.git/objects` directory: blobs, trees, and commits. Every object is identified by a unique 20-byte SHA-1 hash.

*   A **blob** simply contains the contents of a file.
*   A **tree** is a recursive object that corresponds to a directory. It can contain individual files, represented as an entry with a file name, mode, and the respective blob’s hash, as well as subdirectories, represented by the names and hashes of other trees. Because an object’s hash is unique, Git can reuse files and directories when they are identical.
*   A **commit** is essentially a tree with metadata. It contains the hash of its parent commit(s), author and committer information with timestamps, and a commit message. Each commit represents a snapshot of the entire directory; the diff between a commit and its parent is computed by comparing their two trees.

The **index** is a map linking file names to blob objects, sorted by file name. It acts as a scratchpad for Git operations. For example, during a merge, the index expands to hold three entries for a single conflicted file. It keeps these entries unmerged so that Git can create conflict markers in the working directory. After you resolve the conflicts, running `git add`marks the entries as merged. Following these operations, Git writes a new tree object from the current index using `git write-tree`.

![Image 3](https://blog.jetbrains.com/wp-content/uploads/2026/04/image-33.png)
Now, let’s consider how an interactive rebase is performed. To build a sequence of commits according to the `git-rebase-todo` file, Git checks them out sequentially, updates the working tree, and populates the index so that it can create a tree object from it. This can impact performance. However, in some scenarios, we can construct these trees without touching the index.

## In-memory rebase optimization: How it works

The optimization for _Edit Commit Message…_ is the simplest case. If you look at the sequence of commits from the selected one up to the top of the branch, the underlying tree hashes do not change during this operation. For the selected commit, we only need to change the commit message and committer information. Then, for every commit after that, we just rebuild the chain by updating the parent commit and computing a new hash.

Git provides low-level plumbing commands for managing Git objects. Using `git cat-file`, we can extract and parse the body of an object. We can create a new commit object by passing a tree hash and metadata to `git commit-tree`. Once the whole sequence has been rebuilt, we can use `git update-ref` to atomically update the branch reference.

The `git merge-tree` command can perform a three-way merge directly in memory. It takes the tree hashes and returns the resulting tree, failing if there is a merge conflict. So, for rebases that modify trees but do not cause conflicts, we can still avoid touching the working tree and index.

The same idea extends to a general interactive rebase. If we know the rebase plan, such as reordering, dropping, squashing, or renaming commits, we can build the new sequence in memory using the same commands.

That is the approach we implemented. When you perform commit-editing operations, the IDE first tries a fast in-memory path. If it runs into a merge conflict, it silently falls back to a regular Git rebase and stops so you can resolve the conflicts. Otherwise, it updates the branch reference atomically.

We applied the same optimization to other operations. For example, in the _Git Log_, when you select a commit, the _Changed Files_ pane appears on the right. Here, you can select a subset of files and click _Extract Selected Changes to Separate Commit…_ to split one commit into two and never cause a merge conflict. It works by recursively building a split tree in memory and omitting the changes at the specified paths.

![Image 4](https://blog.jetbrains.com/wp-content/uploads/2026/04/extract.png)

Upstream Git is moving in a similar direction as well. The `git replay` command performs a fast in-memory rebase, but it is still experimental and does not support interactive rebase or GPG signing.

## Results

On the IntelliJ monorepo, the average execution time of interactive rebase dropped from tens of seconds to just a few seconds. The exact numbers varied across operating systems, but the overall improvement was consistent.

We also enabled the in-memory optimization in EAP builds during the 2026.1 release cycle. The histograms below show the distribution of interactive rebase execution times in data collected from EAP builds, compared with 2025.3.

### macOS

### Windows

### Linux

### Conflicts

While collecting data on interactive rebase executions, we could also measure how often conflicts occurred. The data shows that around 12% of interactive rebases resulted in merge conflicts, and about 1% failed due to errors. In both cases, we fall back to the regular interactive rebase process.

![Image 5](https://blog.jetbrains.com/wp-content/uploads/2026/04/image-31.png)

The in-memory optimization reduces average execution time across all operating systems. There is still room for improvement, especially on Windows, where the worst-case time is still quite high.

After testing this optimization internally at JetBrains and in EAP builds, we decided to enable it by default in the upcoming 2026.1 release. This applies to standard interactive rebase and actions based on it, such as reword, drop, and squash, as well as extracting selected changes into a separate commit. We expect this to make commit-history editing faster and less disruptive.

## Credits and further reading

The broader developer community was a huge help in shaping our implementation. We would like to acknowledge:

*   [git-revise](https://github.com/mystor/git-revise): The logic in this project was instrumental in guiding our in-memory rebase approach.
*   [Waleed Khan’s blog post](https://blog.waleedkhan.name/in-memory-rebases/#timing): An excellent read that explores this exact topic.
*   [Jujutsu (jj) VCS Discussion #49](https://github.com/jj-vcs/jj/discussions/49): A discussion that sheds light on why the standard Git implementation can be slow in these scenarios.

Interested in the implementation details? Check out the solution in the [IntelliJ Platform sources](https://github.com/JetBrains/intellij-community/tree/master/plugins/git4idea/src/git4idea/inMemory).

Any feedback is welcome! Please leave a comment or email us directly at [vcs-team+ir@jetbrains.com](mailto:vcs-team+ir@jetbrains.com).

[](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#)

1.   [Introduction](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#introduction)
2.   [Interactive rebase: A technical deep dive](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#interactive-rebase-a-technical-deep-dive)
3.   [In-memory rebase optimization: How it works](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#in-memory-rebase-optimization-how-it-works)
4.   [Results](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#results)
    1.   [macOS](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#macos)
    2.   [Windows](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#windows)
    3.   [Linux](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#linux)
    4.   [Conflicts](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#conflicts)

5.   [Credits and further reading](http://blog.jetbrains.com/platform/2026/04/speeding-up-interactive-rebase-in-jetbrains-ides/#credits-and-further-reading)

## Discover more
