VSCodeでのGitの基本操作まとめ

# はじめに

一年前に新人研修でGitを担当して[Tigの記事](https://qiita.com/y-tsutsu/items/98fc75b8814c99619cf4)を書いたのですが，今年も同じくGitの研修を担当することになりました．新人さんたちにとってはターミナル環境はとっつきにくい人も多いようで，短い研修期間では操作自体に苦戦してしまい，Gitそのものを理解するというところに力を割けない人も少なくありませんでした．
それを踏まえて今回はGUIで操作しやすい環境を検討したのですが，以下のポイントを踏まえてVSCodeを使うことに決めました．

* マルチプラットフォームで使える．（研修はWindows環境で行いますが，業務ではLinuxデスクトップ環境も使うので）
* Gitの基本的な内容はVSCode上でGUI操作が可能．
* Gitの内容とあわせて，プログラミング用のテキストエディタの一例として，導入しやすそうなVSCodeを紹介．

VSCodeを使ったGitの基本的な操作を一通りまとめていきます．

# インストール

GitとVSCodeをそれぞれインストールします．Windowsの場合は次のリンクからインストーラをダウンロードしてインストールを行います．

* [Git for Windows](https://gitforwindows.org)
* [Visual Studio Code - Code Editing. Redefined](https://code.visualstudio.com)

また，VSCodeの`Git History`という拡張機能をインストールします．Gitのコミット履歴を見やすく表示することができます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/d0929bfe-610b-8d65-e592-a2e1739db7f5.png)
以降の内容はWindows環境で操作を確認しながらまとめます．

* Windows 10 Pro
* git version 2.21.0.windows.1
* Visual Studio Code 1.33.1

ただしGitもVSCodeもマルチプラットフォームで使用できるので，LinuxやmacOSでも参考になると思います．

## Gitの初期設定

Gitをインストールしたら，まずは次の内容くらいは初期設定をしておくとよいです．Git for Windowsに同梱されている`Git Bash`を起動して，以下の内容でコマンドを実行します．

* ユーザ名とメールアドレス
* エディタ，マージツールの設定（ここではVSCodeを指定しています）
* pushのデフォルト方式を指定（追跡ブランチに対してpush）

```console
$ git config --global user.name 'username'
$ git config --global user.email 'username@example.com'
$ git config --global core.editor 'code --wait'
$ git config --global merge.tool 'code --wait "$MERGED"'
$ git config --global push.default simple
$ git config --global pull.rebase false
$ git config --global core.quotepath false
```

# VSCodeの起動

エクスプローラ上で作業ディレクトリを作成し，右クリックのメニュー（Open with Code）からVSCodeで開きます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/67eac39b-f480-a2bc-9500-557e6cfafefd.png)

# リポジトリ作成

まずはGitリポジトリの作成（初期化）を行います．
サイドバーのソース管理を表示して，リポジトリの初期化アイコンをクリックします．初期化するディレクトリを聞かれますが，VSCodeで開いている場所が初期表示されているのでそのまま選択して進めます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/1aa64d47-34bc-2918-aab2-2ed17ac07641.png)
リポジトリの初期化をすると，表示が次のように変わります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/dc01cfc1-ffaf-747b-eafe-d9a31de9e7aa.png)

# コミットしてみる

foo.txtを作成します．ファイルの作成はエクスプローラで行ってもいいですが，VSCodeのサイドバー上で操作することもできます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/ec2b84a5-052c-9d7a-9f89-208ab5f686a3.png)
ファイルの作成と編集を行うとサイドバーのソース管理に更新ファイルの一覧が表示されます．`+`アイコンでステージングされます．取り消す場合は`-`アイコンです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/7740dfc3-1524-1675-1fb7-6ec7775aaa86.png)
ステージングした状態からコミットメッセージを入力して，チェックアイコンでコミットが完了します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/145b178e-2ed6-41ba-4c6f-bd5403cc4883.png)
続けて以下のように編集してもう一度コミットをします．（コミットメッセージは`add A`）

```text:foo.txt
A
```

# コミットログを見る

はじめにインストールしておいたGit Historyで先ほどのコミットログを確認することができます．Git Historyの表示はコマンドパレットを<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>で表示して，`Git: View History (git log)`を実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/23101851-28bb-9987-31f0-9c8c99418953.png)
次のようにコミットの履歴が確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/1d9c5962-34b2-a540-84eb-2041e3ff7857.png)
コミットの履歴からファイルの変更内容を確認することもできます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/8ffa327b-af1e-5bc8-0887-e9d416c34032.png)

