こんにちは
一月に未経験で入社しましたミツキです。
今回は会社の研修で触れたgit revert
について記事を書きます。
git revert とは
git revert は、元に戻すコマンドの一種である。ただし、通常の元に戻すコマンドとは異なり、コミットがなかったことにするのではなく、「コミットによって加えられた変更を打ち消し、その結果を含む新しいコミットを追加」します。これは Git の履歴を保全するためであり、バージョン履歴の完全性の維持とコラボレーションの信頼性の確保のために重要です。参考
仕組み
git revert を使用すると、リポジトリのコミット履歴への変更を元に戻すことができます。git checkout
やgit reset
などの元に戻すコマンドではHEADと、refポインターが、指定したコミットに移動します。git revertでも指定したコミットを取得することができますが、refポインターが指定したコミットに移動することはありません。打ち消しコミットでは、指定したコミットを取得し、取得したコミットの変更を打ち消して、新しい打ち消しコミットを作成します。その後、ref ポインターは新しい打消しコミットをポイントするよう更新され、ブランチにもその情報が伝わります。
コマンド
ノーマルコマンド
$ git revert <打ち消したいコミットID>
メッセージを編集したいとき
オプションをつけないrevertでは、「Revert + 元のコミットにつけたメッセージ」といったメッセージがついてしまいます。任意のメッセージをつけたいのなら「-e」オプションをつけましょう。
$ git revert -e <コミットID>
コミットメッセージを編集しない
$ git revert --no-edit <コミットID>
コミットする前までもどる
$git revert -n <コミットID>
実際の動き
一つ前のコミットをrevertする
$ git log -1
commit 6f32bfc693eaa14e19248b34d8b0becc1d68f4e5 (HEAD -> feature/dev_1)
Author: *********** <******.***@example.com>
Date: Sun Mar 7 22:45:54 2021 +0900
feature/dev_1 に変更を加えました
2.変更を加える前にrevertする
-------------------git revert-------------------------------------
$ git revert 6f32bfc693eaa14e19248b34d8b0becc1d68f4e5
[feature/dev_1 f7b2069] Revert "feature/dev_1 に変更を加えました"
1 file changed, 1 insertion(+), 3 deletions(-)
-------------------git log-------------------------------------
$ git log -2
commit f7b20691fd1cda34cb598f8f2ce4df71b93a90d6 (HEAD -> feature/dev_1)
Author: *********** <******.***@example.com>
Date: Sun Mar 7 22:49:43 2021 +0900
Revert "feature/dev_1 に変更を加えました"
This reverts commit 6f32bfc693eaa14e19248b34d8b0becc1d68f4e5.
commit 6f32bfc693eaa14e19248b34d8b0becc1d68f4e5
Author: *********** <******.***@example.com>
Date: Sun Mar 7 22:45:54 2021 +0900
feature/dev_1 に変更を加えました
logをみると「Revert "feature/dev_1 に変更を加えました"」と記録されています。また、初めに変更を加えたコミットも残っています。
コミット自体を消去するのではなく、指定したコミットの「内容」を打ち消し、尚且つrevertしたこともコミットすることになります。
3つ前のコミットをrevertする
$ git revert 462c0330cd7d48b2e91e41549896263eda75fa8d
error: could not revert 462c033... 変更1
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
コンフリクト発生
git status
で状況を確認してみる
$ git status
On branch feature/dev_1
Your branch is ahead of 'origin/feature/dev_1' by 7 commits.
(use "git push" to publish your local commits)
You are currently reverting commit 462c033.
(fix conflicts and run "git revert --continue")
(use "git revert --abort" to cancel the revert operation)
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: src/index.html
no changes added to commit (use "git add" and/or "git commit -a")
あなたのブランチは、7回のコミットで「origin / feature / dev_1」よりも進んでいます。
(「git push」を使用してローカルコミットを公開します)
現在、コミット462c033を元に戻しています。
(競合を修正し、「git revert --continue」を実行します)
(「git revert --abort」を使用して、元に戻す操作をキャンセルします)
マージされていないパス:
(「gitreset HEAD ...」を使用してステージングを解除します)
(「git add ...」を使用して解決をマークします)
両方とも変更:src / index.html
コミットに変更が追加されていません(「git add」および/または「git commit-a」を使用)
いくつか前のコミットをrevertした時、更新と削除どちらかを選ぶ必要があるっぽいです。(特定の変更のみをなしにすることはできない)
なので、「何回か追加の処理を加えてしまったけどn個前のコミットだけいらないなー」といった時は手動でコンフリクトを解消するほうが安全なのかな?🤔