Git 2.54で追加されたgit historyとAIでPRレビューの負荷を下げたい

こんにちは。Legalscape SRE・カイゼンチームの橋本です。

先日2026/04/20にリリースされた Git 2.54 では、実験的な新コマンド git history が追加されました。本記事ではgit historyの簡単な解説と、AIエージェントとの相性とその可能性について話したいと思います。

git history とは

作業ツリーを触らずに履歴を編集できるコマンドです。馴染みのあるgit rebase -iは作業ツリーを触るため、ここが大きな違いです。
2.54時点で提供されているサブコマンドは2つです。
なおこのコマンドは実験的なものです。動作が変更される可能性があります。

サブコマンド できること
git history reword <commit> 指定コミットのメッセージを書き換える
git history split <commit> 1コミットを hunk単位で 2分割する

git history reword デモ

操作ログ

可読性のために加工しています。

# 省略...

# ステータスとログを確認
% git status
On branch main
nothing to commit, working tree clean

% git log --oneline
a6e9e45 (HEAD -> main) commit 5
56c50e2 commit 4
fbc6dc3 commit 3
cf54f90 commit 2
b18db33 commit 1

% cat f.txt
line 5

# f.txtを変更
% echo "uncommitted edit" >> f.txt

% git diff f.txt
diff --git a/f.txt b/f.txt
index b9d4c46..76b59d9 100644
--- a/f.txt
+++ b/f.txt
@@ -1 +1,2 @@
 line 5
+uncommitted edit

% git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   f.txt

no changes added to commit (use "git add" and/or "git commit -a")

# working treeに変更がある状態でrebaseを試してみる
% git rebase -i fbc6dc3
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.

# rebaseは実行前にcommitかstashする必要がある...
# historyだと?

% git history reword fbc6dc3
# (コミットメッセージを編集: "commit 3 (changed)" に変更して保存)

% git log --oneline
5d9d88a (HEAD -> main) commit 5
70a38b3 commit 4
c84dcf3 commit 3 (changed)
cf54f90 commit 2
b18db33 commit 1

% git diff f.txt
diff --git a/f.txt b/f.txt
index b9d4c46..76b59d9 100644
--- a/f.txt
+++ b/f.txt
@@ -1 +1,2 @@
 line 5
+uncommitted edit

% git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   f.txt

no changes added to commit (use "git add" and/or "git commit -a")

# Good
% exit

git history split デモ

操作ログ

可読性のために加工しています。

# 省略...

# ステータスとログを確認
% git status
On branch main
nothing to commit, working tree clean

% git log --oneline
c894be2 (HEAD -> main) commit 5
cd888e1 commit 4
e0122b9 commit 3: f.txt と g.txt をまとめてコミット
5ded5f7 commit 2
7d2f6e4 commit 1

% cat f.txt
line 5

# コミット3の中身を確認
% git show --stat e0122b9
commit e0122b97db053a08c418d73a7a372e8fd1d38f5a
Author: MihiroH <mihiro.hashimoto.1125@gmail.com>
Date:   Wed Apr 22 21:33:37 2026 +0900

    commit 3: f.txt と g.txt をまとめてコミット

 f.txt | 2 +-
 g.txt | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

# f.txtを変更
% echo "uncommitted edit" >> f.txt

% git diff f.txt
diff --git a/f.txt b/f.txt
index b9d4c46..76b59d9 100644
--- a/f.txt
+++ b/f.txt
@@ -1 +1,2 @@
 line 5
+uncommitted edit

% git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   f.txt

no changes added to commit (use "git add" and/or "git commit -a")

# working treeに変更がある状態でrebaseを試してみる
% git rebase -i e0122b9
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.

# rebaseは実行前にcommitかstashする必要がある...
# historyだと?

% git history split e0122b9
diff --git a/f.txt b/f.txt
index b7e242c..93bfa43 100644
--- a/f.txt
+++ b/f.txt
@@ -1 +1 @@
-line 2
+line 3
(1/1) Stage this hunk [y,n,q,a,d,?]? y

diff --git a/g.txt b/g.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/g.txt
@@ -0,0 +1 @@
+hello
(1/1) Stage addition [y,n,q,a,d,?]? n

hint: Waiting for your editor to close the file...

# (1つ目のコミットメッセージを編集: "commit 3" に変更して保存)
# (2つ目のコミットメッセージを編集: "add g.txt" に変更して保存)

% git log --oneline
739a3f1 (HEAD -> main) commit 5
98be02a commit 4
b85f9c5 add g.txt
a54a325 commit 3
5ded5f7 commit 2
7d2f6e4 commit 1

