社内勉強会ネタ：Git/TortoiseGitでバージョン管理をはじめよう

「バージョン管理したことない」という人も対象に含めた、社内勉強会用の資料です。
Git特有のインデックス・ステージング・マージ・ブランチ操作みたいな話は一旦除いて、バージョン管理自体をWindows上でTortoiseGitを使って始めてみるには、みたいな内容になってます。

ちなみにGitの入門用記事としては [サルでもわかるGit入門〜バージョン管理を使いこなそう〜【プロジェクト管理ツールBacklog】](https://backlog.com/ja/git-tutorial/) をどうぞ。

---

- 2019.07.03 書きかけの部分、まだあるけど時間ないので一旦アップします😒

# バージョン管理とは

ファイル(ファイル一つ単体とは限らない)の変更を管理するためのシステム。
ファイルサーバ上でエクセル管理してたら、↓みたいなこと、ありませんか？

| ファイル名            | 更新日              |
| ---------------- | ---------------- |
| 画面仕様書.xlsx       | 2019-06-16 13:12 |
| 画面仕様書_ver2.xlsx  | 2019-06-15 19:24 |
| 画面仕様書 - コピー.xlsx | 2019-06-16 17:21 |

これだけ見ると、「最新は『画面仕様書 - コピー.xlsx』なんだろうけど、これきっと『画面仕様書.xlsx』と『画面仕様書_ver2.xlsx』の差分が含まれてないよなきっと。。。」と思ったりしませんか？

こういった版(バージョン)管理をシステムにやらせようってモノ。

バージョン管理することで、上の例であれば、エクスプローラ上では「画面仕様書.xlsx」のみ存在する状態となって、「最新がどれかわからん！」状態から脱却できます。

- 過去のあのバージョンってどんな内容だったっけ
- この日の状態と次の日の状態の変更点ってどんなだっけ
- このファイルのレビュー前の状態と、レビュー指摘事項を更新したバージョンを保持しておきたい

なんてことは、全部バージョン管理ツールにやらせましょう。

# バージョン管理の種類

大きく分けて2種類。
現在のトレンドはGit(のはず)。

## 集中型(中央型)

- 例
    - Subversion(SVN)
    - CVS

みんながアクセスするためにリポジトリを持った「サーバ」を用意する必要があります。

![version-control_集中型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/4e4a3fb1-23b1-e865-0982-d7b118d3ce1c.png)

- リポジトリサーバ上から`checkout`することで、ローカルの作業ディレクトリへ__バージョン管理されているファイルを__ダウンロード
- 手元で編集して`commit`することでリポジトリサーバへアップロード
- ほかの人がcommitしたファイルは`update`でローカルの作業ディレクトリへ取り込み

リポジトリサーバを立てるには、Apache Web Server + WebDAVにSubversionプラグインを組み込んだりして構築したりします。
Sambaでも動くっちゃ動くけど、サポートされてないファイルシステムだったきがする。。。(うろ覚え/過去の知識)

VSS？知らない子ですね。。

## 分散型

- 例
    - Git
    - Mercurial

リポジトリは各ユーザのローカルにそれぞれ保持しています。

![version-control_分散型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/ab4ca58f-6487-1697-bfba-25bd01ec3f92.png)

- リモートリポジトリがある場合…
    - `clone`することで、ローカルへ__リポジトリを__ダウンロード
    - ローカルのファイルを編集して`add`＆`commit`してローカルリポジトリへ反映
    - (1機能テスト完了など)キリのいいタイミングで`push`することで、ローカルリポジトリの変更履歴をリモートリポジトリへアップロード
- ローカルリポジトリをまず作成して場合…
    - 作成したファイルを`add`して`commit`
    - 作業内容に応じて`branch`作成
    - リモートリポジトリがあれば`push`

リモートリポジトリとして動作するサーバが無くても使用できるのが「ちょっと使う」レベルだと大きなメリット。
リモートリポジトリとしては、有名どころのオンラインサービスで[GitHub](https://github.com/)とか[GitLab](https://gitlab.com/)など。
また、GitLabは、社内LANなどのプライベートネットワークでリモートリポジトリを動かすためのGitLab CEもあります。
プライベートネットワークで動かすには、ほかにはwar単体で簡単に動かせる[GitBucket](https://github.com/gitbucket/gitbucket)など。

GitHubやGitLab、GitBucketなど、リモートリポジトリに特化したGitのサーバは、Issue管理やWikiなど、プロジェクト管理機能を備えたものが多い。
GitLabはDockerなどで使えるプライベートなコンテナレジストリも内蔵しています。

# WindowsでGit

## Gitのインストール

WindowsOS上でGitを使うためのアプリケーションのインストール

### Git for Windows

[Git for Windows](https://gitforwindows.org/)

インストールすると、Gitのコマンドラインツールが一式セットアップされます。
最近のバージョンは、ちょっとしたGUIも内蔵しているので、もしかしたらこれ単体でもそれなりに便利に使えるかもしれない(が、筆者は標準のGUIツールは使いこんでないので説明不可)

面白いのは、Git for Windowsをインストールすると、Windows上でLinuxコマンドを使えるようになるMingw64というもの(←かなり大雑把な説明)もセットでインストールするため、基本的なLinuxコマンド(lsとかfileとかgrepとか、、、curlやsshもある)も使えるようになります。

### TortoiseGit

[TortoiseGit – Windows Shell Interface to Git](https://tortoisegit.org/)

コマンドラインだけだとちょっととっつきにくいGit for Windowsに、GUIを提供するアプリケーション。
これをインストールすると、エクスプローラの右クリックメニューにGitのメニューが追加されるので、一般の人(?)なら普段使ってるWindowsのエクスプローラで、Gitのバージョン管理ができるようになります。

また、ログやファイルの差分表示も結構強力で、画像はもちろんMSWordファイルなんかも頑張ってくれるので、便利。

[日本語設定にするためのLangage Pack](https://tortoisegit.org/download/)もあるので、日本語表示が良い場合は追加でダウンロードして設定してもOK.

ただ、操作が分からないときなどにGitの使い方をググると、コマンドで説明してる記事が大半のため、コマンド名と日本語の機能を対応づける作業という一苦労があるため、(多少の慣れは必要だけど)意外と英語版のままがよいかもしれない。(個人の感想)

## ローカルリポジトリの作成

リポジトリとして利用したいディレクトリ(空でなく、すでに作成済みソースファイルとかあってもOK)で右クリックして「Git Create repository here」を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/67a79383-f149-7f6b-3306-d3fde7c011ec.png)

すると英語で何やら聞かれるけど、「Make it Bare」にはチェックを入れずにOK押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/4ad0df4e-7c15-5ee8-dc29-d0b25a9cdc79.png)

これ、要は「作成したリポジトリで作業ディレクトリとして使わない」という設定。
今回は作成したリポジトリのある場所で、ファイル編集してコミットして…ということをやるので、チェックしない。

OK押下すると、リポジトリデータが保存される`.git`ディレクトリが作成され、Gitのローカルリポジトリが使用できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/126855b1-d1fc-2772-f322-e4827babd0ca.png)

## ファイルをバージョン管理する

### ファイルを作成

おもむろにテキストファイルを作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/2a0daae9-b468-898e-6261-fd312652bf94.png)

中身はこんな感じ。

```text:カレー部へようこそ.txt
カレーは粉でできてるのでカロリーゼロ
```

### addで管理対象にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/f0a196f6-9b87-be70-88ac-df08d93d02ba.png)

右クリックメニューの[TortoiseGit]->[Add]を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/195d4bba-0bf9-d6ee-48c6-b0a8793c3f6e.png)

すると`add`されてバージョン管理対象になり、TortoiseGitの機能で、エクスプローラ上のファイルのアイコンにadd済み(未コミット)状態を表すマークが追加されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/e029ecd6-66cd-8685-4a07-1e03b5eb4597.png)

