dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[git]特定のコミットの内容を修正する

直前のコミットを間違ったのでちょっと修正したい場合は

$ git reset HEAD~

で1つ前に戻して修正後、再コミットすればいいんですが、
2つ以上前のコミットの内容を修正する場合にはどうすればいいのか調べてみました。

方法

先に、方法だけを書きます。

  1. git rebase -i HEAD~[戻したいコミット数+1]
  2. コミットログの中から修正したいコミットを探し、pickedit(または単にe)として保存
  3. 通常通りファイルを修正する
  4. git commit --amend-m "[新しいコミットメッセージ]"をつけてもよい)
  5. git rebase --continue

やってみる

たとえばこんなコミット履歴になっているとします。
(コミットが新しい順に上から並んでいます)

$ git log --oneline
1d6bb15 modified index.html
6b327c4 add index.html
0c489f3 add some comments on README
f159f13 add README
a9341dc first commit

ここから、

0c489f3 add some comments on README

を修正します。

修正したいコミットはHEAD ( 1d6bb15 )から2つ前なので、+1して

$ git rebase -i HEAD~3

と実行します。すると...

pick 0c489f3 add some comments on README
pick 6b327c4 add index.html
pick 1d6bb15 modified index.html

# Rebase f159f13..1d6bb15 onto f159f13
#
# 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
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

このように、直近3つ分のコミットが表示されるので(古い順)
該当の0c489f3というコミットをpickからeditに変更します。

edit 0c489f3 add some comments on README
pick 6b327c4 add index.html
pick 1d6bb15 modified index.html

# Rebase f159f13..1d6bb15 onto f159f13
#
# 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
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

そしたら、保存。

あとは、通常通りファイルを修正し、git addしてから

$ git commit --amend

を実行します。

add some comments on README

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# rebase in progress; onto f159f13
# You are currently editing a commit while rebasing branch 'master' on 'f159f13'.
#
# Changes to be committed:
#  modified:   README.md
#

特にコミットメッセージを修正する必要がなければ、このまま保存して閉じます。

最後に、

$ git rebase --continue
Successfully rebased and updated refs/heads/master.

これで、特定のコミットだけ修正することができました。

もし最後のgit rebase --continueの時にコンフリクトが発生した場合
コンフリクトを解消した後、再度git commit --amendからやり直します。