# ブランチを作成する

現在のmasterからブランチを作成してみます．画面の左下のブランチ名（master）が表示されている個所をクリックし，`新しいブランチを作成`を実行します．手順で作成するブランチ名を入力してブランチを作成します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/55adc917-eba1-d034-41bf-6a9aaf3882fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/227e8a28-42f4-d25c-c106-c0ec10425d1e.png)
Git Historyで作成したブランチが確認できます．`All branches`を選択すると両方のブランチが表示されます．ここでは`new-branch`という名前でブランチを作成しています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/112295c5-67cf-6472-b70a-ef88ad325535.png)

# ブランチをマージする

前準備として作成したブランチ上でコミットを行います．ここでは`new-branch`上で2件コミットしています．

1. foo.txtに`B`を追記（add B）
1. foo.txtに`C`を追記（add C）

Git Historyで確認すると次のようになっています．画面が更新されない場合はRefreshボタンをクリックすると更新されます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/44c4b888-15c2-1885-1024-7be6e2008fa5.png)
この状態から`master`に`new-branch`の内容をマージします．

まずはmasterに切り替えます．（チェックアウトします．）ブランチを作成したときと同様に画面左下のブランチ名をクリックしてmasterを選択します．切り替えが完了すると画面左下の表記がmasterに変わります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/60a818e8-b3ba-cae0-2c5b-2cbb4078c3f3.png)
切り替えができたらマージを行います．Git Historyでマージ元となるnew-branchの右にあるアイコンをクリックして`Merge this commit into current branch`を実行します．手順でnew-branchを選択し，Yesを選択してマージを実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/9b383d10-ba9b-8415-1940-ea6fb0adb583.png)
コンフリクト等が起きなければこれでマージが完了します．Git Historyを見るとマージできていることが確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/b5dcf5f9-945a-c0c3-2670-e7fa86f6bc10.png)

# 不要ブランチの削除

マージして不要になったnew-branchブランチの削除を行います．new-branchの`×`アイコンをクリックして確認ダイアログでOKを選択します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/3cd241b7-e899-7505-56ec-f5d56e8e1791.png)
Git Historyを見ると削除できていることが確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/c2235192-b7a3-906c-dea9-b146c515e367.png)

# プッシュする

ここまでの作業をリモートのリポジトリにプッシュしてみます．今回はGitHubに`git_tut`リポジトリを作成したものとして話を進めます．またSSH keyの登録なども事前に完了しているものとします．コマンドパレットから`Git: Add Remote`を実行します．手順でリモート名を設定しますが，ここでは`origin`と指定します．originは慣習的によく使われているデフォルトの名前です．続いてURLを指定します．URLは作成したリモートのリポジトリにあわせて設定してください．GitHubの場合は`git@github.com:<アカウント名>/git_tut.git`となります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/f338286f-0b2e-297c-d11a-a61a887b5bbf.png)
リモートの登録ができたらプッシュします．サイドバーのソース管理にあるメニューアイコンからプッシュを実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/679d5d10-b46a-ef59-293d-9cf49f35ce03.png)
Git Historyを見ると`origin/master`が作成されていることが確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/2f46253a-0a62-0539-1131-1e64e1a5868d.png)

## sshのパスフレーズ対策

sshでキーを生成するときにパスフレーズを設定していると，VSCodeでプッシュなどリモートリポジトリにアクセスするときにエラーが出てしまいます．その場合は以下を参考に解決してください．

[VSCodeからGitのリモートにアクセスできないときの対処方法（Windows 10）](https://qiita.com/y-tsutsu/items/ec984831e6c8262d3ff7)

ここの設定を行った後に，コマンドプロンプトからsshでの接続を確認するとパスフレーズの入力なしに接続できるようになっています．VSCodeからプッシュする前にsshの接続確認を行ってみてください．

```console
> ssh -T git@github.com
warning: agent returned different signature type ssh-rsa (expected rsa-sha2-512)
Hi y-tsutsu! You've successfully authenticated, but GitHub does not provide shell access. 
```

# ログからのブランチ作成

Git Historyから任意のコミットにブランチを作成します．各コミットの右にある＋Branchをクリックして，ダイアログに作成するブランチ名を入力してブランチを作成します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/6ae23a6c-220c-1643-d7bf-ad09f8e7033f.png)
ここでは`new-branch-2`ブランチを`add B`のコミットに作成しています．ブランチの作成後に画面の左下のブランチ名が表示されている個所をクリックしてnew-branch-2をチェックアウトします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/b4f9abc7-706c-dfc3-2027-1dd3eac14420.png)

