Githubを理解しよう！①

今回は、Github学習したので、アウトプットしていきます
※以下の内容は、学習内容のアウトプット用のため、誤りがある場合があります。予めご了承ください

#Githubとは
***Githubは友人、同僚、クラスメイト、見知らぬ人とコードを共有するための場所えお提供しているサービスのことです***

#基礎知識を確認しよう！

<h3>●gitとは？</h3>
主に、プログラムのソースコードを管理するためのシステムです。gitをうまく使うと、バーション管理や、バクの発見、複数の作業を並行して行なうことができます。

<h3>●リポジトリとは？</h3>
ソースコードを管理する単位です。プロジェクトごとに対応するリポジトリが作られます。リポジトリは、基本的に無料で何個も作成できます。

<h3>●stageとは？</h3>
Git では、コミットの前に、「作業ディレクトリ内のこのファイルの内容はリポジトリに反映してほしいけど、このファイルの内容は反映してほしくない」みたいなことを Git に教えておく必要があります。このとき、「次にコミットするときにリポジトリに反映される内容の置き場」のことを、***staging area***　と呼んでいます。

つまり、staging area に上げられたことを***「stage する」***と言います。この状態で commit を行うと、Git は stage に上がっている内容をリポジトリに登録します。

ちなみに、staging areaにあげるコマンドが　git addを使用します。
後ほど、説明します

<h3>●branchとは？</h3>
分岐や再現を利用して、別々の作業を並行して行なうために利用します。

<h4>イメージ図</h4>
![スクリーンショット 2020-10-22 16.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/770482/2a73face-c8e2-1600-193e-72427529f13f.png)


#基礎コマンドを覚えよう！
***開発環境：ターミナル***


<h3>●空のリポジトリを作成し、初期化をする</h3>

```swift:qiita.rbvar 

$ mkdir 自分でファイル名を決める //新しいファイルを作成　
$ cd ファイル名 //作成したファイルに移動する
$ git init //リポジトリの初期化
```
<h3>●ファイルの一覧を確認する</h3>

```swift:qiita.rbvar 
$ ls -a
```

<h3>●現在のリポジトリと作業コピーの状態の確認</h3>
```swift:qiita.rbvar 
$ git status
```
<h3>●staging areaにセットする</h3>
```swift:qiita.rbvar 
$ git add
```
git add コマンドは、リポジトリで作業した内容を記録するために、この変更内容を記録するよと、Githubに教えてあげる作業になります。
これをやることによって、Aの作業はGitHubに登録して記録しておきたいけど、 まだ、B作業は記録したくない時に、A作業だけ、git add でセットして、記録することができます。

```swift:qiita.rbvar 
$ git add .
```
また。git add .コマンドを使うことで、「その中身のファイルを全部」と指定してすることができます。
staging areaにセットする作業が複数ある場合に、使うことができ、***非常に便利です。***(Aの作業と、B作業を同時にセットしたい)

<h3>●staging areaから削除する</h3>

```swift:qiita.rbvar 
$ git rm --cached [ファイル名]
```

staging areaにセットするコマンドがあるなら、staging areaから削除するコマンドもあります。

<h3>●リポジトリの作業を記録する</h3>
```swift:qiita.rbvar 
$ git commit
```
git add でセットされた内容を記録します。この記録を元にファイルを復元したりすることが可能になります。

<h3>●直前のコミットを上書きする</h3>
<h4>作業した状態のファイルを、git add し、以下のコマンドを実行します。</h4>

```swift:qiita.rbvar
$ git commit --amend
```

<h3>●履歴をみる</h3>
```swift:qiita.rbvar 
$ git log
```
「何を」「誰が」「どんな作業したのか」の履歴を見ることができます。

<h3>●ブランチを視覚的に見る</h3>


```swift:qiita.rbvar 
$ git log --graph
```
--graph というオプションをつけて実行すると、コミットの親子関係を視覚化することもできます。

わかりにくいと思うので簡単な例をご紹介します。

```swift:qiita.rbvar 
* commit 
| Author: Shunta-Ymasaki <Yamasakim@gmail.com>
| Date:   Sat May 4 03:20:59 2020 +0900
| 
|    チンパンジーファイルの中に、ゴリラファイルを追加
|  
* commit 
  Author: Shunta-Ymasaki <Yamasakim@gmail.com>
  Date:   Fri May 3 22:32:52 2020 +0900

      チンパンジーファイルを追加
```

