Gitを使おうよ！ - Local編 -（GitKrakenを入れてGUIでGitを操作するハンズオン）

バージョン管理システムとよばれるもののひとつに**Git**というものがある。

そもそもバージョン管理とは何なのか、Gitはどう使うのか、GitHub、BitBucketといったGitホスティングサービスをちょっと使ってみよう！

# What's バージョン管理？
>バージョン管理システム（バージョンかんりシステム）とは、コンピュータ上で作成、編集されるファイルの変更履歴を管理するためのシステム。特にソフトウェア開発においてソースコードの管理に用いられることが多い。

引用 : [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)

**変更履歴を管理する**というのがミソ。
誰が、いつ、どのプログラムを、どのように変更したのかを記録しておいて、もし不具合が起きたときにどの部分の変更が作用しているのかを調べたり、不具合が起こる前の状態に戻したりすることを可能にするようなシステムのこと、という感じですかね。

英語では**Version Control System**、**VCS**なんて呼ばれたりしますね。

# Gitって？
GitはLinuxカーネルの生みの親として知られるリーナス・トーバルズさんがLinuxカーネルを作成する際、**もっと高速なバージョン管理システムほしいな**って思って作ったオープンソースのバージョン管理システムです。（ざっくり意訳）

キャッシュをうまく使うことで巨大なプロジェクトでもすばやく操作することが可能で、とても多くのプロジェクトで採用されています。

# GitHubとかって何よ
GitHubやBitbucketといったサービスは**Gitホスティングサービス**と呼ばれているもので、**Gitリポジトリを共有するためのクラウドサービス**のこと。

ここにGitリポジトリを**push**することでクラウドにアップロードされ、それを**clone**すると自分のPCでそのリポジトリを煮るなり焼くなり好きにすることができます。

