15
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

rebase -iでリモートにプッシュしたコミットの名前を変えられたので勢いでまとめてみた

15
Last updated at Posted at 2026-05-11

はじめに

git commit --amendは使えるけど、それ以外の修正方法はよくわからない」
「pushした後のコミット、どうやって直すの…?」

業務でGitを毎日使っていて、リモートにプッシュしたコミットで誤字があってこれ無視してもいいけどなんか治す方法ないのと検索したらなんかできた話。

この記事では、コミットの修正を「ローカル or リモート」「直前 or 数個前」の2軸で整理して、ある程度状況によってどうするかをわかるようにまとめました。最後に紹介するreflogも使えるので載せています。

この記事の対象読者

  • git commitgit pushは日常的に使っている
  • --amendは知ってるが、それ以外の修正方法に自信がない
  • rebase -iに苦手意識がある、または使ったことがない
  • 一度pushしたコミットの修正で困ったことがある

普通のコミット

最もシンプルなコミット

# ステージング → コミット(特に言うことない)
git add .
git commit -m "機能Aを実装"

記事を書くのに気づいたオプションコマンドなど

# add + commit を一発で(追跡済みファイルのみ)
git commit -am "修正を反映"

# 空コミット
git commit --allow-empty -m "空のコミットです"

# コミットメッセージをエディタで書く
git commit  # -m なしで実行するとエディタが開く

-amは便利ですが、新規ファイル(untracked)は対象外という点に注意。git add .を省略できるのは、すでにGitが追跡しているファイルだけです。


ローカルでの修正

まだpushしていないコミットは何とでも修正が聞く

直前のコミットを修正する ― --amend

よく使うやつ。「コミットメッセージタイプミスした」「ファイル入れ忘れた」のときに。

# メッセージだけ修正
git commit --amend -m "正しいメッセージ"

# ファイルを追加してコミットし直す
git add forgotten-file.ts
git commit --amend --no-edit  # メッセージはそのままファイルだけ追加される

注意: --amendは「前のコミットを編集する」のではなく、「前のコミットを捨てて新しいコミットを作る」操作です。コミットハッシュが変わります。リモートに既にプッシュした時のコミットで気をつけてほしい。

直前のコミットを取り消す ― reset

「そもそもこのコミット自体なかったことにしたい」場合。

# コミットを取り消し、変更はステージングに残す
git reset --soft HEAD~1

# コミットを取り消し、変更はワーキングツリーに残す(ステージング解除)
git reset --mixed HEAD~1  # --mixed はデフォルトなので省略可

# コミットを取り消し、変更も全て破棄
git reset --hard HEAD~1

それぞれの違いとしては:

モード コミット ステージング ワーキングツリー
--soft 取り消す 残る 残る
--mixed 取り消す 取り消す 残る
--hard 取り消す 取り消す 消える

--hardは変更が本当に消えます。もし間違えても後述のreflogでなんとかできます。

数個前のコミットを修正する ― rebase -i

例えば「3つ前のコミットメッセージを直したい」「途中のコミットをまとめたい」など。

# 直近3つのコミットを対象にリベースをする
# それぞれのコミット文をリベースしながら書き直すイメージ
git rebase -i HEAD~3

デフォルトのエディタがvimの場合、こんな画面が開きます:

pick a1b2c3d 機能Aの実装
pick d4e5f6g typoを修正
pick h7i8j9k テストを追加

# Rebase xxxxxxx..xxxxxxx onto xxxxxxx
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# d, drop = remove commit

vimの基本操作(これだけ覚えればOK)

vimに慣れていない人(私です)は何も教えて進まないと思うのですが、rebase -iで使う操作は以下の4つだけで:

やりたいこと キー操作
文字を編集する iを押す(挿入モードに入る)
編集を終える Escを押す(ノーマルモードに戻る)
保存して閉じる Esc:wqEnter
保存せず中止する Esc:q!Enter

つまり、iで編集モードに入ってpickfixupなどに書き換えて、Esc:wqEnterで確定。これだけです。

💡 vim以外のエディタを使いたい場合

# VSCodeを使う場合
git config --global core.editor "code --wait"

ここで各コミットに対して指示を出します:

コマンド 意味
pick そのまま使う
reword メッセージを変更
edit コミット内容を修正
squash 前のコミットと統合(メッセージ編集あり)
fixup 前のコミットと統合(メッセージは前のを使用)
drop コミットを削除

例:typo修正コミットを前のコミットに統合する

pick a1b2c3d 機能Aの実装
fixup d4e5f6g typoを修正      ← pick → fixup に変更
pick h7i8j9k テストを追加

保存してエディタを閉じると、d4e5f6ga1b2c3dに吸収されて、履歴がきれいになります。

rebase -i で気をつけること

  • コンフリクトが起きることがあるgit rebase --continueで続行、git rebase --abortで中止
  • リベース中に「もうやめたい」と思ったら--abortで元に戻せる
  • 表示順は古い順(上が古い)git logの逆

リモートpush後の修正

