【Git】コミットメッセージの変更方法|amend・rebase -i reword・filter-repoの使い分け完全ガイド

【Git】コミットメッセージの変更方法 Git

「コミットメッセージをtypoした」「Conventional Commitsのprefixを間違えた」「数件前のコミットメッセージを直したい」「push済みメッセージを修正できる?」——Gitのコミットメッセージ修正は、意外とシチュエーションが多様です。直前のコミットか過去のコミットか、push済みか未pushか、共有ブランチか個人ブランチかで、使うコマンドと注意事項が変わります。

この記事では、Gitのコミットメッセージを変更する方法を状況別に整理します。定番のgit commit --amend、過去コミットを修正するgit rebase -ireword、push済み・共有ブランチでの扱い、一括修正のgit filter-repo、そしてConventional Commitsやコミット規約との付き合い方まで、実務で迷わない形で解説します。

この記事で学べること

  • 状況別の最適コマンド:直前/数件前/全履歴/push済み
  • git commit --amendの正しい使い方とエディタ設定
  • git rebase -irewordで過去コミットのメッセージを書き換える方法
  • push済み個人ブランチでの--force-with-lease運用
  • 共有ブランチで履歴書き換えを避ける現実的な対処
  • 全履歴の一括修正に使うgit filter-repofilter-branchは非推奨)
  • Conventional Commits・末尾Signed-off-byなどメッセージ規約との付き合い方
スポンサーリンク

まず確認:状況で使うコマンドが決まる

メッセージ変更はどのコミットを修正するかpush済みかで大きく手順が変わります。

状況 推奨コマンド pushへの影響
直前のコミット、未push git commit --amend そのままpushでOK
数件前のコミット、未push git rebase -ireword そのままpushでOK
直前/過去コミット、push済み個人ブランチ 上記+push --force-with-lease 安全な強制pushが必要
push済み共有ブランチ(main等) 原則修正しない/追記コミットで補足 履歴書き換えは禁物
全履歴の一括置換 git filter-repo 全ブランチのSHAが変わる

ポイント:メッセージ修正はSHAが変わる履歴書き換え操作です。push前なら気軽に、push後なら慎重に。共有ブランチ(main/develop)ではメッセージ程度のミスは放置するか、追記コミットで補足するのが運用コストに見合います。

直前のコミットメッセージ:git commit –amend

もっとも頻繁に使うのが--amendです。エディタが開いて編集、または-mで直接指定できます。

amendの基本
# エディタで編集(Git設定のeditor が開く)
git commit --amend

# メッセージを直接指定
git commit --amend -m "fix: トークン有効期限のバグを修正"

# エディタは開かず、メッセージは変えずにファイル追加だけしたい
git add forgotten_file.py
git commit --amend --no-edit

# 作者(Author)も一緒に直したい
git commit --amend --author="New Name <new@example.com>"

# コミット日時も現時点に更新
git commit --amend --no-edit --date=now

amend したあとの状態

  • コミットのSHAが変わる(新しいコミットとして作り直される)
  • 未pushならそのままgit pushできる
  • push済みならgit push --force-with-leaseが必要
  • 元のコミットはgit reflogから90日間辿れる(復元可能)

エディタの設定

コミットメッセージ編集時のエディタ
# VS Code(--wait でGitが待機)
git config --global core.editor "code --wait"

# Cursor
git config --global core.editor "cursor --wait"

# Vim(デフォルト環境が多い)
git config --global core.editor vim

# nano(初心者向け)
git config --global core.editor nano

# JetBrains系(IntelliJ IDEA)
git config --global core.editor "idea --wait"

注意:GUI系エディタは必ず--wait(VS Code/Cursor)・-w(Sublime Text)のような「終了まで待つ」オプションが必要です。指定しないと、エディタが開いた瞬間にGitが「空のメッセージ」と判断してabortします。

過去のコミット:rebase -i で reword

直前ではなく「3コミット前のメッセージを修正したい」という場合は、git rebase -i(インタラクティブrebase)でreword(短縮r)を指定します。

rebase -i の基本
# 直近5コミットを対象にインタラクティブrebaseを起動
git rebase -i HEAD~5

# 特定のコミットの親から
git rebase -i a1b2c3d^

# mainから分岐後すべてを対象に
git rebase -i main

エディタでの操作

