「なんじゃこれ！？」を撲滅するためのGit基礎


#この記事を読んで理解できること
・GitとGitHubの違い
・Gitのファイル保存領域と役割
・Gitコマンドとその意味
・リモートリポジトリを作成し、GitHubにpushするまでの流れ
・【おまけ】Gitのショートカット(エイリアス)の設定方法

Gitの全てを網羅している訳ではありませんが、Git白帯の方には多くの学びがある内容で構成しています。
あまり深く踏み込まず、とりあえず抑えて起きたい要点をまとめましたので、ぜひ最後までお読み下さい。

#初心者からすれば「なんじゃこれ！？」の連続
はじめてGitに触れたのは半年程前。
リモートやらワーキングツリーやらコミットやらプッシュやら全てのGit用語に対して「なんじゃこれ！」と総ツッコミを入れていた当時を思い出しながら、当時の自分の「なんじゃこれ！？」を少しでも減らすことができるような自分想いな記事をここに書き記します。**（因みにGitのインストール等は既に出来ていると想定して話は進んでいきます。QiitaにGit関連の良質な記事が沢山ありますので、そちらを参照してください！）**

それでは**「GitとGitHubの違い」**の解説から始めます。

#GitとGitHubの違い
###Gitとは？
既にご存知かも知れませんが、Gitはプログラムのソースコードなどの変更履歴を記録・追跡するためのバージョン管理システムのことです。バージョン管理システムには分散型と中央集中型がありますが、Gitは分散型です。（中央集中型についてはここでは触れません。）

難しい話は抜きにして、書いたコード（ファイル）を変更・管理するためのシステムを「バージョン管理システム」と理解してください。分散型の大切な概念として「ブランチ」というものがあります。後ほど出てきますので、先程と同様に現時点では言葉だけ覚えておいてください。

###GitHubとは？
Gitを使っている人たち（開発者）が、さらにGitを便利に使うためのWebサービスのこと。GitのHub（中心）となってGitが集まってくるのでGitHub！この辺は分かりやすいですね。GitHub上でソースコードを管理することで、その他大勢の開発者と一緒にコードのレビューを行ったり、プロジェクトの管理をしながらソフトウェアの開発が進められることができるので、世界中で使われています。

#Gitは4つの領域で構成されている

**ワークツリー
ステージング
ローカルリポジトリ
リモートリポジトリ**
※リポジトリ＝ファイルや変更履歴などを置いておく場所。レポジトリとも呼ばれる。

初めはとてつもなくややこしいですが、後々「良くできたシステムやで！」と便利さに感動する日が必ず来るはずです。

以前勉強して上記の言葉を知って理解しているなら、次の説明を飛ばして次の段落にスキップしていただいた方が良いです。
仮に全然わからなくても何も問題ありません。はじめから知っている人なんていませんし、現段階では頭の片隅に置いておけばとりあえずは大丈夫です！！

###Gitの流れと4つの領域を簡単に解説

####**ワークツリー→ステージングエリア→ローカルリポジトリ→リモートリポジトリ** 
この流れで自分のPC内のファイルを移動しつつ、終点のリモートリポジトリ（自分のPC外。Web上）にデータを共有する。
（リモートリポジトリ以外は自分のPC内なので、最悪ミスってもなんとかなる範囲です。笑）

####**ワークツリー（自分のPC内）**：
自分のPC内にあるGit管理下置かれた作業領域。
「add」コマンドを実行することでステージングエリアに移動する。

####**ステージングエリア（まだ自分のPC内）**：
ローカルリポジトリに「コミット」するファイルを一時的に置いておくための領域。ワークツリーとローカルリポジトリの中間に位置する。
この領域があることで、保存するor修正のためワークツリーへ戻すなど選択することができます。いきなり保存されないので安心できる領域です。
「commit」することでローカルリポジトリに移動する。

####**ローカルリポジトリ（まだ自分のPC内。あと一歩でGitHubへ）**：
ローカル環境でバージョン管理するために配置する。
「push」することでリモートリポジトリに移動（共有）できる。

####**リモートリポジトリ（自分のPC外。GitHubに到着）**：
複数人が各自配置したローカルリポジトリをまとめている領域。
リモートリポジトリはWeb上にあるので、複数人でコードを共有・管理できる。


##Gitコマンドとその意味
Gitコマンドをいきなり網羅する必要はないので、初期段階でとりあえずは覚えておきたい！コマンドを抜粋、併せてコマンドの意味を解説します。

####**add(アッド)：ワークツリー→ステージングへ**

```bash
# 特定のファイルを指定ファイルを保存
$ git add <ファイル名>

# 全てのファイルを保存
$ git add .
```

####**commit(コミット)：ステージング→ローカルリポジトリへ**
```bash
# 変更内容を確認しながらコミットメッセージを追記。
$ git commit -v  

# ファイルの変更内容を追記
$ git commit -m "コミットメッセージ"
```

####**push(プッシュ)：ローカルリポジトリ→リモートリポジトリへ**

```bash
# リモートリポジトリのmasterブランチに、ローカルリポジトリのmasterブランチの変更内容を保存
$ git push origin master

# originとはリモートリポジトリのアクセス先に対してGitがデフォルトでつける名前のこと。
```
**originとは？**
リモートのアクセス先の名称です。
GitHubを利用する前には、リモートリポジトリにプロジェクトを作成します。その時にアクセス先として```git remote origin <githubのURL>```とoriginを指定するのが慣例となっているので、慣れるまでは深く考えずpushの時はoriginを指定すると覚えてください。

