8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Git 2.55 の git history fixup で「過去のコミットへの入れ忘れ」を一発修正する

8
Posted at

はじめに

2026年6月に、Git 2.55 がリリースされました。

この記事では、その中から git history fixup という新しいサブコマンドを取り上げて説明します。

「過去のコミットに変更を入れ忘れた」とき、従来は git commit --fixupgit rebase --autosquash を組み合わせて対処していましたが、
新しいサブコマンドである git history fixup は、これを1コマンドにまとめてくれます。

従来手法と比較しながら、新しいコマンドによって、何がどう楽になるのかを見ていきます。

git history実験的な機能 です。
ドキュメントには、THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. と明記されており、今後挙動が変わる可能性があります。

想定するケース

例えば、example.txt というファイルを、少しずつコミットしながら作っていたとします。

$ git log --oneline
c246f98 third commit
578e7f3 second commit
3359793 first commit
736ea7e init

現在のファイルの中身は次の通りです。

$ cat example.txt
foo
baz
qux
quux
corge

ここで「一番最初の first commit で、foobaz の間に入るはずの bar を書き忘れていた」ことに気づいたとします。

今の HEAD に「bar を追加」というコミットを新しく積んでもいいのですが、本来は一番下の first commit に含まれているべき変更です。
そのため、履歴をきれいに保つなら、そのコミットへ直接反映させたくなります。

このように、追加の変更を過去の特定のコミットに取り込むのが今回のテーマです。

従来の手法 git commit --fixup + git rebase --autosquash

まず、今までのやり方を改めて書きます。

1. fixup 用のコミットを作る

まず、bar の行を書き加えます。

 foo
+bar
 baz
 qux
 quux

この変更をステージし、取り込みたい対象コミット(first commit)を指定して --fixup 付きでコミットします。

$ git add example.txt
$ git commit --fixup=3359793
[main 0edfa61] fixup! first commit
 1 file changed, 1 insertion(+)

この時点では、fixup! というプレフィックスの付いたコミットが履歴の先頭に積まれただけです。

$ git log --oneline
0edfa61 fixup! first commit
c246f98 third commit
578e7f3 second commit
3359793 first commit
736ea7e init

2. autosquash でまとめる

続いて git rebase --autosquash を実行すると、fixup! コミットが対象コミットの直後へ自動で並べ替えられ、その後にコミットがまとめられます。

$ git rebase --autosquash 3359793^

コミットがまとめられた後、fixup! コミットは消え、barfirst commit の中に取り込まれます。

$ git log --oneline
18acd35 third commit
4ceff83 second commit
e31dacb first commit
736ea7e init

目的は達成できますが、「fixup コミットを作る」→「rebase でまとめる」の2ステップが必要です。

git history fixup を使う

Git 2.55 で追加された git history fixup なら、上記の操作が1コマンドで済みます。

同じ状況で、今度も bar の行を書き加えます。

 foo
+bar
 baz
 qux
 quux

あとはこの変更をステージし、取り込みたい対象コミットを指定して git history fixup を実行するだけです。

$ git add example.txt
$ git history fixup 0e7711c
$ git log --oneline
138a5a5 third commit
8405e54 second commit
87be1e6 first commit
b7a937f init

fixup! コミットを経由することなく、ステージした変更が直接 first commit に取り込まれました。
従来手法と同じ結果を、たった 1 コマンドで得られています。

$ git show 87be1e6 -- example.txt
...
@@ -0,0 +1,3 @@
+foo
+bar
+baz

対象コミットのメッセージと author は、デフォルトではそのまま維持されます。

制約・注意点

便利ですが、現状は実験的機能ということもあり、制約があります。

端的に言うと、ステージした変更を対象コミットへ簡単にまとめられる場合にのみ使えます。

例えば、ステージした変更を対象コミットに適用するとコンフリクトが発生する場合、git history fixup は履歴を書き換えずに中断します。

$ git history fixup 0e7711c
error: fixup would produce conflicts; aborting

また、対象コミットより後にマージコミットがある場合も対応しておらず、こちらは専用のメッセージで中断します。

$ git history fixup 084f37c
error: replaying merge commits is not supported yet!

こういった場面では、従来どおり rebase などで対応することになります。

おわりに

git history fixup は、git commit --fixup + git rebase --autosquash という定番の2ステップを1コマンドに凝縮してくれる便利なコマンドでした。

実験的機能ではありますが、ローカルのみでの解決を行うような場面では、使っていっても問題はなさそうです。

なお git history fixup には、本記事で触れていないオプションがいくつかあります。
書き換える前に更新される参照だけを表示する --dry-run、対象コミットのメッセージをエディタで編集する --reedit-message、コミットをまとめることで編集内容が空になったときの挙動を決める --empty などです。

気になる方は git-history ドキュメント を覗いてみてください。

Git 2.55 には他にも、フックの並列実行の対応など多くの改善が入っています。
気になる方は、公式ブログをぜひご覧ください。

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?