VSCodeとGitLensを使ってソースコード管理（ステージ、コミット、リバート、リセット）

#はじめに
今回は、Visual Studio CodeにGitLensを拡張した後、ソースコード管理を実際に試します。
前の記事で書きましたが、いまのところ、ローカルリポジトリで管理するだけですので、そんなにたいそうなことをする予定はないのですが、試してみます。
ソースコード管理は、SubVersionくらいしか使ったことがなく、VSCodeでソースコード管理するのは初めてなので、よくわかっていませんし、Gitのマニュアルを読んでというよりは、いろいろネット記事をみつつ、試して理解したものを備忘としてまとめます。
ざくっとまとめますし、よくわかっていないことも多いため、正確ではないかもしれません。自分への備忘の位置づけで、それが少しでも誰かのヒントになればくらいの気持ちです。
なお、Alexaのスキル開発に特化した記載になりますのでご注意ください。

#今回実施する内容
Visual Studio Codeで、Gitを使ってソースコード管理を実施します。
ステージ、コミット、リバーと、リセットを行います。
なお、Alexaのスキル開発に特化した記載になりますのでご注意ください。

#環境
OS:Windows 10 JP
Alexaスキル言語：Node.js
Editor：Visual Studio Code
Alexa developer console

#参考

#用語
##Visual Studio Code (VSCode)
マイクロソフトのフリーのプログラムのエディター。

##リポジトリ
色々な説明があるかと思いますが、シンプルに言えば、ソースコード自体、およびソースコードの変更履歴を保持するためのデータベースのこと。
VSCodeでは、Gitのことでしょうか？
GitやGitHubは、ソースコードをインターネットのサーバー上にリポジトリやソースコードを保存してくれるとっても有用なサービスです。

##コミット
ソースコードを変更したときに、その変更内容をリポジトリに管理するようにコミット（約束、委任）すること。

##ステージ
VSCodeのソースコード管理で初めて知りましたが、コミット前に、コミット対象にする変更を変更単位でコミットに加えるかどうかを判断すること。

##マスター
マスターとブランチと呼ぶみたいです。
マスターは、そのプロジェクトの正統なソースコードの改変をおこなっていく大本のこと。

##ブランチ
マスターとブランチと呼ぶみたいです。
ブランチは、マスターから枝分かれした分岐されたもののこと。
チームで開発する場合、それぞれがマスターからブランチを作って、それを再度マスターに戻すといったように使うようです。
一人チームなのであまりいらないかも。しいて言えば、マスターがおかしくならないように、いったんはブランチを切って開発するかなくらいです。

