ソースコードのバージョン管理をするためにGitとGithubを試してみた

## はじめに
最近ソースコードの管理が魔界状態になってしまっており、作業効率が落ちていました。そこでよりよいバージョン管理ができるようにGitとGithubを使用して、より楽な管理方法がないか試してみました。
今までにもGithubを使ったことも有るのですが、コードを適当においておく場所として使用するだけでした。

　よい機会ですので、コード管理の方法をしっかり勉強することにしました。将来の自分へのマニュアルもかねて、今回試してみたことをまとめておきます。
　今回はWindowsで動作確認を行いましたが、Macを使用してもほぼ同じ手順で試すことができます。

## GitとGithubの関係
　Gitとはファイルのバージョンを管理するために使用するツールです。発生するファイルの変更点をバージョンとして記録し、記録した地点へいつでも戻れる仕組みを提供します。
　わかりやすく説明すると、コミットというセーブポイントをたくさん設けることができ、ファイルを以前の状態に戻すことができます。また、いつだれが何の目的で作業したかが記録されているため、作業者以外でも作業内容を把握しやすいという特徴があります。

このGitの仕組みを利用したサービスにGitHubというものがあります。
GitHubを使用するとインターネット上でのスムーズな共同作業が可能になります。GitHubは個人・企業を問わず無料で試用することができます。プライベート設定とパブリック設定があり、パブリック設定を選択すると、誰にでも閲覧できる状態になります。今回はGithubにリモートリポジトリを持ち、ローカルリポジトリとやり取りをすることで、Gitの使用方法を習得しながら理解を深めていくことにします。

## 用語
コミット：ファイルやフォルダの変更をリポジトリに記録する動作。
リポジトリ：Gitによって管理されているフォルダのこと。ファイルやフォルダの変更履歴を管理する。リポジトリ内に変更が加えられた場合に、自動的に検知される仕組みを持っている。
ローカルリポジトリ：自分用に手元のPC上に配置するリポジトリ
リモートリポジトリ：サーバに配置して複数人で利用、共有するためのリポジトリ（今回はGithub）
ワークツリー：PC上で実際に作業しているフォルダのこと
ステージングエリア：リポジトリへコミットする準備のための場所
プッシュ：これまでの変更履歴ごとファイルをアップロードする
プル：これまでの変更履歴ごとファイルをダウンロードする
ブランチ：Gitで記録する履歴を枝分かれさせるための機能
マージ：ブランチを統合すること
プルリクエスト：作業を行っているブランチからマージしたいブランチに対してマージを依頼すること
フェッチ：リモートリポジトリにあるすべてのブランチの状態を、現在のローカルリポジトリに影響を与えることなくすべて取得する機能

## Gitの使い方
### インストールと設定
[Gitの公式ページ](https://git-scm.com/)からGitをダウンロードしてインストールします。ウィザード形式で簡単にインストールすることができます。

GitをインストールするとGit BashというCUIツールもインストールされます。UNIXコマンドのように操作できて便利なので、Gitの操作に使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/6811f109-785b-035a-8009-7ecd187331c3.png)

Gitのインストールが済んだらGitの設定をします。
最低限必要と思われる
* ユーザー名
* メールアドレス
* 使用するエディタ
を登録します。エディタはvisual studio code(VScode)を使用しました。
Git Bashでのコマンド操作です。
```console
git config --global user.name hogename
git config --global user.email hogehoge@hoge.com
git config --global core.editor "code --wait"
```
設定内容を確認したいときは、git config --listコマンドを入力するか、.gitconfigファイルを開いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/849363d1-9528-a15b-6b72-d6a9630e2039.png)
このように確認できます。

### ローカルリポジトリを使ってみる
作業用のリポジトリを作成して、作成したディレクトリに入ります。
カレントディレクトリでテスト用のファイルを作成します。
/gittest/testfile.md
というファイルを作成したとします。
gittestディレクトリに入って
```
git init
```
コマンドを実行すると、カレントディレクトリにローカルリポジトリを作成することができます。
この時のディレクトリ構成はこのようになります。
```console
gittest
├── .git
└── testfile.md
```
git statusコマンドでローカルリポジトリの状態を確認することができます。

編集した内容を登録したい場合は（この例ではtestfile.mdファイル）、
testfile.mdをステージングエリアに登録してコミットする必要があります。
```
git add testfile.md
git commit
```
コマンドを実行するとVScodeが開くので、1行目にコミットタイトルを書き、1行開けて詳細メッセージを書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/c48171c7-d168-c842-b1d3-62824143b116.png)
コメントを書き終わったら保存をしてVScodeを閉じるとコミットが完了て、結果がコマンドラインに表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/4918134a-1d63-0017-a380-d3b61959a2b7.png)