**branch(ブランチ)とは？**
履歴の流れを分岐(ブランチ)して記録するための仕組み。
分岐させることで、分身を作ることができるので、他のブランチに影響を与えず、分身の数だけ複数の変更を進められる。
例えて言うと、ブランチとはパーツのようなもので、各自がパーツを成長させて最後に本体（mainブランチ）に合体させるとパワーアップしてるみたいな感じです。
####status(ステータス)
```bash
# ファイルのステータスを確認（内容を通常表示）
$ git status

# ファイルのステータスを確認（内容を短縮して表示）
$ git status　-s
```

####diff(ディフ)
```bash
# ワークツリーとステージングの差分
$ git diff

# ワークツリーとHEADの前回コミットからの差分
$ git diff HEAD

# ステージングとHEADの差分(stagedとcachedはどちらも同じ結果になる)
$ git diff --staged
$ git diff --cached

# 修正したファイル一覧を表示
$ git diff --name-only
```
HEADは今いるブランチの最新コミットを示しています。
仮に今、ブランチAとブランチBがあるとしてブランチAにいるならHEADは「ブランチA」を指す。
ブランチAからブランチBに移動した場合、HEADは「ブランチB」を指す。

#### log(ログ)
```bash
# commitした変更内容を確認
$ git log

# 変更履歴を1行でコンパクトに表示
$ git log --oneline

# ファイルの変更差分を表示。Qで終了。
$ git log -p <ファイル名>

# 直近のコミット数を制限して表示
$ git log -n <コミット数>
```
 
#### branch(ブランチ) 
```bash
# 表示系
# ローカルブランチ一覧を表示
$ git branch

# リモートブランチ一覧を表示
$ git branch -r

# リモート/ローカル全てのブランチ一覧を表示
$ git branch -a

# 操作系
# 新しくbranchを作成
$ git branch <ブランチ名>

# branch<ブランチ名>を削除。完全にマージされていない場合はエラーになる。
$ git branch -d <branch>

# branch<ブランチ名>を削除。完全にマージされていない場合でも、強制的に削除する。
$ git branch -D <branch>

# 現在のブランチ名を<branch_B>に変更
$ git branch -m <branch_B>
```

#### checkout(チェックアウト) 
```bash
# 今いるブランチから<branch>に切り替える
$ git checkout <branch>

# <branch>を新しく作成して<branch>切り替える
$ git checkout -b <branch>

# 書き換えたものを、最新のコミット状態に戻す
$ git checkout --<ファイル名>  

# 書き換えたものを、最新のコミット状態に戻す
$ git checkout --<ディレクトリ名>  

# 全変更を取り消す  
$ git checkout --.

```
#### clone(クローン) 
```bash
# リポジトリをコピーする
$ git clone <クローンしたいリポジトリ>

#　タグやブランチを指定してコピーする
$ git clone -b <クローンしたいブランチ名> <クローンしたいリポジトリ> 
```
#### remote(リモート) 
```bash
# リモートリポジトリを作成
$ git remote add origin <リモートリポジトリURL>

# リモートリポジトリを削除
$ git remote rm origin
```
まだまだ理解しないといけないコマンドはありますが、一先ずは上記のコマンドの理解を深めて慣れないGit環境や操作になれるようにしましょう。掘り下げればキリがないので見たことないコマンドやわからないコマンドに遭遇した時は、その都度「ググり」ってじっくり吸収することをおすすめします。

信頼できる[Git公式サイト](https://git-scm.com/book/ja/v2)のリンクを貼っておきます。
「Git Pro」という解説本を無料で読めますので、困ったらまず「Git Pro」を見ると良いですよ！（日本語対応）

##リモートリポジトリ作成〜pushするまでの流れ
```bash
# 1. ローカル上（自分のPC内）の任意の場所に作業フォルダを作成  
$ mkdir <ディレクトリ名>

# 2. 作業フォルダに移動
$ cd <ディレクトリ名>

# 3. .gitフォルダ（隠れフォルダ）を作成
$ git ini #ini = initialの略称   

# 4. リモートリポジトリを作成
$ git remote add origin <リモートリポジトリURL>

# 5. ファイルをワークツリーからステージに移動 
$ git add . 　又は　　$ git add <ファイル名>

# 6. コミット前にファイルのステータスを確認する。(必須ではない。コミット前にステータスを一応確認したい)
$ git status

# 7. ファイルをステージングエリアからローカルリポジトリに移動
$ git commit -v  又は　　$ git commit -m "コミット内容をコメントとして書く" 

# 8. masterという名前のブランチを作成
$ git push origin master 

# 9. origin masterを楽にpushする(次回以降git push origin masterと入力しなくても、git pushだけで済む。)
$ git push -u origin master
```
　　
以上がローカル環境で作成したフォルダをリモートリポジトリにpushするまでの一連の流れです。
##【おまけ】Gitのショートカット(エイリアス)の設定方法
```bash
$ git config --global alias.st　status
```
本来なら```status```と入力していたものが、```st```だけで済むことになります。例えば ```git st```だけで```git status```と同じ内容を実行できるようになるので良く使うコマンドをエイリアスすると効果的です！そして、僕自身も下記のようにエイリアス登録していますが短縮できるのでめっちゃ便利です。

例：commit    →　ci
　　checkout  →　co
　　branch    →　br
　　status　  →　st


#最後に一言
これでGit基礎以上です。
少しでもあなたの「なんじゃこりゃ！」を減らすことができたなら嬉しいです。
最後までお読み頂き有難うございました！


# 参考にさせて頂きました！
・[Git](https://git-scm.com/)
・[サル先生のGit入門](https://backlog.com/ja/git-tutorial/)
・[Git超絶まとめ](https://qiita.com/masashi127/items/2e103c3fba9d1b058961#status)  @masashi127さん

有益な情報を有難うございました！