このように、作業のgit log --graphコマンドを使うことによって、作業の分岐を確認することができます。

<h3>●ファイルの削除する</h3>

```swift:qiita.rbvar 
$ git rm ファイル名
```

これも簡単な例を見ていきましょう。
今回もこちらの例を使います。

```swift:qiita.rbvar 
$ git log --graph
* commit 
| Author: Shunta-Ymasaki <Yamasakim@gmail.com>
| Date:   Sat May 4 03:20:59 2020 +0900
| 
|    チンパンジーファイルの中に、ゴリラファイルを追加　
|  
* commit 
  Author: Shunta-Ymasaki <Yamasakim@gmail.com>
  Date:   Fri May 3 22:32:52 2020 +0900

      チンパンジーファイルを追加
```

***チンパンジーファイルの中に、ゴリラファイルを追加をしたのに、「やっぱりいらないとなって、ゴリラファイルを削除しました」***

```swift:qiita.rbvar 
$ git log --graph
* commit 
| Author: Shunta-Ymasaki <Yamasakim@gmail.com>
| Date:   Sat May 4 03:20:59 2020 +0900
| 
|    チンパンジーファイルの中に、ゴリラファイルを追加 //追加したゴリラファイルを削除した
|  
* commit 
  Author: Shunta-Ymasaki <Yamasakim@gmail.com>
  Date:   Fri May 3 22:32:52 2020 +0900

      チンパンジーファイルを追加
```


さて、これで、作業ディレクトリ内には、「ゴリラファイルが削除された」という変化がおこりました。
この変更をstageするためにgit addをすればいいと思いがちなんですが、
<h4>実は、ファイルの削除という変更を stage するためには、git add ではなく、git rm を使わないといけません！</h4>

また、git rmコマンドを使うと、手動でファイルを削除する必要がないです。

この作業をリセットすることもできます。

<h3>●not staged 状態にする</h3>


```swift:qiita.rbvar 
$ git reset HEAD 削除したファイル名
```

<h3>●削除したファイルを復活させる</h3>

```swift:qiita.rbvar 
$ git checkout -- 削除したファイル名
```
<h3>●ファイル名を変更する</h3>
```swift:qiita.rbvar 
$ git mv  ＜リネーム前のファイルの名前＞ ＜リネーム後のファイルの名前＞
```
<h3>●新しいファイルを作って、そこに既存のファイルを移動させる</h3>

```swift:qiita.rbvar 
$ mkdir animals //新しいファイルを作成
$ git mv 既存のファイル名 animals/既存のファイル名
$ git mv 既存のファイル名 animals/既存のファイル名
```

#branchを理解しよう！
<h3>●ブランチを表示する</h3>
```swift:qiita.rbvar 
$ git branch
```
<h3>●ブランチを作成する</h3>
```swift:qiita.rbvar 
$ git branch ブランチ名
```
<h3>●ブランチを切り替える</h3>

```swift:qiita.rbvar 
$ git checkout 切り替えるブランチ名
```

<h3>●ブランチを作成して、切り替える</h3>

```swift:qiita.rbvar 
$ git checkout -b ブランチ名
```

簡単な例を見てみましょう

```swift:qiita.rbvar 
$ git graph
* bab8d49  (HEAD, A_branch) 2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
| * c3ef974  (master) 2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加
|/
* 5fe17c7  2020-010-22 Shunta-Ymasaki 動物ファイルを作成
```
上記の例では、masterブランチの分岐として、A_branchが存在しています。

<h3>●分岐元を指定して、ブランチを作成し切り替える</h3>

```swift:qiita.rbvar
git branch -b ＜新しく作るブランチの名前＞ ＜分岐元＞
```
上記のコマンドにすることで、分岐元を指定することができます。

#マージを理解しよう！
merge というのは***「複数のコミットを」***一緒にするということです。

例として、 branchAをマージしてみます。

```swift:qiita.rbvar 
$ git merge branchA
```