#前提条件
[VSCodeにGitLensをインストールしてソースコード管理の開始](https://qiita.com/Mount/items/c29ddfa6932fcb256887)を読んでいる。

#ソースコードの管理の基本
用語にも書いていますが、ざくっとソースコード管理の仕組みというか実施していることを用語とともにまとめます。

当たり前ですが、通常、ソースコードを編集して、そのファイルを保存すると、編集内容はファイルに保存されます。
また、保存後は、もとのファイルに戻すことはできません。
UnDoやReDoはありますが、一時的です。そのため、ファイルを自分でコピーして一時的に更新してみたり、過去のバージョンを保存しておいたりをするかと思います。
そういうことをGitがかわりにやってくれるというのが、ソースコード管理課と思います。

実際の動きとあっているかわかりませんが、まずはシンプルな概念です。
![ソースコード管理概要.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/4d3e2b01-f8f2-69e8-fd26-99ce31861378.jpeg)


単に**リポジトリ**と呼ばれる管理データベースファイルに、変更前後の内容と変更理由を保持させて、それをいつでも戻したり、また反映したり、その理由をみたりすることができるのが、ソースコード管理の基本と思います。

##ソースコードのステージとコミット
VSCodeで、ソースコードを編集して保存すると変更内容は記録されていませんが、リポジトリを作成すると、その編集内容を記録します。
その編集内容に対して、ステージやコミットという作業をすることで、リポジトリにどういった編集を加えたのかということを保持します。

編集内容が複数ある場合、それぞれに対し、その内容をリポジトリに加えるかどうかを判断するのがステージであり、**「ステージ」**や**「ステージング」**と呼びます。
**「コミット」**は、ステージしたものをまとめて、そのバージョンとして管理するように指示することです。
![ステージコミット.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/568b78d4-3a5f-670c-ecbc-7246c1fa0e0e.jpeg)

###ステージとコミットの実施方法
実際にステージとコミットを実施します。

1. 何かソースコードを編集し、保存する。
    今回は、`index.js`の最初に`"use strict";`を追記し保存。
2. 左側の「ソース管理」ボタンに数字が表示され、変更されたことがわかるため、ボタンを押す。
    まず従来は、変更しても特にソースコード上に何もなかったのですが、1行目のところに緑色が表示されるようになりました。これは変更個所を示します。
続いて、左側の「ソース管理」の画面では、`index.js`が変更されたためにファイル名が表示されており、Mと記載される。「M」は、Modified（変更済み）で、変更があったことを示します。
    ![ステージ前画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/8a4fdbe9-14e2-665a-c0e2-ceddf6d137be.jpeg)

3. この`index.js`の記載を選択すると、左側の「ソース管理」の`index.js`のところには、いくつかのアイコンが表示される。右側の「ソース画面」には、変更前と変更後の差分が表示される。
![ステージ選択画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/1d46722b-6c07-b3dd-cff4-f9a29478d1f5.jpeg)

4. アイコンは、３つで左から、「ファイルを開く」、「ステージする」、「変更を破棄」である。今回は、＋マークの「ステージする」を押す。
    「ソース管理」画面は、「ステージング済みの変更」が表示され、そこに`index.js`は記載される。また、「ステージする」アイコンは、「変更のステージング解除」の「－」アイコンになる。
![ステージ後画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/c1dd83d3-75e6-857a-b509-0b95553da838.jpeg)
    まだステージングしていない場合は、それらは「変更」のところに表示されたままです。
5. 「ソース管理」画面上部の「レ」マークをおして、コメントを追加し、コミットする。
    （今回は、「use strict追加」と記載）

これで、ステージングとコミットは終了です。

ところで、最初の「M」などのマークの意味は以下の通り。
###ソース管理の記号
| 記号 | アイコン | 意味 |
|:--|:--|:--|
| U | ![U.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/a1f7a589-9b43-b561-f33f-5422d50e7a48.jpeg)  |Untracked。追跡対象外。|
| A | ![A.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/cbb09788-3a6b-1260-7e0d-7b66e9fee8b1.jpeg) |Added。インデックスの追加。 |
| M | ![M.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/b06081b7-beff-c51c-4abd-ebdc55e0b6a0.jpeg)  |Modified。変更済み。 |

###GitLensでの画面
「GitLens」画面に遷移すると、以下のような画面になりました。
まずは、構成からです。

|名前 |説明|
|:--|:--|
| REPOSITORIES | リポジトリーの内容で、マスターとブランチの記載があります。 この階層を追っていくと「First edition.」や「use strict追加」など、コミットしたときに記載した文字列が記載される。|
| FILE HISTORY  | ファイル単位のコミットの内容が記載される。この欄は、REPOSITORIESでコミットしたものを選択すると記載がかわる。 |
| LINE HISTORY  | 行単位のコミットの内容が記載されれる。この欄は、REPOSITORIESでコミットしたものを選択すると記載がかわる。 |
| COMPARE  | よくわかりませんが、何か比較したものが残るのかな。 |
| SEARCH COMMITS  |コミットを検索できるようです。|

![GitLens画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/f669d023-1312-f659-8842-825028604653.jpeg)

画面をみると、`REPOSITORIES`のところに、最初に追加した`First edition.`やその後の`use strict追加`が表示されました。これでどう更新したかがわかるということです。
ここで、`index.js`をクリックすると前版との差分が表示されるようです。

##ステージとコミットの取り消し
ステージしたものやコミットしたものを取り消したくなることは当然発生します。

###ステージの取り消し（ステージング解除）
これは簡単で、コミット前であれば、「ソース管理」画面で、「ステージング済みの変更」のところに、取り消したいステージ済みの内容が表示されるため、「変更のステージング解除」の「－」アイコンを押せばよい。

###コミットの取り消し
何種類方法があるかわかりませんが、二つはあるようです。

| コマンド | 説明 |
|:--|:--|
| Revert Commit | **取り消したことを記録して**取り消しする。前の作業をもとに戻すコミットをするという感じです。 |
| Reset Commit | **取り消ししたこともなかったことにして**取り消しする。 |

####コミットの取り消し用サンプルデータ作成
`index.js`に以下の変更を加え、取り消し用のサンプルを作成する。

1. 上記で追加した`"use strict";`の追加はなかったことしにして、改めて、以下をステージングしたうえで、「定数test1追加」としてコミットする。

    ```
const test1;
```

2. 上記と同様に、`const test2;`を「定数test2追加」としてコミットする。

    ![サンプルコミット.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/677c07cb-c312-bd84-adef-651ab79af5a5.jpeg)
![サンプルソース.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/64e70e15-99b6-cd28-8d01-6614fcc52218.jpeg)
    
####Revert Commit
Revertして、`const test2;`を削除します。

1. GitLensメニューの`REPOSITORIES`のmaster配下の「定数test2追加」で右クリックし、`Revert Commit...`を選んでクリックしたうえでRevertする。これで、`const test2;`は削除され、Gitメニューには、ステージング済みの変更で、`const test2;'を削除したことが記載される。
2. Gitメニューでメッセージ欄に、「定数test2削除」と入力し、「レ」ボタンを押して、Commitする。

上記で、Revert Commitは終了です。
GitLensでは以下のように記録されました。

![Revert.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/c098bd7e-a61f-b61a-4ebf-f06a5130fd93.jpeg)

「定数test2追加」を取り消したことを、Commitしたということです。

「定数test1追加」まで取り消そうとすると、定数test1と定数test2の両方を取り消すことができるようです。
また、変更箇所が離れている場合（今回のように連続した行への変更ではなく、別の行に変更を加えた場合）は、定数test1だけ削除することも可能なようです。

でも、削除したことが記録されるため、それならば自分で削除してCommitし直せば同じかなと思いました。

####Reset Commit
Reset Commitは、SoftとHardがあるようです。
Softは、変更した内容は残したまま戻し、それをどう処理するかを再選択することができ、Hardはそういった情報も即座に削除してしまうようです。

Soft Resetして、`const test2;`を削除します。

1. GitLensメニューの`REPOSITORIES`のmaster配下の**「定数test1追加」**で右クリックし、`Reset Commit...`を選んでクリックしたうえでその後に`Soft Reset`を選んでクリックする。
先ほどと違い、**「定数test1追加」**を選択しています。取り消すというよりは、**「定数test1追加」**まで戻すという意味合いかと思います。
2. Gitメニューを開くと、「変更」のところに`index.js`に`const test2;`を追加したときの内容が表示されるため、これを「＋」の横にある「変更を破棄」を押して破棄する。

    ![soft_reset.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/132eb535-1903-522c-49af-d5a1013bd816.jpeg)
    ![soft_reset比較画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/1b4a3832-9705-5b72-5403-f076191732bc.jpeg)

3. GitLensメニューに戻って`REPOSITORIES`を確認すると以下のように、「定数test2追加」は削除され、また削除された記録もないことがわかる。 

    ![soft_reset後画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/950ecd6f-2b9d-de88-c060-dc62f091d3c1.jpeg)

注）`Hard Reset`の場合、上記の`Soft Reset`部分で`Hard Reset`を選ぶだけであり、そうすると2の手順はない。

#おわりに
今回は、VSCodeのGitと拡張のGitLensを使用して、ステージ、コミット、レバート、リセットを行いました。
触ってみると結構厄介で、Revertは特に期待しない動作が多かったように思いました。Resetのほうが思う通りに動作します。なかなか奥が深いです。

次回は、時間があれば、マスターとブランチを書きたいと思いますが、個人利用ではあまり必要なさげなのでどうしようか悩み中です。