※ 実はTortoiseGitでの`add`とGit自体の`add`は微妙に機能が違うんだけど、ややこしいので「TortoiseGitの`add`はファイルをバージョン管理対象にする」と覚えておいてください。詳しくは「[git add ステージング](https://www.google.com/search?q=git+add+%E3%82%B9%E3%83%86%E3%83%BC%E3%82%B8%E3%83%B3%E3%82%B0)」あたりでググると良き。

### commitで変更を確定・ログの入力

`add`しただけでは、バージョン管理対象になっただけで、まだリポジトリへ保存はされていません。
今度は右クリックメニューで[Git commit -> "master"]を押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/3a653a6c-7d13-3733-e1b0-a258e03f2da2.png)

すると、コミットの入力画面が起動。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/201158eb-b72e-21e8-dcb8-4f8605e4ea90.png)

基本的にチェックするのは3か所。

- 画面上部の「コミットログの入力フィールド」
- 画面下部の変更ファイル一覧
- 内容に問題なければ[Commit]押下

これで`commit`すれば、進捗ダイアログが表示され、(日本語ファイル名にした部分はちょっと表示できてないけど)問題なければコミットが完了します。
(※ pushボタンは、リモートリポジトリがあれば、押下すればpushされるけど、まだ用意してないので無視)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/4aee92f5-9c9f-a112-58ef-26eb14155065.png)

