頑張らないために頑張る

ゆるく頑張ります

すでにコミット済みの「コミットメッセージ」を安全に修正する方法

Posted at — Jul 13, 2026

概要

Git でコミットした直後に「メッセージを間違えた……」というケースは誰にでもあります。直近のコミットから過去のコミット、さらにマージコミットまで、メッセージを変更するための正しい手順と、チーム開発で安全に運用するためのベストプラクティスをまとめます。

重要:コミットメッセージの変更は 履歴の書き換えです。そのため、とくにチームで開発している場合において、共有ブランチ(例:main)で履歴を変えると、他メンバーのローカル履歴を壊す恐れがあります。リモートのブランチ保護設定次第では、強制プッシュが禁止されている場合もあります。作業前にチーム内で合意を形成するか、ルールについて確認してください。

直前(最新)のコミットメッセージを修正する

エディタを使ってメッセージを修正する

直近のコミットは git commit --amend で置き換えます。-m を付けるとエディタを開かずにメッセージを指定できます。

# 直近のコミットメッセージだけを差し替える
git commit --amend -m "修正後のメッセージ"
````

`--amend` は 直前のコミットを新しいコミットで置き換えるため、コミット ID が変わります。 

よく使うバリエーション:

```bash
# コミットし忘れたファイルを追加(メッセージは変更なし)
git add <<忘れたファイル>>
git commit --amend --no-edit

# 既にコミットしたファイルを直前コミットから除外(メッセージは変更なし)
git rm --cached <<いらないファイル>>
git commit --amend --no-edit

# 署名付きコミットを維持して再生成(署名必須なリポジトリ向け)
git commit --amend -m "修正後のメッセージ"

# 著者情報を修正
git commit --amend --author="Correct Name <correct@example.com>" --no-edit

これらのオプションは公式ドキュメントで定義されています。

リモートへ反映する(安全な強制プッシュ)

--amend でコミット ID が変わると、通常の git push は 非 fast-forward として拒否されます。そこで 安全な強制プッシュである --force-with-lease を使うのが推奨です。

git push --force-with-lease origin <ブランチ名>

--force-with-lease は「自分が最後に取得したリモートの先端が変わっていない場合だけ」上書きし、他人の未取得コミットを誤って消す事故を防ぎます。必要に応じて --force-if-includes を併用すると「ローカルブランチのreflogによって、リモートの更新を取り込んでいることを確認する」ことが可能なので、さらに安全な運用が可能です。

過去のコミットメッセージを修正する(インタラクティブ rebase)

直近ではないコミットを修正するには インタラクティブ rebase を使います。対象コミットを含めた範囲を指定して「reword」または「edit」を指示します。

手順

変更したいコミットを確認する

git log --oneline --graph --decorate などで履歴を把握し、対象のコミット(例:abc1234)を特定します。git log はコミット履歴の巡回表示、git reflog は 「HEAD がどのコミットを指してきたか」というローカルの移動履歴であり用途が異なります。対象の選定には git log の利用が適しています。

インタラクティブ rebase を開始

例として、直近 4 コミットを対象にします(古いものが上、最初に再適用される順で表示されます)。

git rebase -i HEAD~4

この一覧は 最古のコミットが上に並びます。ここでは「直近からnコミットまでを表示する」という処理なので、実際にコミットメッセージを修正できるのはもう少し後の手順です。

修正したい行の pickreword に変更

reword abc1234 <現在のメッセージ>
pick   def5678 ...
pick   ghi9012 ...
pick   jkl3456 ...

表示されたコミットの履歴から、実際に修正したいコミットを探します。そして、その行について、pickと表示されている部分を書き換えます。書き換えは2パターンあり、reword はコミット内容は維持してメッセージだけ変更、edit はそのコミットで停止してcommit --amendreset などを使って内容やメッセージを変更します。

reword abc1234 <現在のメッセージ>
pick   def5678 ...
reword   ghi9012 ...  ←今回はこのコミットメッセージを書き換えるとする
pick   jkl3456 ...

修正したいコミットについていずれかを指定し保存、終了します。

なお、ここでは「どのコミットメッセージを修正するか?」の指示だけであり、実際にコミットメッセージを修正するのは次の手順です。

メッセージ編集画面が開くので書き換え

今度は、先の手順で指定したコミットについて書き換えます。メッセージを修正可能な画面が表示され、先ほどの手順で修正を指定したコミットが表示されているはずです。ここでやっとコミットメッセージの内容を書き換えできます。

保存して閉じると rebase が進みます。

リモートへ安全に反映

git push --force-with-lease origin <ブランチ名>

履歴を書き換えたため、安全な強制プッシュで更新します。

注意:インタラクティブ rebase の対象に マージコミットは通常含まれません。マージを保持して書き換える場合は次節の --rebase-merges を使います。

エラーが表示されたら
$ git rebase -i HEAD~2
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.

git rebaseを実行すると、上記のようなエラーメッセージが表示されることがあります。これは、作業ツリーやインデックス(ステージ)に未コミットの変更が残っているため、git rebaseを開始できないことを示しています。git rebaseは基本的にクリーンな状態(作業ツリーとインデックスが HEAD と一致)でのみ実行されます。git rebaseは対象コミット群を再適用していく過程で、作業ツリーやインデックスを更新します。未コミットの変更が残っていると、適用順序や競合解決に支障が出るため、gitは事前にクリーンを要求するわけです。

対処法はいろいろあるものの、簡単なのはgit stashを使っていったん退避してしまう方法です。

git stash push -u      # 追跡外(-u/--include-untracked)も含めて退避
git rebase -i HEAD~2
git stash pop          # rebase後に戻す(競合時は手動解決)

あるいは、明示的なスナップショットとして一度コミットしてしまう方法です。これから進めると、git stashとは異なり通常のコミットなので、失敗時の巻き戻しや復旧、比較などの手段が容易です。

git add -A             # すべてステージ
git commit -m "wip: 作業途中のスナップショット"
git rebase -i HEAD~2   # 目的の rebase を実施

マージコミットのメッセージを修正する(--rebase-merges

マージコミットは通常の -i では落ちます。マージ構造を保ったまま履歴を書き換えるには --rebase-merges を付けます。

# 例:直近 10 コミット分でマージ構造を保持
git rebase -i --rebase-merges HEAD~10

このモードの「merge -c <commit>」を使うと、元のマージコミットのメッセージを再編集できます(-C は元メッセージをそのまま使う)。マージを再作成するため、競合の再解決や手作業の再適用が必要になることがあります。

多数のコミットメッセージを一括で置換したい場合(上級:git filter-repo

多くのコミットに含まれる表記を一斉に修正したい場合、従来の git filter-branch よりも高速で安全な git filter-repo の利用が推奨されています(Git プロジェクトも推奨)。例えばメッセージ内の語句置換は次のように実行できます。

# expressions.txt に 'foo==>bar' のような置換規則を記述しておく
git filter-repo --replace-message expressions.txt

git filter-repo はコミットメッセージ、ファイル内容やパスの改変などを効率的に履歴全体へ適用できます。破壊的操作なので事前にバックアップを取り、作業後は安全な強制プッシュで共有します。

チーム開発での運用上の注意

(参考)git loggit reflog の正しい使い分け

注意点:HEAD@{3} の番号は reflog の移動回数に基づく指標で、git rebase -i HEAD~n の 「n 個前のコミット」とは意味が異なります。対象コミット数を指定する HEAD~n とは混同しないでください。

まとめ

参考

  1. Git - git-commit Documentation
  2. Git - git-rebase Documentation
  3. Changing a commit message - GitHub Docs
  4. Using Git rebase on the command line - GitHub Docs
  5. git rebase - what’s the difference between ‘edit’ and ‘reword’ - Stack Overflow
  6. git push –force-with-lease vs. –force - Stack Overflow
  7. GitHub: Managing protected branches
  8. Git - git-reflog Documentation
  9. What’s the difference between git reflog and log? - Stack Overflow

  10. Rebasing a Git merge commit - Stack Overflow

  11. Git Rebase… with Merges? - DEV Community

  12. newren/git-filter-repo - GitHub

  13. git-filter-repo Man Page

  14. 間違ったgit commit(コミットメッセージ)を修正したい

  15. git commit –amend と git rebase で コミットを修正する

comments powered by Disqus