git commitコマンドに-mオプションをつけると、コマンドラインから直接コミットすることができます。
```
git commit -m "コミット用のコメント"
```
※ワークツリーで行った変更はステージングエリアに登録しないとコミットすることはできない。ステージングエリアに登録した状態のファイルが登録されることに注意する必要があります。
### Git管理下のファイルの削除
Gitの管理下にあるファイルはエクスプローラーから削除することができないので、
```console
git rm 削除したいファイル名
```
で削除する必要があります。

### Gitで管理しないファイルの設定
ローカルリポジトリの中でもGitで管理したくないファイルがある場合は「.gitignore」というテキストファイルを用意して、その中にファイル名やディレクトリ名を書くことで無視されるようになります。.gitignoreファイルが配置されたディレクトリ配下のパスにしか効果がないので、「.git」ディレクトリと同じディレクトリに配置すると良いです。

### コミット履歴の確認
```console
git log
```
コマンドでコミット履歴が確認できます。

## GitHubとの連携
### GitHubとの接続の準備
[GitHubの公式ページ](https://github.com/)にアクセスして、アカウントの作成を行います。
アカウントはユーザー名、メールアドレス、パスワードを設定することで簡単に作成することができます。特に理由がなければ無料プランを選択して、メール認証を行います。

アカウントの作成ができたら、認証方法を設定します。パスワード認証と、sshでの公開鍵を用いたサーバー認証がありますが、今後も使用することを前提に公開鍵を利用した方法で認証を行います。
##### 公開鍵認証を行う方法
* SSH Keyの発行
* 鍵の保存場所の確認
* パスフレーズの入力
* 公開鍵の登録

鍵を作成したい場所で
```console
ssh-keygen -t rsa -b 4096 -C "メールアドレス"
```
コマンドを入力すると、「Enter the which to save the key」と表示されますので、Enterキーを押します。この時に表示されるパスは生成した鍵の保存場所です。
「Enter passphrase」と表示されたら、鍵を使用する際に必要となるパスワードを決めて入力します。確認のため2度の入力が必要になります。
生成した公開鍵の中身をGitHubの設定画面に登録するためにクリップボードにコピーしておきます。

GitHubのSettingsからSSH and GPG keysを選択してNes SSH Keyをクリックします。
鍵の名前を決めて、公開鍵の内容を貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/c324bb78-6ab2-5a64-7fc3-e94f7df43eee.png)
公開鍵を貼り付けてAdd SSH keyで登録したらGit Bashでの作業に戻ります。
確認用のコマンドを入力します。
```console
ssh -T git@github.com
```
「want to continue connecting(yes/no)」?と聞かれますので、「yes」と入力します。パスフレーズを聞かれますので、鍵を使用する際に必要になるパスワード（前の手順で決めたパスワード）を入力します。
「successfully authenticated」と表示されれば設定は完了です。

### プロジェクトの取り込み
githubをパトロールしてみて、興味があるリポジトリを見つけたらフォークして、ローカルリポジトリにクローンを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/00743e79-18b0-a208-e180-c07017d4174a.png)
複製元のリポジトリを表示した状態で右上にある「Fork」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/66d510c2-ecec-f87e-05e5-5fb945bb347e.png)
フォークが完了すると、自分のアカウントの中にリポジトリが取り込まれます。

次に自分のGitHubアカウントの中に取り込まれた内容を、自分のローカルリポジトリの中に取り込みます。
```console
git clone git@github.com:hoge/hogehoge.git
```
git@github.comの部分はGitHubからコピーするコピー用のurlになります。
コピー用のURLは、リポジトリのページのCodeボタンから取得することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/8fc6ac5b-5723-8f9f-5f6c-9192f7f1732d.png)
コピーが終わったら、新しいローカルリポジトリが作成されるので、そのディレクトリに移動します。エディタを開くために
```console
code .
```
コマンドを入力してカレントディレクトリをVScodeで開いて編集していきます。

 
### ブランチについて
ブランチとはGitで記録させる履歴を枝分かれさせる機能で、同時に複数の異なる作業をすることができ、内容ごとに別々に管理することができます。ブランチは複数同時に作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/bd90905d-3de5-6c38-4a39-0a8721422e56.png)
枝分かれさせたブランチを任意のタイミングで統合させることをマージと呼びます。編集作業ごとに作業用のブランチを作成して、編集と検証が終わったらmasterブランチにマージするという進め方が一般的です。

