こんにちは。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 thatgit historybenefits fromreplay‘s ability to operate without touching the working tree, making it a natural fit for scripting and automation in addition to interactive use.
作業ツリーに触れることなく操作できるため、対話的な使用に加えて、スクリプト作成や自動化にも最適です。とのことです。
サーバーサイドで動く嬉しさ
git history がbare repositoryで動くということは、作業ツリーが存在しないサーバーサイドやCIパイプラインで履歴を書き換えやすいということです。
詳細は割愛しますが、これまでも低レベルなplumbing commandsを使ったり、一時的にcloneを作成すればできそうではあります。
PRレビューでの活用シーンを考えてみる
AIエージェントに大きめのタスクを投げると巨大な1コミットになってしまうことが少なくありません。そしてそのままだとレビュー負荷に繋がります。(AI時代に合わせてレビュー方法などが変わってきていると思いますが、それは一旦置いておきます)
そのため私は普段以下のようなフローで作業しています。
AIに任せつつも、自分で細かくコミットを切る
- 適度なタスクに分解
- AIエージェントに依頼
- PR作成
- レビュー依頼
- 承認をもらったらマージ
- 1に戻る
しかしAIによる履歴の編集ができたらどうでしょうか。
雑に1コミットし、AIがコミットやPR単位を調整
- もう少し大きめのタスクに分解
- AIエージェントに依頼
- 変更を一旦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つに分割 - レビュー依頼
- 承認をもらったらマージ
美しい...
他にも良い方法があるかもしれませんし、より良いVCSやPR方法がすでにあるかもしれませんが、レビューがしやすく、かつ変更履歴を辿りやすいことは開発メンバーやAIにとって嬉しいことです。対人間だけで考えると嬉しいというよりはほぼ必須だと思います。
将来の展望:意味論的(AST ベース)な分割
現時点の git history splitは 行ベースのhunk選択UIで、git add -p と同じ仕組みです。ここが次の進化の余地だと感じています。
ソースコードは本来、関数・クラス・ブロックといった構文木で成り立っていて、行境界で切ると関数や式を途中で分断してしまうことがあります。一方 Tree-sitter のようなparserを用いると、ソースコードを構文木として理解できます。
将来的に「このクラスに関する変更だけを別コミットに切り出す」のような指示が書けるようになったり、AIフレンドリーな操作方法になると、スタック型開発やAIによる履歴の編集体験がさらに良くなると思います。
最後に
Legalscapeでは、サービスのUX向上はもちろん、開発体験の向上にも日々取り組んでいます。もしこの記事を読んで興味を持っていただけたなら、ぜひLegalscapeで一緒に挑戦してみませんか。