はじめに
Git初心者の私が使用したコマンドの中でも、過去のコミットの削除を行う方法をご紹介します。
前提
ディレクトリ構成とコミット履歴下記のとおりです。
これらのコミットに対して操作をしていきます。
$ tree .
.
├── first.txt
├── second.txt
├── test.txt
└── third.txt
$ git log --name-status
commit 1e0676bc80d26143c972aa9b08ff4940a10e22e8
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:42:35 2015 +0900
Added third.txt
A third.txt
commit 5e6448ddb2c4ecd12ec24175e58c49582836b45a
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:41:59 2015 +0900
Added second.txt
A second.txt
commit 64ca8df0c49f43ea9149e499c62d636ab9bcdd26
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:41:29 2015 +0900
Added first.txt
A first.txt
commit 1c14c4654f4ebd4aa88d75726bcfecb2e87a7f0b
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:38:44 2015 +0900
Added test.txt
A test.txt
コミットのロールバックを行う方法
あるコミットまで戻す方法です。
今回はsecond.txt追加のコミットの直後まで戻ります。
なのでコミットはもちろん、third.txtが存在しない状態が目標になります。
使用するコマンド
git reset [option] [commit]
オプションでは修正の範囲を指定します。
使用例
- [option]: 直前のコミットの内容をワーキングツリーから削除するため、
--hard
を指定 - [commit]: 2つ前のコミットまで戻るので、
HARD^
もしくは コミットのハッシュ値を指定
# HEAD^を指定する場合
$ git reset --hard HEAD^
HEAD is now at 5e6448d Added second.txt
# コミットのハッシュ値を指定する場合
$ git reset --hard 5e6448ddb2c4ecd12ec24175e58c49582836b45a
HEAD is now at 5e6448d Added second.txt
すると下記のように、コミット履歴からthird.txtを追加したコミットが消え、
最新のコミットがsecond.txtを追加したコミットになったことがわかります。
$ git log --name-status
commit 5e6448ddb2c4ecd12ec24175e58c49582836b45a
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:41:59 2015 +0900
Added second.txt
A second.txt
commit 64ca8df0c49f43ea9149e499c62d636ab9bcdd26
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:41:29 2015 +0900
Added first.txt
A first.txt
commit 1c14c4654f4ebd4aa88d75726bcfecb2e87a7f0b
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:38:44 2015 +0900
Added test.txt
A test.txt
下記からファイルが削除されていることも確認できます。
$ tree .
.
├── first.txt
├── second.txt
└── test.txt
これで無事コミットのロールバックを行うことができました。
上記ではコミットとthird.txt自体を削除するためにoptionに --hard
を指定しました。
git reset
で他のoptionを指定すると下記のような結果になります。
option | 削除対象 | 備考 |
---|---|---|
--hard | コミット + そのコミットでの変更内容 | |
--mixed | コミット |
git add されていない(インデックスに登録されていない) |
--soft | コミット |
git add されていない(インデックスに登録されている) |
指定なし |
--soft を指定したときと同様 |
過去のコミットを削除する方法
直前のコミットではなく、過去のコミットを削除する方法です。
今回は2つ前のsecond.txtのコミットを削除します。
なので、コミットが削除され、second.txtが存在しない状態が目標になります。
使用するコマンド
git rebase -i [commit]
使用例
- [commit]: 2つ前のコミットよりも前のコミットを指定します。
$ git rebase -i 1c14c4654f4ebd4aa88d75726bcfecb2e87a7f0b
上記を実行するとテキストエディタが開きます。
そこで、今回削除したいsecond.txt追加のコミットの行を削除し保存します。
pick 64ca8df Added first.txt
pick 5e6448d Added second.txt <-この行を削除
pick 1e0676b Added third.txt
# Rebase 1c14c46..1e0676b onto 1c14c46
#
# 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
それではコミット履歴からsecond.txt追加のコミットが削除されているか確認します。
$ git log --name-status
commit eb30f92d9fadfc1127001ef9fd4ff86eab4c27a8
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:42:35 2015 +0900
Added third.txt
A third.txt
commit 64ca8df0c49f43ea9149e499c62d636ab9bcdd26
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:41:29 2015 +0900
Added first.txt
A first.txt
commit 1c14c4654f4ebd4aa88d75726bcfecb2e87a7f0b
Author: Your Name <you@example.com>
Date: Wed Dec 16 10:38:44 2015 +0900
Added test.txt
A test.txt
コミット履歴からは削除されていることが確認できました。
では次にファイル自体も削除されているかを確認します。
$ tree .
.
├── first.txt
├── test.txt
└── third.txt
これでコミット、ファイルともに削除されていることが確認できました。