コミットが完了すると(未コミットのファイルがなくなると)、エクスプローラの表示はこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/1ccd9d3a-4d39-9d5f-6e7f-bdee8feaedfd.png)

### ファイルを更新する・差分を確認

2行目を追加してみます。

```text:カレー部へようこそ.txt
カレーは粉でできてるのでカロリーゼロ
カレーは汗をかくのでスポーツ
```

コミット済みの状態からファイルに変更があると、アイコンの表示が変化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/7e901709-6ecc-4884-69cb-54d8980218ac.png)

赤！の変更有アイコンがある場合、Git+TortoiseGitの差分表示機能で内容を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/253bf7cd-4fcb-bb9d-3c85-2876782749f0.png)

変更のあるファイル一覧。
ここでファイル名をダブルクリックすると、差分ビューワが起動。
(※ フォルダを右クリックして`diff`を押下すると表示される画面。ファイルを右クリックして`diff`すると、直接差分ビューワが起動します)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/669e3af2-c1bd-88db-754c-32354b2111ef.png)

左が最新のコミット済み状態、右が変更後の内容。
1行追加している箇所の色が変わって表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/7a5a61ee-2e42-f68c-6e8c-4667cfb0f7fc.png)

この内容でコミットしてよければコミットしましょう。
ここからコミット画面を呼べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/25e7c7ad-5513-7772-c424-26c483743dde.png)

※ コミット画面からも、下部の変更ファイル一覧のファイル名をダブルクリックすれば差分ビューワが起動します

ファイルの変更作業の途中で終業時間になって、次の日に続きをやるときに、「あれ？昨日どこまでやって、何がまだなんだっけ？」みたいなときに、差分を見てチェックすれば便利。

### コミットログを見る・差分を確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/25d21600-b4e2-0e07-0142-58d4c9ef36d7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/46c43aba-5eff-50a5-2c3c-70b1cf232d54.png)

この画面も、下部の「そのコミットで変更されたファイル一覧」のところでファイル名をダブルクリックすれば、そのコミットにおける変更点を確認できる差分ビューワが起動します。

### 過去バージョンのファイルを参照する

コミットログを表示してて「このコミットの時の差分でなくファイルそのものの内容を確認したい」場合、ファイルを右クリックして[Open]をすることで、そのバージョンのファイルを開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/3fefa2e2-0cb5-fec6-640e-3fca683eebf0.png)

