# バージョン管理ってなんぞやの状態からはじめるGitとGitHub講座
## 1. はじめに
ITSアドベントカレンダーの14日目を担当させていただきます(大遅刻です.申し訳ないです).ITソルーション室所属のなかむーです.
今回は,「バージョン管理ってなんぞやの状態からはじめるGitとGitHub講座」ということでGitとGitHubを参考に,バージョン管理ツールを使うときの”お気持ち”の部分を解説していきたいと思います.
まず,このような記事を書くことになった経緯から話していきます.自分は,静岡大学情報学部情報科学科の1年で,後期になってから授業でグループ開発のようなものをする機会が増えてきました.これからもこのような形式の授業をやっていくと思ったので,バージョン管理ツールについての解説を自分の言葉で書いてみようと思いました.
特に今回は,GitとGitHubを使うことのうれしさについて解説していきたいです.
初めての記事投稿ですので間違いがあるかもしれないのでお気を付けください.間違ってたら指摘してくださるとうれしいです.
この記事を読んで気になったところや分からないところがあったら是非いろいろ調べてみてください.
## 2. バージョン管理とは?
バージョン管理とは,言葉の通り,バージョンを管理することを指します.
とは言っても,そもそもバージョンとは何のことを言っているか分からないかもしれません.
ここでいうバージョンとは(誤謬があるかもしれないが),プログラムコードの変更履歴や変更内容のことです.
バージョン管理を身近なところで例えると,ファイルを編集している最中に変更を取り消したいとき (`Ctrl` + `Z`)や変更の取り消しを取り消したいとき( `Ctrl` + `Y` )にやっていることを拡張したイメージです.
具体的にどのような点において拡張されているかというと,以下の4つが挙げられます.
1. 自分の好きなタイミングでファイルの状態(バージョン)を記録することができます.(この操作を続けると,ファイルの状態(バージョン)の記録の履歴が出来上がります.)
2. 現在作業中のファイルの状態を,一つ前に記録した状態(バージョン)に戻すことができます.(`Ctrl`+`Z`と`Ctrl`+`Y`の拡張版の機能)
3. 自分のファイルの状態(バージョン)を他の人に共有することができます.
4. プロジェクト内で並行開発をすることができます.(この操作をする際には注意が必要です.)
## 3. Gitとは?
バージョン管理ツールのひとつです.バージョン管理ツールには,さまざまな種類があります.Gitは,分散型バージョン管理ツールという種類に分類されます.Gitには, `add`, `commit`, `push`, `pull`, ローカルリポジトリ,リモートリポジトリ,ブランチ,マージという概念があります.
## 4. GitHubとは?
インターネット上でリモートリポジトリの作成と運用をするサービスがGitHubです.リモートリポジトリとは,インターネット上のどこかに存在するプロジェクトのことです.GitHubなどが提供しているサービスをホスティングサービスといいます.
GitHubは,最も有名なGitのホスティングサービスです.
## 5. バージョン管理することのうれしさ
### 5.1. 個人開発でのうれしさ
- ファイルの状態を都度記録しておくことで,いつでも一つ前の状態にもどすことができます.
- 普段,VScodeなどで使っている `Ctrl`+ `Z`や `Ctrl`+ `Y`の,取り消す範囲を自分の好みに決められると思ってよいです.
- 他の人に自分のコードをレビューしてもらうときに,簡単に自分のコードを共有できます.
### 5.2. グループ開発でのうれしさ
- 個人開発でバージョン管理することでのうれしさに加えて,複数人で同じプロジェクトを進めていく上での問題を解決してくれます.
- 自分の(最新の)ファイルの状態を他の人に共有できます.
## 6. 基本的な利用方法
ここからは,具体的にどのような操作を行ってバージョンを管理していくのか説明していきます.
まず,はじめにリモートリポジトリを作成する必要があります.リポジトリとは,プロジェクトのことです.インターネット上にプロジェクトを公開することで他の人とそのプロジェクトを共有することができます.
GitHubのウェブサイトでリモートリポジトリを作成することができます.作成したリモートリポジトリを自分のローカル環境に `clone`します.(クローンの具体的なやり方は,各自で調べてみてください)
クローンをすることでリモートリポジトリをコピーしてローカル環境にローカルリポジトリを作成できます.
次に,個人開発のときのGit利用方法と,それに加えてグループ開発ではどのように使うのかを解説していきます.
### 6.1. 個人開発のとき
個人開発でGitを使う際に出会う概念を解説していきます.概念としては,全部で4つあります. `git add`, `git commit`, `git pull`, `git push`です.
まずは,ファイルの状態(バージョン)を記録する作業について解説します.
個人開発では,リモートリポジトリに最新のバージョンを保存( `git push`)する利点は少ししかありませんが解説します.
#### 6.1.1. バージョンを記録する方法
バージョンを記録するには, `git add`と `git commit`コマンドを主に使います.
アドとコミットの使う手順を文章にすると以下のようになります.
- 作業ディレクトリで `git add`した変更箇所の集合を `git commit`コマンドでローカルリポジトリ(正確には.gitディレクトリ)に記録します.
作業ディレクトリとは,あなたが編集しているファイルがあるディレクトリのことです.
`git add <ファイル名>`コマンドを実行することで指定のファイルの中の変更した箇所をステージング領域に追加します.
`git commit`コマンドでステージング領域に登録してある変更箇所をローカルリポジトリ(.gitディレクトリ)に記録します.
コミットをする際にはコミットメッセージを残します.コミットメッセージは,そのコミットを行った段階での状態の説明をします. `git commit -m "<コミットメッセージ>`"と打つことでコミットメッセージを残せます.