# コミット3が2つに分かれている

% git diff f.txt
diff --git a/f.txt b/f.txt
index b9d4c46..76b59d9 100644
--- a/f.txt
+++ b/f.txt
@@ -1 +1,2 @@
 line 5
+uncommitted edit

% git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   f.txt

no changes added to commit (use "git add" and/or "git commit -a")

# Good
% exit

両方に共通する挙動のポイント:

  • 対象コミット以降のコミットIDは書き換わる
  • 作業ツリー(working tree / index)は一切触れられない

git rebase -i との違い

同じ書き換え系の git rebase -i と比べると、次のような違いがあります。

比較項目 git rebase -i git history (reword / split)
主な目的 履歴全体の自由な再構築 特定のコミットへの安全な操作
作業ツリーへの影響 変更される(退避が必要) 影響なし(現在の作業を維持)
bare repository
での実行
不可 可能(サーバー上での操作に好適)
コンフリクト時 中断して手動解決を要求 発生が予測される場合は実行を拒否
マージコミット
の扱い
対応可能 現時点では非対応

要点をGitHubの公式ブログから引用すると、

Unlike git rebase, it doesn’t touch your working tree or index, and it can even operate in a bare repository.

Highlights from Git 2.54 - The GitHub Blog

The history command is built on top of git replay‘s core machinery, which was itself extracted into a library as part of this work. That foundation means that git history benefits from replay‘s ability to operate without touching the working tree, making it a natural fit for scripting and automation in addition to interactive use.

Highlights from Git 2.54 - The GitHub Blog

作業ツリーに触れることなく操作できるため、対話的な使用に加えて、スクリプト作成や自動化にも最適です。とのことです。

サーバーサイドで動く嬉しさ

git history がbare repositoryで動くということは、作業ツリーが存在しないサーバーサイドやCIパイプラインで履歴を書き換えやすいということです。
詳細は割愛しますが、これまでも低レベルなplumbing commandsを使ったり、一時的にcloneを作成すればできそうではあります。

PRレビューでの活用シーンを考えてみる

AIエージェントに大きめのタスクを投げると巨大な1コミットになってしまうことが少なくありません。そしてそのままだとレビュー負荷に繋がります。(AI時代に合わせてレビュー方法などが変わってきていると思いますが、それは一旦置いておきます)

そのため私は普段以下のようなフローで作業しています。

AIに任せつつも、自分で細かくコミットを切る

  1. 適度なタスクに分解
  2. AIエージェントに依頼
  3. PR作成
  4. レビュー依頼
  5. 承認をもらったらマージ
  6. 1に戻る

しかしAIによる履歴の編集ができたらどうでしょうか。

雑に1コミットし、AIがコミットやPR単位を調整

  1. もう少し大きめのタスクに分解
  2. AIエージェントに依頼
  3. 変更を一旦1コミットでpushし、ドラフトPRを作成 3-1. AIがdiffを解析して「リファクタリング」「機能修正」「テスト追加」の3単位を検出
    3-2. AIがgit history splitを2回呼び出して3コミットに分割
    3-3. AIがgit history rewordでコミットメッセージを編集
    3-4. AIがリファクタリングPRと修正PRの2つに分割
  4. レビュー依頼
  5. 承認をもらったらマージ

美しい...
他にも良い方法があるかもしれませんし、より良いVCSやPR方法がすでにあるかもしれませんが、レビューがしやすく、かつ変更履歴を辿りやすいことは開発メンバーやAIにとって嬉しいことです。対人間だけで考えると嬉しいというよりはほぼ必須だと思います。

将来の展望:意味論的(AST ベース)な分割

現時点の git history splitは 行ベースのhunk選択UIで、git add -p と同じ仕組みです。ここが次の進化の余地だと感じています。

ソースコードは本来、関数・クラス・ブロックといった構文木で成り立っていて、行境界で切ると関数や式を途中で分断してしまうことがあります。一方 Tree-sitter のようなparserを用いると、ソースコードを構文木として理解できます。

将来的に「このクラスに関する変更だけを別コミットに切り出す」のような指示が書けるようになったり、AIフレンドリーな操作方法になると、スタック型開発やAIによる履歴の編集体験がさらに良くなると思います。

最後に

Legalscapeでは、サービスのUX向上はもちろん、開発体験の向上にも日々取り組んでいます。もしこの記事を読んで興味を持っていただけたなら、ぜひLegalscapeで一緒に挑戦してみませんか。