# マージコンフリクトに対処する

`new-branch-2`ブランチで`foo.txt`の内容を更新してコミットします．この編集内容が「add C」のコミットとコンフリクト（競合）します．

```text:foo.txt
A
B
D
```

Git Historyを表示すると，以下のようになっているはずです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/3803ad41-eaf6-9fc6-2e12-b0a338c65c43.png)
`master`に戻って`new-branch-2`ブランチをマージしてみます．
画面左下のブランチ表示されている個所をクリックしてmasterをチェックアウトします．masterに切り替えたら前回と同様にnew-branch-2ブランチの右にあるアイコンをクリックしてマージを実行します．
マージを行った結果コンフリクトすると，サイドバーのソース管理にコンフリクトしているファイルが表示されます．ここで`foo.txt`をクリックすると，コンフリクトしている個所が次のように表示されるので，手動で修正を行います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/721bd73a-3813-0dfd-c8b7-092057063007.png)
今回は次のように修正して`+`アイコンでステージングします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/405cf236-b036-8ab8-1ebd-cfb08d7ba9c7.png)
ステージングしたらこれまでと同様にコミットします．Git Historyを表示するとマージされていることが確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/eac5070c-a49d-71e5-a430-0a81abdfc755.png)

# 編集の一部をコミット

masterで作業を続けます．foo.txtの内容を次のように更新します．

```text:foo.txt
A
HOGE
PIYO
B
C
D
E
```

サイドバーのソース管理でfoo.txtを選択すると次のように差分が確認できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/c1601abf-b7f6-a87e-800d-d29e21e49df2.png)
ここで画面右のコミットしたい箇所（今回はE）にカーソルを当て，右クリックのメニューから`選択した範囲をステージする`を実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/422d1e37-43bb-4dba-e9e9-4e317a4500d4.png)
サイドバーのソース管理でfoo.txtが二つに分かれ，先ほど選択した「E」だけがステージングされています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/e839cec9-05c8-a5e8-c63a-13ab3cffaf55.png)
この状態でコミットすると「E」の追加だけをコミットすることができます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/39994ebf-4952-6e6e-6643-c92a9aa88a6b.png)

# 不要な編集を戻す

先ほどコミットしなかった編集を削除します．サイドバーのソース管理から差分を確認すると，コミットしなかった「HOGE」と「PIYO」が残っています．ここでサイドバーのソース管理にあるアイコンをクリックすると，編集内容を破棄することができます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/09a3ebf7-4833-4247-e47d-b7180f43094a.png)

# ここまでをプッシュ

ここまでの状態を前回と同様の手順でプッシュしておきます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/fe48dfd5-f8d7-e733-ed62-6cc34bd0b5ad.png)

# フェッチ・プルする

前準備としてGitHub側でファイルの編集を行います．GitHubで`foo.txt`を表示して鉛筆アイコンから編集画面を開いて，最終行に`F`を追加します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/f381af1c-094c-05a1-28ba-c6aaa052a1ca.png)
コマンドパレットから`Git: Fetch`を実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/833aedd4-56ce-c00f-2981-e187689cd68b.png)
この時点ではローカルの`master`ブランチには反映されていません．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/9d245885-46fa-d460-71fe-1fcfe1d75160.png)
次はプルします．コマンドパレットから`Git: Pull`を実行してもいいですし，サイドバーのソース管理にあるメニューアイコンからプルを実行することもできます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/4fd0be20-02a6-9ab1-e787-c8ae986b92ee.png)
GitHubでの変更がローカルの`master`に取り込まれました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/60375aad-d34e-eb4d-7ced-0c478ea34140.png)
今回はフェッチしてプルという流れでしたが，フェッチせずいきなりプルすることもできます．

# おまけ

ここまでの手順で出てこなかったものについて付け加えておきます．