# Gitを使ってみよう！
## インストール
WindowsやmacOSを使ってるひとはこちらからインストールしてこよう。
[Git](https://git-scm.com/)

Linuxとかを使ってる人は多分`apt install git`とか`yum install git`とかでインストールできると思われ（適当）
できなかったら適宜調べてくださいまし。

GitそのものはCUIのツールです。
なので、とりあえずお手持ちの環境でターミナルを開いてコマンドを打ってみましょう。

```shell
git --version
# git version 2.19.2
```

てな感じに表示されたらおっけーです。Gitが使えるようになりました。

## GUIクライアントも入れちゃおう
CUIってコマンド覚えたりするの辛いよね...
コマンドができなきゃ困るシーンもあるんだけど、それはもっとイケイケなエンジニアになる手前のお話なので、手早く楽にGitで幸せになるために**GUIクライアント**なるものをインストールしちゃいましょう。

### Git Kraken
僕のオススメは**Git Kraken**！
美しいグラフ表示と、コミットログがシンプルで見やすく、操作系も使いやすいです！
インストールはこちらから -> [Git Kraken](https://www.gitkraken.com/)

.debパッケージもダウンロードできますが、最新のUbuntuだとコケがちなのでそのへんは気合で頑張ってください...

後述の説明とかはすべてGit Krakenを使います。

<font color="Red">
2019/10/11 追記
※GitKrakenの料金が変更され、**Private Repositoryが無料版では開けなくなりました。**
</font>

### Source Tree
Source Treeも有名なGUIクライアントです。
GitホスティングサービスのBitBucketを提供しているAtlassianが開発しているツールです。
起動が早く、レスポンスは良いのですが、画面いっぱいに情報が詰められていて、シンプルさはGitKrakenに劣ると思います（主観）

あと、Linuxには対応していません。WindowsとMacで利用できます。

ダウンロードはこちらから。
[Sourcetree - 無料の Git & Mercurial クライアント | アトラシアン](https://ja.atlassian.com/software/sourcetree)

# リポジトリを作ってみる
初回起動時にはGitHubやBitbucketなどのアカウントでログインするように求められたはず。
なんとか回避するか、GitHubにサインアップしてログインしておこう。

Gitでバージョン管理を行なうために**リポジトリ**というものを作成する必要がある。
GitKrakenの左上のフォルダのアイコンをクリックするとこのようなダイアログが出るので、左の「Init」をクリックして、とりあえず自分のPCでのみ扱うリポジトリを作成してみよう。

<img width="1012" alt="スクリーンショット 2019-03-22 22.52.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/1dfee796-37fd-8e5b-d18f-c033750c78c5.png">

「Name」はリポジトリの名前。
そのままフォルダ（ディレクトリ）の名前になるので日本語やスラッシュ、¥などを使うのはやめておこう。

「Initialize in」の欄にはリポジトリを配置したいパスを指定する。
指定したフォルダの下にNameのところに入力した名前のフォルダが作られるので、このために新しくフォルダを自分で作成する必要はないかな。

「.gitignore Template」はGitのバージョン管理の対象にしないファイルを指定できる**.gitignore**というファイルのテンプレートを追加することができる。
とりま選ばなくていい。.gitignoreに関しては後述します。

「Lisence」は作ったリポジトリをGitHubなどでオープンソース・ソフトウェアとして公開する際に、利用者に従ってもらうライセンスファイルをどのオープンソースライセンスのものを入れておくかを選べます。
Gitの動作的には何も影響がないので選んでも選ばなくても良いです。
これも大切な要素なので最後の方で詳しく書きます。

必要事項を入力してCreate Repository！！

<img width="1440" alt="スクリーンショット 2019-03-22 23.12.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/bc1197ed-9420-7c3d-af27-90bc8a9bcd33.png">

こんな感じになればおーけーです。
では、この虚無なリポジトリにファイルを追加していきましょう。

ちなみに、リポジトリのディレクトリの中の隠しディレクトリ`.git`にこのリポジトリの情報が詰め込まれているのでゴミと勘違いして削除しないでね。
削除するとせっかくログを取っていた変更履歴が全てパーになります。

# コミットしてみる
作成したリポジトリのディレクトリに適当なファイルを作って見ましょう。

<img width="409" alt="スクリーンショット 2019-03-22 23.19.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/8c2ce214-db4b-14d8-f422-7f7b48bcf50c.png">


そうすると右側の「Unstage Files」の欄に作成したファイルたちが並んでいるはずだ。
それじゃあ、「Stage all changes」ボタンを押してこれらのファイルをバージョン管理の対象にしよう。

<img width="409" alt="スクリーンショット 2019-03-22 23.22.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/b97b195f-1aa8-b2d3-27b3-f0a018f3829a.png">

ほいで、したの「Summary」のところに何をしたのか、君の行動に名前をつけよう。
今回、僕がしたのは「helloworld.cの追加」だ。だからそうする。

Descriptionは細かいメモのようなことを書くのがいいと思う。
特になければ空欄で構わない。

で、ミドリのボタンを押して**コミット**しよう。
結果にコミットではなく、結果をコミットだ。

<img width="428" alt="スクリーンショット 2019-03-22 23.24.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/eb73d458-7c4f-9433-c32d-ea3f7176ccb9.png">

そうすると、このようにファイルを追加したことが記録される。
コミットを行なうことで、どのような変更が行われたのか知ることもできるし、もしものときにリポジトリをそのコミットの状態に戻したりすることができる。

原因不明のバグを発見したときにどの部分の変更が作用しているかを調べたり、バグがなかった頃の状態に戻すことが可能なんだ。素敵だろう？

できる限りすべてのファイルを監視したいけど、別に監視しなくていいファイルもあるよね。
じゃあそのファイルを監視しないように**.gitignore**を設定しよう！

# .gitignore
**.gitignore**にはファイルの変更の記録を取らなくていいファイルやディレクトリを指定することができるファイルだ。

さっきの例では実行ファイルの`a.out`も一緒に監視されているけど、正直いらないので.gitignoreでこいつを除外しよう。

`.out`の拡張子のファイルはすべて除外するようにしちゃおう。

```:.gitignore
*.out
```

ワイルドカードが使える。便利だね。

ただ、これだけでは除外は完了しない。
Gitは高速にバージョン管理を行なうために膨大なキャッシュを溜め込んでいる。
.gitignoreの変更を今すぐ適用するにはこのキャッシュを削除しなきゃならない。

このコマンドをリポジトリのディレクトリで入力しよう。

```bash
git rm -r --cached .
```

これでキャッシュが全て削除されて、.gitignoreに指定したファイルを無視してくれるようになる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/d34499a9-90f1-7889-113e-fbdbe9577123.png)

こんな感じで作成した`.gitignore`が追加され、無視するように指定した`a.out`は削除されたことになっている。
余計なファイルもロギングしてしまうと、他の環境でうまく読み込めなくなったり、Gitの操作が遅くなったりするし、何よりごちゃごちゃして気持ち悪いので必要ないと思ったものは除外しておくのがいいかな。

# Revertしてみる
「いろいろ書いたけど、なんかもとに戻したくなっちゃった。」
**そういうときはRevertしましょう。奥さん。**

Revertすると、ファイルをコミットしたときの状態に戻すことができる。

じゃあ、とりあえず適当に`HelloWorld.c`を書き換えてみよう。

<img width="416" alt="スクリーンショット 2019-03-22 23.45.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/0520225a-2033-d111-cb86-b8039ea4b306.png">

**「何かがおかしい。正しくプログラムを書いたはずなのにコンパイルが通らない...」**
プログラムの動作は変えていないはずなんだけどな、なぜだ...

はい。
Revertしましょ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/8d58a329-5fe0-edf1-468b-bff3d320bafb.png)

ファイル名を右クリックして、「Discard changes」を押してあげるだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/ac1da016-5341-f672-e1b2-9436bece2be1.png)