#### 6.1.2. リモートリポジトリへ保存する方法
個人開発の場合は,リモートリポジトリに最新の状態を保存することで万が一自分のパソコンが壊れてしまってローカルに存在するファイルが消えてしまっても別の端末からリモートリポジトリを `git pull`して開発を続行できます.

個人開発の場合,1日の作業の最後に `git push origin <ブランチ名>`コマンドを実行します.
そして,1日の作業開始時に `git pull origin <ブランチ名>`コマンドを実行します.
`git push origin <ブランチ名>`コマンドでは,ローカルリポジトリに記録されたコミット履歴をリモートリポジトリに送信します.
`git pull origin <ブランチ名>`コマンドでは,リモートリポジトリの状態をローカルリポジトリに反映します.
個人開発でのgit pull 操作は全く意味がないですが,グループ開発ではとても重要なものなので `git push origin <ブランチ名>`と `git pull origin <ブランチ名>`の組み合わせを理解してもらうために書きました.
### 6.2 グループ開発のとき
グループ開発では,先ほど説明したaddとcommitに加えて新しくブランチという概念が登場します.また, `git push origin <ブランチ名>`と `git pull origin <ブランチ名>`を使う頻度が変わってきます(やっていることは同じだけど使い方がちょっとだけ違うみたいな印象です).
個人開発とグループ開発の大きな違いはプロジェクトの開発に携わる人数の違いです.
グループ開発では以下のような場面に出会います.
- Aさんが編集したファイルの状態(バージョン)をBさんに共有したい.
- プロジェクト内で並行開発をしたい.
#### 6.2.1. 他の人に自分が編集した状態(バージョン)を共有する方法
ここで活躍するのがリモートリポジトリです.リモートリポジトリは,インターネット上に存在するため誰でもアクセスできます.ただ,編集はローカルリポジトリでしかすることができません.
つまり,リモートリポジトリの状態をローカルリポジトリにpullしたり,自分が加えた変更(コミット履歴)をリモートリポジトリにpushしてから他の人にpullしてもらえれば他の人とファイルの状態(バージョン)を共有することができます.(誰かがリモートリポジトリにpushしたら,その人は他の人に連絡して,リモートリポジトリをpullしてもらいます.)

上の図は,Aさんが更新したバージョンをBさんとCさんに共有している状況です.
まず,Aさんが自分のコミット履歴をpushします.
そしたら,BさんとCさんはAさんが更新したバージョンのリモートリポジトリをpullします.
この段階でBさんとCさんのローカルリポジトリのバージョンはAさんのローカルリポジトリのバージョンと一致します.
## 7. ブランチ機能について
GitHubでリモートリポジトリを作成する際にmainブランチという名前のブランチが自動で生成されます.
新たなブランチを作成しない限り,あなたが記録するコミットはmainブランチに記録されていきます.
新しいブランチは,自分で作成できます.
一つのブランチは,他のブランチに干渉しません.
mainブランチから独立して作業を進めるために新たなブランチをmainブランチから生やします.
新しく生やしたブランチをhogeブランチとすると,hogeブランチはmainブランチのパラレルワールドとも言えます.hogeブランチでいくら編集してもmainブランチには干渉しません.
丸をコミットとします.下の図の場合,赤丸のときのバージョンでmainブランチからhogeブランチを生やしています.hogeブランチを生やした直後は,mainブランチの赤丸のバージョンと一緒です.そこからhogeブランチでコミットを加えていくことができます.hogeブランチで加えたコミットはhogeブランチにあるので他のブランチ(mainブランチ)へは影響を与えません.

一度生やしたブランチは,いつか生やした元のブランチへ統合させてあげる必要があります.今回の場合,hogeブランチはいつかmainブランチに統合されます.
hogeブランチでの状態がmainブランチと整合性が取れている状態になったらmainブランチに統合します.この操作をmerge(マージ)といいます.
マージはとても慎重にする作業なのでマージをしてもよいか他の人が確認するpull request(プルリクエスト)という工程を踏むのが一般的です.

ブランチを活用するとプロジェクト内での並行開発を実現することができます.
ブランチの活用方法は多岐に渡ります.ブランチの使い方の方針
をチーム内で決めたりします.このようなことをブランチ戦略と言ったりします.
## 8. 最後に
最後まで読んでいただきありがとうございます.分かりづらい部分があったかも知れませんが,少しでもバージョン管理がどんなものなのか理解していただいたらうれしいです.
個人的にこの記事を執筆しながら自分の力不足を痛感する場面が多々ありました.来年この記事を読んで少しは成長したなと思えるように来年も頑張っていきたいと思います.