rebase -i のエディタ画面
# エディタに以下のようなリストが表示される
pick a1b2c3d feat: ユーザー登録を追加
pick e4f5g6a fix: emailバリデーションを修正    # ← メッセージを直したい
pick i7j8k9l docs: README更新

# Commands:
# p, pick = コミットを使用
# r, reword = コミットを使用し、メッセージだけ編集
# e, edit = コミットを使用し、修正のために停止
# s, squash = 前のコミットに統合(メッセージ合体)
# f, fixup = 前のコミットに統合(メッセージ破棄)
# d, drop = コミットを削除

# 変更したいコミットの pick を reword に書き換える
pick a1b2c3d feat: ユーザー登録を追加
reword e4f5g6a fix: emailバリデーションを修正
pick i7j8k9l docs: README更新

エディタを保存して閉じると、rewordの対象コミットごとにメッセージ編集用のエディタが開きます。新しいメッセージに書き換えて保存→閉じる、を繰り返し、すべて完了するとrebaseが終了します。

複数コミットのメッセージを一度に編集

複数 reword
# 対象コミット全部 pick を reword に書き換える
reword a1b2c3d feat: ユーザー登録を追加
reword e4f5g6a fix: emailバリデーションを修正
reword i7j8k9l docs: README更新

# 保存→閉じる → エディタが順番に開くので順次編集

rebase -i は履歴の書き換え

  • 対象コミット以降のSHAがすべて変わる
  • 未pushなら安全、push済みなら--force-with-leaseが必要
  • 共有ブランチでは絶対に使わない——他メンバーのローカルが壊れる
  • 途中で困ったらgit rebase --abortで開始前に戻れる

rebase途中でエラーになった場合の復旧はリベース途中でエラーになったときの復旧方法、rebaseとmergeの使い分けはrebaseとmergeの違いと使い分けを参照してください。

push済みコミットの扱い

既にリモートに出ているコミットのメッセージを直す場合、ブランチの性質で対応が分かれます。

個人ブランチ:–force-with-lease で安全に反映

個人ブランチの強制push
# メッセージ修正
git commit --amend -m "新しいメッセージ"
# または rebase -i で reword
git rebase -i HEAD~3

# 最新リモート情報を取得してから
git fetch origin

# 安全な強制push
git push --force-with-lease origin feature/my-branch

–force-with-lease の安全性

  • リモートが自分のローカルorigin/xxxと一致していればpush
  • 他人が間にpushしていたら拒否されて上書き事故を防止
  • --forceは無条件上書きで危険、代替として--force-with-leaseを推奨
  • push関連の詳細はpushを取り消す方法を参照

共有ブランチ(main/develop):修正しないのが原則

禁止:共有ブランチのコミットメッセージを直すための履歴書き換えは行いません。他メンバーのgit pullでコンフリクトが起き、作業が消える事故につながります。メッセージの typo 程度なら放置が原則。どうしても伝えたい補足があれば追記コミットでPR descriptionに書くのが現実的です。

どうしても共有ブランチで修正が必要なとき

最小限の影響で修正する場合
# 1. 管理者権限でブランチ保護を一時解除(GitHub設定)
# 2. 全メンバーに周知:作業を退避してもらう
# 3. amend または rebase -i で修正
git commit --amend -m "修正メッセージ"

# 4. --force-with-lease で反映
git fetch origin main
git push --force-with-lease origin main

# 5. 全メンバーに周知:
# 各自:git fetch origin && git reset --hard origin/main

全履歴のメッセージ一括修正:filter-repo

「リポジトリの全履歴で「fix」を「fix:」に揃えたい」といった一括置換はgit filter-repoを使います。旧来のgit filter-branchは公式にも非推奨で、filter-repoが現在の標準です。

git filter-repo でメッセージ一括書き換え
# インストール(まだなら)
pip install git-filter-repo

# ミラーcloneを推奨(安全のため)
git clone --mirror https://github.com/user/repo.git repo-mirror
cd repo-mirror

# コールバックでメッセージ置換
git filter-repo --message-callback '
import re
return re.sub(rb"^fix ", b"fix: ", message, flags=re.MULTILINE)
'

# 同じプロジェクトの別ディレクトリで作業するなら --force を付ける
git filter-repo --force --replace-message ../replacements.txt

警告:filter-repo全コミットのSHAが変わる破壊的操作です。実行前にミラーcloneでバックアップを取り、チーム全員に通知し、作業を退避してもらってから実行してください。push後は全メンバーが再cloneする必要があります。