最初のコミット時の内容

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/98f79ed1-3f46-89c9-9e41-5c2298516a71.png)

### テキストファイル以外のバージョン管理

普通にできます。
TODO: 画像やWordファイルの変更差分表示

でも、リモートリポジトリなどでほかの人との作業でマージ時には注意が必要かも。
(この辺りは「ロック」の概念がある中央型のSubversionの方が便利かも…と個人的に思ってたり)

# Appendix

## コミットログの書き方

Gitのコミットログ、文化としては以下のようになってます。

- 1行目に概要 (メールでいうsubject)
- 2行目は空行
- 3行目以降に詳細 (メールでいう本文)

コマンドラインで`git log`したり、前述のコミットログ表示時の一覧部分で1行目がサマリとして表示されるので、この書式にしておくと都合が良いため。

また、個人的にシンプルでわかりやすいと思って、自分管理のリポジトリで使用しているルールがこちら。(のライト版)
[Gitのコミットメッセージの書き方](https://qiita.com/itosho/items/9565c6ad2ffc24c09364)

簡単にいうと、1行目の概要の先頭にprefixを付けよう、というもの。
使うprefixは以下の通り

- fix: バグ修正
- add: (ファイルや機能の)追加
- update: 更新
- remove: 削除

## ブランチについて

### ワークフロー

- git-flow
- GitHub Flow

Gitでは、リポジトリ作成直後などデフォルトでは`master`ブランチでの作業となっています。
`master`は基本的にリリースバージョン用に使うブランチなので、Git操作に慣れたら別ブランチを作ってそちらで作業してみましょう。(作業完了したら`master`ブランチへ`merge`する)

※ Subversionだと`trunk`と`branch`があったけど、Gitは全て`branch`。(`branch`の配下に`master`やその他のブランチが同じ階層/名称で区別で存在してる。`tag`は別概念)

## リモートリポジトリ

TODO: あとで少し詳しく書き足す。。

- GitHub
- GitLab
- GitBucket

基本的な使い方はどれも一緒。
リポジトリを作ってローカルに`clone`するときは、コマンドラインでやるほうが便利。

GitBucketは`java`コマンドで簡単動作もできるけど、[Tomcatで動かすならこちら](https://qiita.com/zaki-lknr/items/e1841b176e2212bdb382)

## シェルの起動

フォルダの右クリックメニューの「Git Bash Here」から起動。
Git操作をググった結果、コマンドはでてくるけどTortoiseGitの操作がどれに該当するかわからないような場合は、ここから実行すればたいていはうまくいく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/670401cd-066b-c35c-09bf-827978bc8c12.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256859/e32703dc-3692-e31e-02e2-ee50b90e739c.png)

こんな感じ。

```console
zaki@mascarpone MINGW64 ~/src/sample (master)
$ ls -al
total 9
drwxr-xr-x 1 zaki 197121  0 7月   2 22:58 ./
drwxr-xr-x 1 zaki 197121  0 7月   2 23:33 ../
drwxr-xr-x 1 zaki 197121  0 7月   3 08:06 .git/
-rw-r--r-- 1 zaki 197121 68 7月   3 07:30 カレー部へようこそ.txt

zaki@mascarpone MINGW64 ~/src/sample (master)
$ curl --version
curl 7.61.1 (x86_64-w64-mingw32) libcurl/7.61.1 OpenSSL/1.0.2p (WinSSL) zlib/1.2.11 libidn2/2.0.5 nghttp2/1.33.0
Release-Date: 2018-09-05
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz TLS-SRP HTTP2 HTTPS-proxy MultiSSL Metalink

zaki@mascarpone MINGW64 ~/src/sample (master)
$ ssh -V
OpenSSH_7.7p1, OpenSSL 1.0.2p  14 Aug 2018

zaki@mascarpone MINGW64 ~/src/sample (master)
```

普段Linuxでシェル上で生活してる人ならこっちも便利。