Gitの「ブランチ」は、特定のコミットを指すポインタです。git pushすると、リモートのポインタが更新されます。

ローカル:   main → コミットC → コミットB → コミットA
リモート:   main → コミットC → コミットB → コミットA
                    ↑ 同じものを指している

ここでローカルのコミットをamendrebaseで書き換えると:

ローカル:   main → コミットC' → コミットB → コミットA  (C'は新しいコミット)
リモート:   main → コミットC  → コミットB → コミットA  (古いCのまま)

この状態だとgit pushしても拒否されます。コミットのハッシュが異なっているからとか。

リモートでも履歴を整理したい ― rebase -i + force-push

わたしはこれになってしまったのですが、「feature branchにpushした後にコミットのタイポに気づいてなんとかなおしたい」。PRのレビュー前に履歴をきれいにしたい場合、リモートでもrebase -iは使えます。

# ① ローカルでrebase -iを実行
git rebase -i HEAD~3

# ② vimで編集して保存(:wq)

# ③ リモートの履歴を上書き
git push --force-with-lease

ローカルのセクションで紹介したrebase -iと操作は同じで、最後に--force-with-leaseでpushするだけ。

打ち消しで対応する ― revert

revertは「過去のコミットを打ち消す新しいコミットを作る」操作です。

# 直前のコミットを打ち消す
git revert HEAD

# 特定のコミットを打ち消す
git revert <commit-hash>

# 複数コミットを一括で打ち消す
git revert HEAD~3..HEAD
修正前:  A → B → C(問題のコミット)
修正後:  A → B → C → C'(Cを打ち消すコミット)

最後の命綱 ― reflog

ここまでの操作をすべて台無しにしてぐちゃぐちゃになってもreflogが助けてくれる。

reflogとは

reflog`は「あなたがGitに対して行った全操作の記録」です。

commit、reset、rebase、amend、checkout、merge…HEADが動くたびに記録されています。

git reflog
a1b2c3d HEAD@{0}: rebase (finish): returning to refs/heads/feature
x9y8z7w HEAD@{1}: rebase (pick): テストを追加
m3n4o5p HEAD@{2}: rebase (start): checkout HEAD~3
f4e5d6c HEAD@{3}: commit: テストを追加
b2c3d4e HEAD@{4}: commit: 機能Aの実装

なぜreflogで「消えた」コミットを探し出せるのか

Gitはコミットを本当に削除することはほぼありません

reset --hardしても、rebaseでsquashしても、元のコミットオブジェクト自体はリポジトリに残っています。ただ、どこからも参照されなくなっただけ。

reflogはHEADの移動履歴を全て持っているので、「参照されなくなったコミット」がどこにあるのかを教えてくれる。

通常のgit log(コミットツリー):
  main → C' → B → A
  (reset --hard で C が見えなくなった)

reflog(操作ログ):
  HEAD@{0}: reset: moving to HEAD~1     ← 今ここ
  HEAD@{1}: commit: 機能Cの実装          ← Cはまだ存在する!
  HEAD@{2}: commit: 機能Bの実装

rebase -i をやらかした場合の救出

# rebase -i で履歴を整理しようとした
git rebase -i HEAD~3

# ...なんかコミットが消えた気がする

git reflog

# rebase前の状態を見つける(rebase (start) の1つ前)
# 例: HEAD@{5} が rebase 前の状態だった場合
git reset --hard HEAD@{5}

# → rebase前の状態に復元できる

reset --hard をやらかした場合の救出

# うっかり直前のコミットを消してしまった
git reset --hard HEAD~1

# reflogで消えたコミットを探す
git reflog
# HEAD@{1} が reset 前の状態

git reset --hard HEAD@{1}
# → 復元

reflogの注意点

  • ローカル限定。リモートには存在しない
  • デフォルトで90日間保持git gcで古いものは削除される
  • cloneし直すと消える。reflogはそのリポジトリのローカル操作ログなので
  • git gcが手動実行されると、参照されていないコミットが本当に消える可能性がある

reflogは万能ではないけれど、「やらかした直後」であればほぼ何とかなるコマンドです。


まとめ ― コミット修正の早見表

やりたいこと ローカル(push前) リモート(push後)
直前のメッセージ修正 commit --amend revert + 新コミット
直前にファイル追加 addcommit --amend revert + 新コミット
直前のコミット取り消し reset --soft HEAD~1 revert HEAD
数個前のコミット修正 rebase -i revert <hash> or rebase -i + force-push
コミット統合 rebase -i (squash/fixup) rebase -i + force-push
全部やらかした reflogreset --hard

株式会社シンシアでは、実務未経験のエンジニアの方や学生エンジニアインターンを採用し一緒に働いています。
※ シンシアにおける働き方の様子はこちら

シンシアでは、年間100人程度の実務未経験の方が応募し技術面接を受けます。
その経験を通し、実務未経験者の方にぜひ身につけて欲しい技術力(文法)をここでは紹介していきます。


15
4
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
15
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?