filter-branchは非推奨

filter-branch(非推奨)の代わり
# 旧 filter-branch の例(使わないでください)
# git filter-branch --msg-filter 'sed "s/old/new/g"' HEAD

# 新 filter-repo での同等処理
git filter-repo --replace-message expressions.txt
# expressions.txt の中身例:
# old==>new

filter-branch が非推奨な理由

  • 処理速度が数倍〜数十倍遅い
  • デフォルトで安全装置が緩く、壊しやすい
  • Git公式ドキュメントに非推奨と明記されている
  • 機密情報削除も含めてfilter-repoに一本化するのが現代的
  • 機密情報削除は履歴に含まれる機密情報を完全に削除する方法も参照

コミット規約との付き合い方

メッセージ修正のよくある理由が「規約違反の修正」です。代表的な規約を押さえておくと、そもそも修正が必要なくなります。

Conventional Commits の基本

  • feat:(機能追加)/fix:(バグ修正)/docs:(ドキュメント)
  • style:refactor:test:chore:
  • breaking change はfeat!:BREAKING CHANGE:フッタで明示
  • semantic-release等の自動バージョニングで活躍
  • 1行目は50字以内、本文は72字折り返しが慣習

コミットメッセージテンプレート

テンプレートで規約を強制
# リポジトリ/全体のテンプレート作成
cat > ~/.gitmessage.txt << "EOF"
# <type>(<scope>): <subject>
# 
# type: feat / fix / docs / style / refactor / test / chore
# scope: auth / api / ui など(省略可)
# 
# <body: なぜ変更したかの説明>
# 
# <footer: BREAKING CHANGE / refs #issue など>
EOF

# グローバル設定
git config --global commit.template ~/.gitmessage.txt

# リポジトリ個別
git config commit.template .gitmessage.txt

commit-msg hookで自動検証

commit-msg hook 例
# .git/hooks/commit-msg
#!/bin/sh
pattern="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .+"
msg=$(head -1 "$1")
if ! echo "$msg" | grep -qE "$pattern"; then
  echo "エラー: Conventional Commits形式で書いてください" >&2
  echo "例: feat(auth): Add OAuth support" >&2
  exit 1
fi

ポイント:規約違反の修正はamendよりcommit前にフック等で予防するのがコストが低いです。husky+commitlint、pre-commit(Python)、simple-git-hooksといったツールでチーム全員の手元で自動チェックできます。

実践シナリオ

シナリオ① 直前のメッセージをtypo修正

最頻出ケース
# push前の典型パターン
git commit --amend -m "fix: ログイン失敗時のエラーメッセージを修正"

# push済みの個人ブランチなら
git commit --amend -m "..."
git push --force-with-lease origin feature/xxx

シナリオ② 3件前のメッセージを書き換え

rebase -i で reword
git rebase -i HEAD~5
# エディタで該当コミットを pick → reword に変更
# 保存して閉じる → メッセージ編集用エディタが開くので書き換えて保存

# 個人ブランチなら強制push
git push --force-with-lease origin feature/xxx

シナリオ③ 直前のコミットに Signed-off-by を追加

Signed-off-by の後付け
# 単一コミットのDCO署名を追加
git commit --amend --no-edit --signoff

# 過去N件に一括追加
git rebase --exec 'git commit --amend --no-edit --signoff' -i HEAD~5
# rebase -i で全コミットを pick のままにして実行

シナリオ④ 作者情報を直す

Author を修正
# 直前のコミットの作者
git commit --amend --author="Name <email@example.com>" --no-edit

# 過去コミットの作者を一括変更(filter-repo)
git filter-repo --email-callback '
return email.replace(b"old@example.com", b"new@example.com")
'

GUI・IDEでのメッセージ編集

主要ツール

  • VS Code / Cursor:Source ControlのCommit欄、Git Graph拡張で過去commit右クリック→Rebase
  • JetBrains:Git Log → コミット右クリック → Edit Commit Message...(未pushのみ)
  • SourceTree:Log/Historyで過去commit右クリック → Edit(interactive rebase起動)
  • GitHub Desktop:History → Amend Commit(最新のみ)
  • GitKraken:commit右クリック → Reword

やってはいけない落とし穴

共有ブランチで履歴書き換えしてforce push