## クローンする

今回の説明ではローカルで作成したリポジトリをリモートのGitHubにプッシュする流れでしたが，すでにリモートに存在しているリポジトリをローカルにクローンすることもできます．
コマンドパレットから`Git: Clone`を実行します．手順でリモートのURLとクローン先のディレクトリを指定します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/23124444-6601-ee19-b53e-8e49ea38ee54.png)

## スタッシュする

作業中のファイルの編集を，いったん退避しておきたいときにスタッシュが便利です．
`foo.txt`の内容を次のように「G」を追加して更新します．

```text:foo.txt
A
B
C
D
E
F
G
```

サイドバーのソース管理にあるメニューアイコンから`一時退避`（スタッシュ）を実行します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/7e7afc87-0362-68a2-67aa-bbd647d3f11a.png)
スタッシュするとファイルの変更差分がなくなっています．スタッシュした内容を戻すには`一時退避内容を適用`（または`一時退避内容を適用して削除`）を実行します．

## Gitの管理から特定のファイルを除外する

除外設定を行いたいディレクトリ（トップでもOK）に`.gitignore`という名前でファイルを作成し，除外したいファイルの情報を記述しておくと，Gitの管理対象から外れます．サイドバーのソース管理に表示される内容にも反映されます．
.gitignore自体をコミットしておくと，複数人で開発をするときに同じ除外ルールでGit管理をすることができます．
設定パターンの一例を下記に載せておきます．

```text:.gitignore
# 拡張子が.exeのファイルを除外する
*.exe
# Bin/binディレクトリとその中身を除外する
[Bb]in/
# 特定のディレクトリの中の特定の拡張子のファイルを除外する
out/*.log
```

## コマンドパレットからのキーボード操作

ここまでの内容は，新人さん向けにマウス操作を中心にまとめましたが，操作の多くはコマンドパレットからも同じように行うことができます．コマンドパレットを使うとマウスを使わずにキーボードだけで操作することができ，慣れると効率的です．
コマンドパレットは<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>で表示されます．とりあえずコマンドパレットで`git`と入力するといろいろと候補が出てくるので，いろいろと試してもらうといいと思います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/a1e63f71-8d37-3c84-54a8-d91936e6080e.png)

## GitLens（拡張機能）

今回の記事ではVSCodeの標準機能での操作を中心にして拡張機能もGit Historyだけを紹介しましたが，もう一つおすすめの拡張機能である`GitLens`を紹介します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/7d77eff7-e947-2d42-e2cf-8a9cdd06fd48.png)
GitLensはかなり高機能な拡張になり，ここまでで紹介していない様々なGit操作を行うことができます．例えば`git blame`の表示や，サイドバーに表示されるコミット履歴から`git reset`などいろいろな操作ができます．
VSCodeで本格的にGitを使うのであれば試してもらうとよいかと思います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/0a1f4520-6337-9424-9c16-31f0c28f3c33.png)

## Git Graph（拡張機能）

もう一つVSCodeの拡張機能で`Git Graph`を紹介します．この拡張はGit Historyとよく似た拡張です．どちらかを入れておけばよいかと思いますが，使いやすかったので紹介しておきます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/42adfd82-65f7-24a5-d776-ba26a9a15a1e.png)
Git Historyと同様にコミット履歴をツリー形式で表示してくれます．またそこからさまざまなGit操作を右クリックメニュー等から実行することができます．両方試してみて好みのほうを使用してみるとよいかと思います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/4c55968c-88c4-d392-8733-a09de3a3b43c.png)
またGit Graphを使用するときは，ひとつおすすめの設定があります．コミット履歴のツリーから変更ファイルをクリックして差分を表示するとき，通常ではGit Graphを表示しているタブのグループでDiff表示されます．下記の設定を行うとDiff表示をとなりのグループで開いてくれるので，Git Graphが隠れることなく次々とファイルの差分を確認しやすくなっておすすめです．

```json
"git-graph.openNewTabEditorGroup": "Beside"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45310/959e7719-764e-cb30-b362-3897d1556540.png)

# おわりに

VSCode上でGitを使いながら開発を進めるにあたって，必要最小限の操作は説明できたと思います．とはいえGitの便利な機能や操作はまだまだたくさんあります．この記事をひとつのきっかけに，さらに使いこなしていってもらえると幸いです．