おっ、戻った戻った。めでたしめでたし。

# Branchを作ってみる
**Branch**（ブランチ）を作ることで変更履歴を分岐させることができる。
この分岐させたブランチを後でくっつけられるので、複数人で手分けして同時並行で同じプロジェクトを作ることができるのだ！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/6978209b-0b71-6e4d-807e-2d6fbffd84d1.png)

`master`ってとこを右クリックして「Create branch here」をクリックしてみよう。
そしたら、なんか文字が打てそうになるので新しく作るBranchに名前を付けてあげよう。

ちなみに`master`はデフォルトのブランチの名前で、だいたいは製品版バージョンが`master`。
プロジェクトにもよるけど`develop`なら製品一歩手前で、その他は追加機能だったり、そのブランチでの目的が名前になってることが多いと思う。

例えば、`feature/addService`だったら、`Service`というものを追加しようとしてたりとか、`fix/service`ならバグ修正とか、そんな感じ。
ブランチ名にスラッシュを入れると、フォルダ分けみたいになるので、うまく使っていこう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/78c7f139-15d8-ea6f-b315-b2b4933c4a6b.png)

ホイッと。
これでBranchを作って、`master`から新しく作ったブランチに切り替えができました。

試しに適当にファイルを追加して、コミットしてみると...
![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/bca6b300-8346-c0f8-117d-3fc10ee21f41.png)
こんな感じに、`master`とは別に履歴が記録されていくよ。

# Check outしてみる
ブランチを切り替えることを**Check out**（チェックアウト）という。
GitKrakenでCheck outするには他のBranchの名前のところをダブルクリックするだけよ。

![image.gif](https://media.giphy.com/media/WNlfkR7bpZwrCqQCxa/giphy.gif)

できた。

# Mergeしてみる
分かれたブランチをくっつけることを**Merge**（マージ）という。
Mergeはとても良くできてて、いい感じにくっつけてくれるし、同じ部分の変更が衝突することがあっても簡単に解決することができる！

試しに、また新しくブランチを作ってみよう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/b1af8155-2f33-b0ff-d94d-c5585d332bde.png)
`addJavaHelloWorld`と`addTashizan`を用意した。

`addJavaHelloWorld`ブランチの`HelloWorld.java`は以下の通り


```java
class HelloWorld{
    public static void main(String[] args){
        System.out.println(returnHelloWorld());
    }

    public static String returnHelloWorld(){
        return "Hello world!!";
    }
}
```

それに対して、`addTashizan`ブランチの`HelloWorld.java`は以下の通り

```java
class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello world!!");
        System.out.println(tashizan(4,5));
    }

    public static int tashizan(int a, int b){
        return a + b;
    }
}
```

名前の通り、足し算を行うメソッドを追加しただけ。
じゃあ、これらのブランチをマージしてみよう！！

<img width="622" alt="スクリーンショット 2019-03-26 9.23.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/273517/a71dff39-013f-bedc-11a0-888220401361.png">

取り込みたいBranchを右クリックして、「Merge feature/addTashizan into feature/addJavaHelloWorld」をクリックすることでマージできるぞ！！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/47f0c48b-a5b7-cf02-c72f-07c4f64109c1.png)
おっと、衝突してしまったようだ。

右の「Conflicted Files」欄にあるファイルをクリックして、衝突を解消してあげよう。

こーんな画面になるので、ぺっぺっぺーと必要な行をクリックしていこう。
必要なものをすべて選んだら左上の「Save」で変更を保存しよう。
![image.gif](https://media.giphy.com/media/hTDR6fNt9GIGOZvJJE/giphy.gif)
ちょっと独特な操作なので、実際に操作して慣れるのがいいかな。

衝突を解消し終わったら、右下の「Commit and merge」をクリックしてコミットしてあげよう。
衝突がない場合は超あっけなくMergeが完了するので、毎回こんなめんどくさいことする必要はないのよ。

# ひとこと : Git操作ができるエディタ・IDE
開発環境の中にはGitリポジトリを読み込んでIDEから操作できる親切なものもあります！
僕が知ってる限りだと、 IntelliJ IDEAやPyCharmといったJetBrains製のIDEとVisual Studio Codeなどです。

Visual Studio Codeだと、こんな感じに変更されたり、追加されたりしたファイルの一覧が出てきたり、左下の方からチェックアウトできたりとか、便利です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/273517/cf05bc91-94d7-dbdb-8bfd-8cc9fd228474.png)

こういうエディタを選ぶのも快適に作業する上で大事かも。


# シメに...
とりあえずLocal編はここまで！

次回 -> [Gitを使おうよ！ - Remote編 -（GitKrakenを入れてGUIでGitを操作するハンズオン）](https://qiita.com/okmt_okmt_/items/a11acbe009fc7dcdfd00)