3
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?

More than 1 year has passed since last update.

git rebaseのinteractiveモードを活用して2個以上前のコミットを修正する

Last updated at Posted at 2022-03-11

前置き

業務ではこまめにコミットをするようにしているのですが
「あの修正入れ忘れた!」
とか
「あ!コミットメッセージが誤字ってる!!」
とかありますよね(私はよくあります)

それを修正するためのコマンドを毎回調べるのも面倒なので備忘録のためまとめました
この記事が私と同じおっちょこちょいな人の手助けになれば幸いです🙇‍♂️

前提として本記事はリモートリポジトリにpushしてない状態での説明となります

push済みだとpush -fを使わないと修正出来ないのでオススメしません
素直に新しくコミットを作ってpushしましょう

2個以上前のコミットの修正の説明をより理解しやすくするために
先に1個前のコミットの修正を説明しようと思います

そんなん知ってるわ!早く教えてくれーって方は
こちらをクリックでジャンプ出来ます
(そんな人はこんな記事見ないと思いますが…😅w)

1個前のコミットの修正

これはとてもシンプル
git commit --amendを使います

どうやって使うか具体例で見てみましょう

e.g.) さっきのコミットにBの変更を入れ忘れた

terminal
$ git log -1 --name-only
commit 509bab5e2596d88b469bb692b9dc23bdbc1287e7 (HEAD -> xxx, origin/xxx
Author: xxxx <xxx@test.com>
Date:   Thu Mar 10 10:02:00 2022 +0900

    Aを追加

app/views/A.html

$ git status
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   app/views/B.html

no changes added to commit (use "git add" and/or "git commit -a")

「あ!!今のコミットにBの変更を入れ忘れた!!」
落ち着いてください
直前のコミットの変更は簡単ですよ

このBの変更をさっきのコミットに滑り込ませるには

tarminal
$ git add app/views/B.html
$ git commit --amend

これだけ!

他にも変更を入れたいなら普通に作業してgit addすればOKです

git commit --amendを実行すると
vimが立ち上がりコミットメッセージの修正画面が出ます
オプションなしでgit commitを実行したときの画面ですね

ちょっと違うのは1個前のコミットメッセージが表示されています
つまりコミットメッセージの修正もここで出来るということです

今回は

  • 入れ忘れたBの修正を追加
  • 追加でCの修正も追加
  • コミットメッセージを「AとBとCを追加した」に修正

これらの変更をしました

tarminal
$ git add app/views/B.html app/views/C.html
$ git commit --amend

コミットメッセージの変更をしない場合はそのまま:qで終了でOKです

コミットメッセージ修正画面を終了するとちゃんとコミットが追加されています
確認してみましょう

tarminal
$ git log -1 --name-only
commit 509bab5e2596d88b469bb692b9dc23bdbc1287e7 (HEAD -> xxx, origin/xxx
Author: xxxx <xxx@test.com>
Date:   Thu Mar 10 10:47:22 2022 +0900

    AとBとCを追加した

app/views/A.html
app/views/B.html
app.views/C.html

ちゃんと追加出来ました👏

2個以上前のコミットの修正

いよいよ表題のgit rebase -iを使います

ちょっとだけ手順が増えるので順を追って具体例で見てみましょう

e.g.) 3個前のコミットにDの変更を入れ忘れた

先ほどの修正から少し開発も進みコミットも何個か積んできました
ふと思いつきます

「あの時のコミットにDの変更含めておけば良かった…」

terminal
$ git log --oneline
7d6fd8904 (HEAD -> xxx, origin/xxx 1個前のコミット
55074c0d9 2個前のコミット
509bab5e2 3個前のコミット <- これに含め忘れたい
.
.

なんと2個以上前のコミットの修正にはgit commit --amendは使えません

「でもまた新たにコミットを作ると履歴が汚くなるし嫌だな…」

大丈夫です
ここではgit rebase -i(interactive mode)を使って
N個前のコミットを取得してから編集するという流れで修正できるので説明します

-iオプションgit rebaseをinteractiveモードで起動できるオプション
interactiveは対話とか対話式と訳されたりするようです
編集だけでなくコミットをまとめたり削除したりも出来ます

Rubyのコンソールであるirbもinteractive Rubyの略
たしかにコンソールってinteractiveですよね💡

1. 対象のコミットを取得

git rebase -i HEAD~N(NにはN個前のコミットまで対象にするかで適宜数値を入れてください)

terminal
$ git rebase -i HEAD~3

を実行するとvimが立ち上がり

vim
pick 0d2711298 3個前のコミット
pick 55074c0d9 2個前のコミット
pick 7d6fd8904 1個前のコミット
.
.

こんな感じでN個で指定した分だけコミットが取得出来ます
(今回はHEAD~3を指定したので3個分のコミットが取得出来ましたね)

HEAD今現在自分が作業している場所を示すポインタです
つまり今現在の作業~3個前のコミットを取得したわけです

次に各コミットの左端にpickとなっている部分をeditに変更します
(今回は3個前のコミットを修正したいので3個前のやつを変更ですよ)

vim
edit 0d2711298 3個前のコミット
pick 55074c0d9 2個前のコミット
pick 7d6fd8904 1個前のコミット

:qで終了すると

terminal
~/dir branch_name|rebase-i
$ |

こんな感じでプロンプトにrebase-iと表示されるようになります

各々の環境によって表示のされ方には違いがあります
もしrebase-iなどのgitの状態が表示されないなら改善をオススメします

2. 実際に追加したい修正作業をする

ここまで来たらもう簡単です
ほとんど1個前のコミットの修正と同じです
追加し忘れたファイル以外にも新たに別の変更を追加してもOKです
何度も修正しなくていいように慎重に作業しましょうw

3. 修正をコミットし直す

修正作業が終わったのでいよいよコミットを修正します
といってもgit rebaseで該当コミットの編集モードに入っているので

terminal
git add .
git commit —-amend

お馴染みのこれでOKです

同じくコミットメッセージを修正する画面になるので
適宜操作して終了したらコミットの修正は完了です
(今回はコミットメッセージを3個前のコミットにDを追加に変更してみました)

確認してみましょう

terminal
$ git log -1 --name-only
commit 509bab5e2596d88b469bb692b9dc23bdbc1287e7 (HEAD -> xxx, origin/xxx
Author: xxxx <xxx@test.com>
Date:   Thu Mar 10 10:47:22 2022 +0900

    3個前のコミットにDを追加

app/views/A.html
app/views/B.html
app/views/C.html
app/views/D.html

ちゃんと出来てるー👏

4. interactiveモードから抜ける

忘れずがちです
ちゃんと最後はinteractiveモードから抜けましょう
下記コマンドで抜けられます

terminal
$ git rebase --continue

interractiveモードを中止したい場合は
git rebase --abortを実行すると
gitのリポジトリはgit rebaseを実行する前に戻ります

gitだけに限らずCUIでの操作は今どの状態にいるかを意識して作業しましょう
思わぬ事故を防ぐためには大事です

長くなりましたが説明は以上になります
お疲れ様でした!

まとめ

  • 1個前のコミットの修正は
    git commit --amendを使う
  • 2個以上前のコミットの修正は
    git rebase -i HEAD~Ngit commit --amendを使う
  • rebaseを中止したい場合は
    git rebase --abortを使う
3
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
3
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?