mainやdevelopの過去コミットを--amendrebase -iで書き換え、force pushすると他メンバーのローカルが壊れます。メッセージ程度のミスは追記コミットで補足するか放置しましょう。GitHub等のBranch protection rulesでforce push禁止を設定しておくと物理的に防止できます。

amend でエディタが開かず空メッセージabort

VS Code等のGUIエディタをGitのcore.editorに設定したのに--waitを付け忘れていると、エディタが開いた瞬間にGitが「空メッセージ」と判定してAborting commit due to empty commit message.となります。git config --global core.editor "code --wait"のように必ず--waitを。

rebase途中で困って状態を複雑にする

rebaseの途中でコンフリクトや想定外のエラーが出たとき、闇雲に追加操作をすると状態が悪化します。困ったらまずgit rebase --abortで開始前に戻れます。詳細はリベース途中でエラーになったときの復旧方法を参照。

filter-branch を使う

Git公式で非推奨とされており、処理速度も安全性もfilter-repoに劣ります。旧記事やStack Overflowの古い回答に従わず、新しく書くならfilter-repoを選びましょう。

amend 後にforce pushせずに普通のpushで失敗

push済みコミットをamendするとリモートとローカルで履歴が食い違います。普通のgit pushnon-fast-forwardで拒否されるので、git push --force-with-leaseが必要です。詳しくはnon-fast-forwardで拒否されたときの解決方法も参考になります。

よくある質問

Qamend でメッセージだけ変えたつもりがSHAが変わった
A正常な動作です。--amendは新しいコミットを作り直すのでSHAは必ず変わります。同じブランチで作業中なら問題ありませんが、push済みブランチの場合は--force-with-leaseで反映が必要です。
Qrebase -i で画面の見方が分からない
A各行が対象コミット、先頭のpickreword(またはr)に書き換えるのが操作の要です。画面下部にコマンド一覧が表示されるのでそれを参照してください。メッセージ変更だけならreword、コミットの内容も直すならedit
Qrebase -i中にコンフリクトが出た
Arewordだけならコンフリクトは発生しません(メッセージのみ変更)。editsquashで内容も触るとコンフリクトが起き得ます。衝突ファイルを直してgit addgit rebase --continueで再開、中止したいならgit rebase --abortで元に戻せます。
Qpush済みコミットのメッセージを修正したい
A個人ブランチなら--amendrebase -i reword--force-with-leaseで安全に可能。共有ブランチ(main等)では原則修正せず、追記コミットでPR descriptionに補足する運用が無難です。
Qコミットメッセージの1行目と本文を分けて書きたい
Agit commit -m "一行目" -m "本文"-m複数指定、または引数なしのgit commitでエディタを開いて1行目・空行・本文と書くのが基本です。commit.template設定で毎回テンプレートから編集開始もできます。
Q過去のメッセージから大量typoを一括修正したい
Agit filter-repo --replace-message <file>で正規表現置換が可能です。全コミットのSHAが変わる破壊的操作なので、必ずミラーcloneで作業し、チームに再clone依頼をセットにしてください。
Qそもそもメッセージを間違えないようにしたい
Acommit.templateでフォーマットを固定、commit-msgフックで検証、commitlint + huskyで自動チェック、が王道です。Conventional Commits準拠にしておくと、セマンティックリリースやCHANGELOG生成に繋がります。

関連記事

まとめ

  • 直前のメッセージ修正はgit commit --amend、過去はgit rebase -ireword
  • どちらもSHAが変わる履歴書き換え——未pushなら気軽、push済みは--force-with-lease
  • 共有ブランチは原則修正しない。追記コミットやPR descriptionで補足
  • 一括置換はgit filter-repofilter-branchは非推奨)
  • GUIエディタ設定は--wait必須
  • そもそも間違えないようcommit.templatecommit-msgフックで予防
  • Conventional Commits準拠にするとツール連携(semantic-release等)が便利

コミットメッセージ修正は、Gitの履歴書き換え操作の中では比較的軽微ですが、「SHAが変わる=push済みなら--force-with-lease必要」という原則は必ず意識してください。修正よりもむしろcommit前の予防(テンプレート・フック・Conventional Commits)に投資する方が、長期的にはチーム全体のコストを下げます。それでも修正が必要になったら、この記事のコマンドを状況別に使い分けて、きれいな履歴を保ちましょう。