Visual Studio CodeとGitHubを用いたGitバージョン管理方法

# Visual Studio CodeとGitHubを用いたGitバージョン管理方法

無料のコードエディタであるVisual Studio CodeとGitHubを用いたGitバージョン管理方法について、[初期設定](#クローン)から[プルリクエスト](#プルリクエスト)までの実用的な流れと[競合発生時](#競合解消)の解消方法を解説いたします。

# ソフトウェアのインストール
以下のURLから必要なソフトウェアをダウンロードしてインストールします。

* Git
  * ファイルの変更履歴等を管理するバージョン管理システム
  * https://git-scm.com/downloads
* Visual Studio Code
  * 無料で軽量かつ拡張機能が豊富なコードエディター
  * https://code.visualstudio.com/
# GitHubのアカウント登録
以下のURLからGitHubを使用するためのアカウント登録を行います。Sign upを選択してアカウントを発行します。（Sign upはアカウント発行。Sign inはログインとなります）

* GitHub
  * プロジェクトの管理及び開発を支援する開発プラットフォーム 
  * https://github.com/

# 拡張機能
* GitHub Pull Requests and Issues
  * Visual Studio Code上でプルリクエストが実行できるようになる拡張機能
  （Visual Studio Codeを開いて拡張機能（Ctrl + Shift + X）の検索欄にGitHub Pull Requests and Issuesと入力してインストールを選択する）
  * https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github

<br>

* Git Graph
  * Gitのブランチをグラフ化して可視化する拡張機能
  * https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph

# クローン
クローンしてリモートから取得したファイルを管理するためのフォルダ（例：sourceフォルダ）を任意の場所に作成しておきます。

Visual Studio Codeを開いてソース管理（Ctrl + Shift + G）から`リポジトリのクローン`を選択、`GitHubから複製`を選択してサインインを許可する。（リポジトリのクローンはCtrl + Shift + Pから`すべてのコマンドの表示`を行い入力欄に`git: clone`と打ち込むことでも可能）

![repository_clone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/832022cb-122b-6202-85ad-90129ce1e484.png)

Visual Studio Codeに対してGitHubの承認を確認する画面が表示されるので`Authorize github`を選択して承認する。

![authorize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/a67d9c5c-75be-2f48-150d-06dfa53a7ab1.png)

上記の承認以降`GitHubから複製`を選択するとアカウントに紐づいた`Public`のリポジトリが一覧で表示されるようになります。

`Private`のリポジトリや他者のリポジトリをクローンする場合には`リポジトリURLを選択するか、リポジトリソースを選択します。`と記載された入力欄に対象のリポジトリが存在するURLを入力します。（以下の画像の`HTTPS（画像上部のURLでも可）のURL`を入力します）

![clone_https.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/0c4016bc-b775-2362-4194-144c2ad31695.png)


クローン対象のURLを入力して選択すると`フォルダーの選択`ウィザードが表示されるので初めに作成した管理用フォルダを選択して`リポジトリの場所`を選択してクローンを実行します。

Visual Studio Code上にて`クローンしたリポジトリを開きますか？`と表示されるので`OK`を選択してワークスペースにリポジトリを以下の画像のように追加することができます。（`ファイル`の`フォルダーをワークスペースに追加…`から管理用フォルダに存在するリポジトリを選択することでも手動で追加できる）

![add_workspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/5bbc8001-4249-d700-c6bd-bd43bdebdad4.png)


最後にGitのコミットを行った際の情報元となる個人の識別情報を登録します。拡張機能のGit Graphが有効である場合には以下の画像のように`Git Graph`と表示されるようになるのでこちらを選択してGit Graphタブを表示させます。Git Graphが表示されたら歯車マークの`Repository Settings`から設定を開きます。

![config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/857cdc33-cfa2-b21e-9e73-c75b535c4322.png)



設定が開いたら`User Details`の`Edit`を選択して`User Name`と`User Email`に任意のユーザー名とメールアドレスを入力して`Set User Details`で変更を確定します。

![setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/f62b1963-b2a5-c70f-9e56-60ef57fcc559.png)


<br>
クローンの手順については以上になります。

<br>
<br>
<details>
<summary>Git Commandを用いたクローン方法（補足）</summary>

<br>
クローンしてリモートから取得したファイルを管理するためのフォルダ（例：sourceフォルダ）を任意の場所に作成しておきます。

<br>
Visual Studio Code上にてファイルからフォルダーをワークスペースに追加…で先程作成したファイル管理用のフォルダを選択します。

<br>
ターミナルから新しいターミナルを選択して先程ワークスペースに追加したフォルダを選択することで、以下の画像のように選択したフォルダのディレクトリパス上のコマンドラインを表示することができます。

![terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/0c8f0dea-dd3f-23fe-dfe7-1c528f3fc2ef.png)


初めにGitが使用できる状態にあるか否かを確認するために以下のコマンドを実行します。（Gitが使える状態にあれば現在のバージョンがコンソール上に表示されると思います。）

``` Shell
git --version
```

<br>
<details>
<summary>Gitの初期化</summary>

※GitHub上でリポジトリを作成している場合にはローカルリポジトリに.gitファイルが既に作成されているため以下の作業を行う必要はありません。

Gitの初期化を行い以下のコマンドが実行されたフォルダにて作業を行えるようにします。（コマンド実行後にフォルダに.gitファイルが作成されます。隠しファイルとなっているので見えない場合にはエクスプローラの表示から隠しファイルの項目をチェックします）

``` Shell
git init
```
</details>

<br>
バージョンが表示されて既にGitが使える状態にあれば以下のコマンドでGitHubからリポジトリをクローンします。

``` Shell
git clone クローン対象のURL
```

クローンが完了したら管理用フォルダの中にクローン対象のリポジトリが追加されていると思います。

最後に管理用フォルダ内のリポジトリにて以下のコマンドで個人の識別情報（ユーザー名とメールアドレス）が設定されているかを確認します。（Visual Studio Code上に一覧で表示されているワークスペースに対して右クリックをして「統合ターミナルで開く」からでもコマンドラインを開くことができます）

``` Shell
git config user.name
git config user.email
```

個人の識別情報が設定されていない場合には以下のコマンドで設定を変更及び追加することができます。

``` Shell
git config --global user.name "User Name"
git config --global user.email UserName@example.com
```

<br>
Git Commandを用いたクローンの手順については以上になります。
</details>

# プルリクエスト
`ソース管理`から`ビューとその他のアクション`を選択`プル、プッシュ`の中にある`フェッチ(Prune)`を選択することでリモートリポジトリの最新の状態を取得します。

![fetch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/65e11207-6339-b6de-e4c8-6b83dda9ce74.png)


初期設定であれば現在のローカルブランチはリモートブランチの`origin/main`を参照した`main`ブランチとなっております。（Visual Studio Code内の左下に現在作業中のブランチが表示されます。またプロジェクトによっては`origin/main`を`origin/master`と呼称する場合があります）

今回は開発用のリモートブランチである`origin/develop`を参照してローカルブランチを作成したいと思います。（現場によって参照するブランチ名や手順が異なる場合にはorigin/developの部分を任意のものに置き換えて以下の作業を行ってください）

`ソース管理`から`ビューとその他のアクション`を選択して`チェックアウト先…`を選択。`新しい分岐の作成元…`を選択して作成する任意のローカルブランチ名（例として今回はfeature/updateReadme）を入力してEnter。そうすると作成元を指定することができるので任意のブランチ（今回はorigin/develop）を選択します。（作成元にしたいブランチが表示されない場合には`フェッチ(Prune)`を再度実行することで作成元の一覧に追加されます）

上記の作業が完了すると以下の画像のようにローカルブランチが`main`から`feature/updateReadme`に切り替わります。（ブランチ名を直接クリックすることでもチェックアウトの作業が行えます）

![feature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/1cd60a85-bfe7-0fe4-0e31-d1a96bd95070.png)

実際に取得したファイルを編集してプルリクエストを行います。今回は以下の画像のようにREADME.mdファイルを編集して保存します。そうすると`ソース管理`に`1個の保留中の変更`と表示されるようになります。

![update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/317d7e61-a06d-164d-dff0-327c8ac2f4cc.png)


`ソース管理`からリモートリポジトリに渡したいファイル（先程変更を加えたREADME.mdファイル）に対して`変更をステージ`を選択してステージング（選択）します。（`変更`の横にある`＋`を選択することですべての変更をステージできます）

![before_add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/de8f772d-944e-f3ad-9353-30a29d2a0cca.png)


`変更をステージ`したことで`ステージされている変更`にファイルが追加されます。

以下の画像のようにコミットメッセージ（今回は"READMEの編集"）を入力して`コミット`します。

![after_add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/ee65d6d0-e42d-532c-a285-8ac4e03dd759.png)


コミットが完了したらプルリクエストを作成する前にプルリクエスト送信先のリモートブランチである`origin/develop`の最新の状態をプルで取得します。`ソース管理`から`ビューとその他のアクション`を選択して`プル、プッシュ`内の`指定元からプル…`を選択。対象のリモートリポジトリを選択してプルの指定元を一覧に表示されたリモートブランチから選択する。

このタイミングにて`競合`が発生する可能性があります。もし発生してしまった場合には[競合解消](#競合解消)を参照してください。

![pull.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/a7c5073e-28ad-4780-ed37-f35d841477e8.png)


拡張機能のGitHub Pull Requests and Issuesが有効である場合には以下の画像のように`Create Pull Request`ボタンが追加されているのでこちらを選択します。

![before_create_pull_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/bd70b2c7-8907-97ed-291a-e4e2320a9b7d.png)


GitHub Pull Requests and Issuesの各項目について説明します。
* `INTO`
  * 上部の選択リストは`プルリクエスト送信先`の`リモートリポジトリ`を表す。
  * 下部の選択リストは`プルリクエスト送信先`の`リモートブランチ`を表す。
* `MERGE CHANGES FROM`
  * 上部の選択リストは`プルリクエスト送信元`の`リモートリポジトリ`を表す。
  * 下部の選択リストは`プルリクエスト送信元`の`リモートブランチ`を表す。
* `TITLE`
  * プルリクエストの`タイトル`
* `DESCRIPTION`
  * プルリクエストの`概要`

以下の画像のように各項目を選択及び入力して`Create`を実行。`Publish branch`で対象のリモートブランチに対してプルリクエストを送ることができます。

![after_create_pull_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/b53546c8-8f06-b112-5d9b-05f2c71aabf3.png)



以上で実装者の作業は終了となります。

あとはReviewers（レビュアー）に設定されたメンバーがプルリクエストの内容を確認して問題がなければ`Marge Pull Request`を選択、さらに`Create Marge Commit`でプルリクエストを承認して`feature/updateReadme`を`develop`に取り込んだら修正（追加）は完了となります。

![pull_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/ca4ae7dd-70ba-f0e4-69ff-5a431b7735a7.png)


最後に拡張機能のGit Graphが有効である場合には以下の画像のように`ソース管理`の`View Git Graph`からGitのコミット履歴を確認することができます。

![git_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/2b58f5db-2a81-7af4-50ba-7db5be3ba38f.png)


<br>
プルリクエストの手順については以上になります。

<br>
<br>
<details>
<summary>Git Commandを用いたプルリクエスト方法（補足）</summary>

リモートリポジトリに接続されているかを以下のコマンドで確認する。
``` Shell
git remote -v
```

既に接続されている場合には以下のように表示される。(※GitHubを使用している場合には既にリモートリポジトリに接続されています）
``` Shell
origin  https://github.com/xxx/GitHubForVSCode (fetch)
origin  https://github.com/xxx/GitHubForVSCode (push)
```

リモートリポジトリに接続されていない場合には以下のコマンドで接続します。
``` Shell
git remote add origin クローン対象のURL
```

現在のローカルブランチを以下のコマンドで確認します。
``` Shell
git branch --contains
```

リモートブランチを直接参照してローカルブランチを以下のコマンドで作成します。
``` Shell
git checkout -b feature/updateReadme origin/develop
```

README.mdファイルを編集したら変更（追加）内容を以下のいずれかのコマンドでステージします。
``` Shell
git add . // 全てのファイルをステージ
git add -u // 変更を加えたファイルのみステージ
```

ステージしたファイルを以下のコマンドでコミットします。
``` Shell
git commit -m "メッセージ内容"
```

コミット内容に不備がある場合には以下のコマンドでコミットの取り消しを行うことができます。
``` Shell
git reset --soft "HEAD^"
```

プッシュの実行前に以下のコマンドでリモートリポジトリのdevlopブランチの最新情報をプルします。
``` Shell
git pull origin develop
```

コミットした内容を以下のコマンドでリモートブランチにプッシュします。(リモートブランチにfeature/updateReadmeが存在していればそのブランチに対してプッシュを行います。まだ存在しなければ新規でリモートブランチを作成します)
``` Shell
git push origin feature/updateReadme
```

プッシュが完了したらGitHub上にてプルリクエストを作成します。New pull requestを選択して新規でプルリクエストを作成します。（リモートへプッシュしたばかりであればCompare & pull requestからプルリクエスト作成することもできます）

![new_pull_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/2cec0a63-bcb7-c8c9-cdc8-54811b600859.png)


base（プルリクエスト送信先）をdevelopに変更。compare（プルリクエスト送信元）をfeature/updateReadmeに変更してCreate pull requestを選択します。

![new_pull_request_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/409c62c2-0239-59b8-294b-35e0476a07ea.png)


最後にタイトルと概要を入力してCreate pull requestを選択すればプルリクエストが作成されます。

![new_pull_request_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/c91036cf-3bce-531f-72c3-b4541016e559.png)


<br>
Git Commandを用いたプルリクエストの手順については以上になります。
</details>

# 競合解消
変更内容をコミットしてプッシュを行う前に、リモートのdevelopブランチから最新の情報をプルしてきたタイミングで競合が発生したものとします。

競合の内容はhuman.jsファイルにactive項目を追加しようとしたが既に他の作業者によってage項目が追加されていたため競合が起きてしまいました。

Visual Studio Codeにて競合が発生すると以下の画像のようになります。

![conflict.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/5a963909-920f-9222-219d-0bf6880e0e28.png)

Visual Studio Codeでは競合を解消するための以下の補助機能が存在しております。

* `Accept Current Change`
>プル（取得）してきた内容を破棄して、自分の変更内容を適用する。実行結果は以下となる。
>``` diff_javascript: human.js
>const human = {
>   name: "tanaka_taro",
>+ active: "soccer"
>}
>```

* `Accept Incoming Change`
>自分の変更内容を破棄して、プル（取得）してきた内容を適応する。実行結果は以下となる。
>``` diff_javascript: human.js
>const human = {
>   name: "tanaka_taro",
>+ age: '20'
>}
>```

* `Accept Both Change`
>自分の変更内容とプル（取得）してきた内容を両方を順番に適応する。実行結果は以下となる。
>``` diff_javascript: human.js
>const human = {
>   name: "tanaka_taro",
>+ active: "soccer"
>+ age: '20'
>}
>```

* `Compare Change`
>自分の変更内容とプル(取得)してきた内容の差分を比較するタブを以下の画像のように新規で開きます。（比較するだけなのでこのタブから編集を行うことはできません）
>
>![compare_change.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/0d5b3cd6-064b-f752-6c67-ea7aee9b16d6.png)



チームで開発を行っている場合、基本的には勝手に競合を自己解決してしまうことは意図せぬバグを発生させる可能性があることからも望まれません。（明らかなものは除くが、それでもなるべく一報を入れる必要があります）

まず初めに競合が発生した場合には該当のファイル（human.js）を編集した他の作業者に競合が発生したことを伝え、その上で修正内容を話し合い修正方針を定める必要があります。

話し合いの結果今回の修正方針としてはage項目、active項目共に追加する必要があるため`Accept Both Change`を利用して競合の解消を行いたいと思います。以下は適用後のソースコードとなります。

``` javascript: human.js
const human = {
  name: "tanaka_taro",
  active: "soccer"
  age: '20'
}
```

ですがこのままだとactiveとageの間にカンマ（,）が存在しないためエラーが発生してしまい、手動で以下のようにソースコードを修正する必要があります。

``` diff_javascript: human.js
const human = {
  name: "tanaka_taro",
+ active: "soccer",
  age: '20'
}
```

競合が解消されたのでもう一度ファイルをステージしてコミットし直します。

![conflict_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/27e8957f-ba44-d869-9982-ebaa0e631a59.png)


再度プッシュを行う前にリモートのdevelopブランチから最新の情報をプルして問題がなければリモートブランチにプッシュしてプルリクエストを作成します。

<br>
競合解消の手順については以上になります。

# ブランチ運用
最後にブランチの運用（概念）について簡単に説明いたしますので、既に十分理解している方や興味のない方は作業に戻ってもらって大丈夫です。

リモートブランチは主に次のような構成でできています。

* main（またはmaster）
  * 製品（成果物）を納品及び管理するためのブランチ

* develop
  * 製品（成果物）を開発するためのブランチ
  * mainから派生してmainにプッシュを行う

* feature
  * 製品（成果物）に機能を追加及びバグを修正するためのブランチ
  * developから派生してdevelopにプッシュを行う

* hotfix
  * 製品（成果物）に緊急の修正（脆弱性対応など）を行うためのブランチ
  * mainから派生してmainにプッシュを行う

今回ローカルブランチを作成する際に`origin/develop`を作成元にしていたのは上記内容が理由です。

またブランチを作成する際の命名規則として`feature/xxx`としていたのも上記内容が理由です。

基本的に開発者は`develop`と`feature`を主として扱うことになります。

`main`ブランチを古くは`mastar`ブランチと呼称しておりました。ですが昨今では人権運動の流れからセンシティブな用語を避けるような流れがIT業界でも広がっております。現場やネットの文献などでは`master`という名称がまだまだ使われておりますが上記のような社会的な情勢があることを鑑みてIT業界でも再認識する必要があります。

![git_flow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149636/3884299f-9991-ada5-8a52-cd9f2e5bc1d7.jpeg)

<br>
<br>

以上でVisual Studio CodeとGitHubを用いたGitバージョン管理方法についての解説を終了いたします。