ブランチの作成は
```console
git branch 作成するブランチ名
```
ブランチの移動は
```console
git checkout 切り替え先のブランチ名
```
使用中のブランチの確認は
```console
git branch
```
コマンドで行います。

### マージ
ローカルリポジトリの内容をリモートリポジトリに反映させるために、プッシュという操作を行います。プッシュすることでローカルリポジトリの内容をリモートリポジトリに移動させた後にマスターブランチにマージさせます。
```console
git push origin ブランチ名
```
originのところはプッシュ先のリモートリポジトリになります。
クローン元のリポジトリは慣例的にoriginという名前が用いられます。
マスターブランチにプッシュを行うと、そのままマージが行われます。

マスターブランチ以外のブランチからプッシュを行った際は、GitHubのページから手動でマージを行います。（GUI操作で行うことができます）

マージとプルリクエストを組み合わせて、コードレビューを行うこともできます。

### コンフリクトについて
　異なるブランチで同じファイルの同じ行をそれぞれが編集してコミットしていた場合、マージ時にコンフリクト（競合）が起こります。
　コンフリクトが起こった場合は、該当のファイルの内容を確認して、コンフリクトを解消してからコミットを行うようにする必要があります。
イメージ的には、人間がマージ後の正しい姿を判断して、コンフリクトしている部分を手動で調整していきます。

以下はGitHubでのコンフリクト対処例です。
GitHubでコンフリクトが起こった際は場所を確認していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/d4aa761c-9e7b-468d-9b32-c1f2b0363752.png)
Resolve conflictsボタンを押すとコンフリクトが起こっている場所を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/b2ee60e3-a6d3-b62c-1a52-2a70ad132d42.png)
コンフリクトを取り除いて、画面上部にあるMask as resolvedボタンを押すと、コミットができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/e61921c5-a518-1a26-e356-2320c40d3bae.png)
これでコンフリクトが起こった際の対処ができました。

## まとめ
これでGitとGitHubでファイルを管理する手順を一通り試すことができました。
使ってみる前は少し難しそうなイメージでしたが使用してみると簡単に利用できて便利そうだなというイメージに変わりました。細かいルールもありそうですが、より便利に使用するための知恵だと思います。習うより慣れよの精神で使っていけば、すぐに慣れそうな感じです。
少しずつブラッシュアップしていこうと思いますので、ご意見やまさかり等大歓迎です。

## 追記
GitHubの学習用のサイトができたようです。
[GitHub skills](https://skills.github.com/)


## 参考情報
- 書籍
[いちばんやさしいGit&GitHubの教本](https://www.amazon.co.jp/%E6%A8%AA%E7%94%B0%E7%B4%8B%E5%A5%88/dp/429500524X/ref=sr_1_2_sspa?crid=3J6QJBG77K64M&keywords=%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84git%26github%E3%81%AE%E6%95%99%E6%9C%AC&qid=1652160224&sprefix=%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84Git%2Caps%2C195&sr=8-2-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExMEM4MUg2MUg5WFg4JmVuY3J5cHRlZElkPUEwNjExNDI3MzlOUDgwR09UUlkyNSZlbmNyeXB0ZWRBZElkPUEyNE1KWVU2U0ZUQTlGJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)  　横田紋奈　宇賀神みずき　著　
（初版を参考にしましたが第二版もあるようです。）
[サルでもわかるGit入門](https://www.amazon.co.jp/-/en/%E5%A4%A7%E4%B8%B2-%E8%82%87-ebook/dp/B07HHRGHKJ/?_encoding=UTF8&pd_rd_w=cMpwX&pf_rd_p=09fc5329-add5-4943-82f6-96f98cfdada8&pf_rd_r=D7MX0MG0AHMA46BEQ9E9&pd_rd_r=7e966d9c-2cc4-4280-8558-17302627b323&pd_rd_wg=00Mif&ref_=pd_gw_ci_mcx_mr_hp_atf_m)　大串肇　ら著
[現場でいきなりGitを使うことになったエンジニアが急いで「未経験者」から「初心者」になるための本](https://www.amazon.co.jp/-/en/%E7%9B%B8%E8%89%AF%E5%AE%97%E4%BB%8B-ebook/dp/B07YJ2KJZB/ref=sr_1_38?crid=YLOQ0F969GAU&keywords=git&qid=1652160489&sprefix=git%2Caps%2C166&sr=8-38)　相良宗介　著
- webページ
[GitHubとは何かわかりやすく解説！機能やメリットも簡単に紹介](https://www.sejuku.net/blog/7901)
[【絶対理解できる】Gitとは？特徴やできることまとめ！](https://www.sejuku.net/blog/5756)
[GitHub skills](https://skills.github.com/)