```swift:qiita.rbvar 
$ git graph                 //mergeしたことよって分岐していたものが一つになる
*   e175c44  (HEAD, master) 2020-010-22 Shunta Shunta Merge branch 'branchA'
|\  
| * bab8d49  (branchA) 2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
* | 5fe17c7  2020-010-22 Shunta-Ymasaki 動物ファイルにチンパンジーファイルを追加
|/
* ６fe17c7  2020-010-22 Shunta-Ymasaki 動物ファイルを作成
```

<h3>●ブランチを削除する</h3>
mergeしたbranchAは不要なので、削除します。

```swift:qiita.rbvar 
$ git branch -d branchA
```

```swift:qiita.rbvar 
$ git graph                 
*   e175c44  (HEAD, master) 2020-010-22 Shunta Shunta Merge branch 'branchA'
|\           /
| * bab8d49  2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加 //branchAの項目は削除される
* | 5fe17c7  2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加
|/
* ６fe17c7  2020-010-22 Shunta-Ymasaki 動物ファイルを作成
```
git branch -d branchAを削除する先ほどのgit graphの項目からbranchAを削除することができます。


<h3>●Fast-forwardにならないmerge</h3>

Fast-forwardは説明が難しいので、こちらも簡単な例を見ていきましょう。
まず、branchA、branchBを作成して、「branchAは動物ファイルにチンパンジーファイルを追加」、「branchBは動物ファイル名にゴリラファイルを追加」という作業をし、コミットします。さらに、branchBだけmergeした想定で行います。


<h4>Fast-forwardを使用とすると以下のgraphになります</h4>

```swift:qiita.rbvar 
$ git graph 
* 5f26eb2  (HEAD, master, branchB) 2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
| * ff00bb6  (branchA) 2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加
|/  
* 8efecbd  (master) 2020-010-22 Shunta-Ymasaki 動物ファイルを作成
```

一見、シンプルに見えるgraphですが、これでは、直感的にmergeした履歴がわかりにくいです。

そこで登場するのが、このコマンドです。

```swift:qiita.rbvar
$ git merge --no-ff branchB
```
このコマンドを使用することで、Fast-forwardを使用せずに、mergeを行います。
そうすると、以下のようなgraphになります。

```swift:qiita.rbvar
$ git graph 
*   7090c03  (HEAD, master) 2020-010-22 Shunta  Merge branch 'branchB'
|\  
| * 5f26eb2  (branchB) 2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
|/  
| * ff00bb6  (branchA) 2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加
|/  
* 8efecbd  2020-10-22 Shunta-Ymasaki 動物ファイルを作成
```
このようにMergeした記録も分岐して残リます。

<h3>●過去改変をする</h3>

```swift:qiita.rbvar
$ git checkout branchA
$ git rebase master
```
git rebase を行なうことで、過去の改変を行なうことができます。
簡単な例を見ていきましょう

```swift:qiita.rbvar
$ git graph 
*   7090c03  (HEAD, master) 2020-010-22 Shunta  Merge branch 'branchB'
|\  
| * 5f26eb2  2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
|/  
| * ff00bb6  (branchA) 2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加
|/  
* 8efecbd  2020-10-22 Shunta-Ymasaki 動物ファイルを作成
```

前提条件として、branchBはmergeしてgit branch -dコマンドを実行をしています。
この状態からbranchAに戻って作業する時に、branchBの作業内容を反映させられたら便利ですよね。
それを可能にしてくれるのが、git rebaseコマンドです。

git rebaseコマンドを実行すると以下の通りになります。

```swift:qiita.rbvar
$ git graph 
* 03f91be  (HEAD, branchA) 2020-010-22 Shunta 動物ファイルにチンパンジーファイルを追加 //branchBの要素を持ったbranchA
* 87fe5eb  (master) 2020-010-22 Shunta  Merge branch 'branchB'
|\  
| * 0bd5673  5f26eb2  2020-010-22 Shunta 動物ファイル名にゴリラファイルを追加
|/  
* 3b9ccc5  2020-10-22 Shunta-Ymasaki 動物ファイルを作成
```

#最後に
今回は、基礎知識と基礎コマンドのについてまとめてみました。
GitHubは色々なコマンドがあるので、混乱してしまいますが、焦らず少しづつ使いこなせるようにしていきます。

次回は、複数人でGitHubを使う時に、用いるコマンドについてまとめていきます！

参考文献
[Git をはじめからていねいに]　https://github.com/takanabe/introduction-to-git

かなりわかりやすくて、お勧めです！！