git revertの記録

## こんにちは

一月に未経験で入社しましたミツキです。
今回は会社の研修で触れた`git revert`について記事を書きます。

## git revert とは

git revert は、元に戻すコマンドの一種である。ただし、通常の元に戻すコマンドとは異なり、コミットがなかったことにするのではなく、「コミットによって加えられた変更を打ち消し、その結果を含む新しいコミットを追加」します。これは Git の履歴を保全するためであり、バージョン履歴の完全性の維持とコラボレーションの信頼性の確保のために重要です。[参考](https://www.atlassian.com/ja/git/tutorials/undoing-changes/git-revert)

## 仕組み

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する
![スクリーンショット 2021-03-07 22.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048570/8a610941-02cc-79c6-4759-b2d6076652fb.png)

```
$ 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 に変更を加えました
```
結果
![スクリーンショット 2021-03-07 22.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048570/7a3e8416-a2ab-74c1-ed98-70a3c8cb8a49.png)

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'
```
![スクリーンショット 2021-03-07 23.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048570/e11a4228-bfd4-55df-0cca-374af1a985ce.png)

コンフリクト発生  
`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 <file> ...」を使用してステージングを解除します）
  （「git add <file> ...」を使用して解決をマークします）
両方とも変更：src / index.html
コミットに変更が追加されていません（「git add」および/または「git commit-a」を使用）

いくつか前のコミットをrevertした時、更新と削除どちらかを選ぶ必要があるっぽいです。（特定の変更のみをなしにすることはできない）
なので、「何回か追加の処理を加えてしまったけどn個前のコミットだけいらないなー」といった時は手動でコンフリクトを解消するほうが安全なのかな？🤔