サル以下の存在がまとめた「Git用語」図解

#はじめに
どうも、「[サルでも分かるGit入門](https://www.backlog.jp/git-guide/)」が分からなかった、サル以下の存在です。

正確には、各ページの言わんとしていることは分かるし、言われた通り操作もできる。
だけど、各操作が具体的に、何を対象にしているのかが分からない。。。

初めての人に教える機会もあるので、ついでにまとめてみました。

#基本操作
![image.png](https://raw.githubusercontent.com/nh321/material/master/git/gitterm.png)
※寒色：頻度の少ない操作（比較的）
※暖色：頻度の多い操作

|操作|説明|
|:---|:---|
|fork|**リモート上**での**リポジトリ**のコピー <br>fork時点の資源/ブランチ構成がコピーされる。fork以前の履歴情報はコピーされない。|
|clone|**ローカルへ**の**ブランチ**のコピー（ブランチは指定する）<br>「clone元となるリモートリポジトリおよびリモートブランチ」と「cloneしたものを格納するローカルディレクトリ（≒working-tree）」を指定する。|
|merge|後で補足します。|
|fetch|リモートブランチの状態を、リモート追跡ブランチに反映する。<br>マージはしないので、差分チェックしたい時は、いきなりpullするよりは、一度fetchした方が良い。<br>fetchを自動で行ってくれるツールもある（SourceTreeなど）。|
|pull|fetch + merge。リモートブランチの内容を差分を確認せずに一気にmergeしたい時に行う。|
|add/stage|修正したファイルをcommit対象にする場合、この操作をする。<br>この操作がされていないファイルは、commitされない。<br>なお、add/stageした後に、同一ファイルに対して変更を加えても、その変更はcommitされない。|
|commit|add/stageされた物を対象として、ローカルブランチに変更を反映する。|
|push|ローカルブランチの内容をリモートブランチに反映する。|
|stash(stash save)|indexとworking-treeにある変更をstashという領域に退避する。<br>この操作を行うと、indexとworking-treeは、local-branchと同じ状態（変更を加える前の状態）になる。<br>stash操作をしたタイミング毎に保持される。（過去退避したものが上書きされたり、過去分にマージされたりはしない。）<br>stashの後のsaveは省略できるらしい。<br>なお「ファイルの追加」に関しては、working-treeからの直接stashできず、一度add/stageしてindexにある状態だとstashできる。（「ファイルの削除」はstashできた。）|
|stash apply|指定した退避状態を、working-treeに反映させる。<br>競合が発生していると失敗するので、stashはあまり溜めすぎないようにしたい。<br>「ファイルの追加」に関してだけは、working-treeだけじゃなく、indexにも反映される。|

|英語|日本語|説明|
|:---|:---|:---|
|remote-repository|リモートリポジトリ|サーバにあるリポジトリ。<br>githubだと「Create new file」などで直接変更することもできるが、基本的に直接操作しない類のもの。|
|local-repository|ローカルリポジトリ|PCにcloneして来たリポジトリ。基本的に直接操作するのはココ。|
|remote-branch|リモートブランチ|サーバにあるブランチ。「リポジトリじゃなくて、ブランチやで！」って伝えたい時に主に使われる。|
|local-branch|ローカルブランチ|図示されている通り。|
|index|インデックス|ココに入れた時点のファイル状態がコミット対象になる。|
|working-tree / working-copy|作業コピー / ワーキングツリー など|実際のディレクトリに格納されているファイル。cloneする際に指定したディレクトリを指す。|
|stash|スタッシュ|一時退避したものが格納されている領域。|

#自分が正しく理解できていなかったこと
##ブランチとは
「この線がブランチなのだな」と理解していたのが、適切じゃなかった。
概念的には「線」に近いのだが、実際の挙動としては「点（コミット）」が中心に据えられている。		

**概念としてのブランチ**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/ac89c9c2-55cd-85e7-fabb-a4aa6325f673.png)

**実際のブランチが指し示しているもの**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/ac5548c9-2da2-c1cb-edd6-98af2a70df28.png)
ここらへんは下のマージについての説明で補足します。

###マージ操作におけるブランチ
merge操作についてもここで合わせて説明します。

**概念としてのマージ**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/b4dbef74-7afa-c217-1130-5f1ae333d743.png)

**実際のマージ**
以下の図では、developブランチを起点(checkoutした状態)として、merge対象にfeatureを指定しています。コマンドライクに言うなら`git merge feature`。
developブランチで`git merge feature`を実行したときに行われる操作は、**「developとfeatureの2つを親としたマージコミットが作成され、それが新たなdevelopになる」**というもの[^1]。
featureブランチが指すコミットは変化しない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214587/5f491edd-b090-9c04-adbf-a2623d716f75.png)

[^1]: [コメント](https://qiita.com/nh321/items/6517b0964c6ed1685ecf#comment-e3b775f711fc020dffd6)でご指摘いただいた表現を使わせていただいております。ありがとうございます！

###ブランチとタグの違い
似たような概念で、「タグ」がいますが、以下のような違いがあります。

- タグは静止点なので、他にcommit/mergeがどれだけ発生しても、指し示すcommitは変動しない。
- ブランチは、概念としては「線」の扱いなので、commit/merge等で指し示すcommitが変動する。
    - 該当のブランチであると認識される「最新のcommit」を常に指し示す。

#最後に
色々調べたつもりですが、間違ってたら教えてください・・・

なお、[弊社のアドベントカレンダー](https://qiita.com/advent-calendar/2017/tis)は、こんなサル以下な記事とは違って、良記事ばっかりなので、ぜひ見てみて下さい。

こんな記事あげて大丈夫かな・・・と小一時間悩みましたが、「へーきへーき！フレンズによって得意な事違うから！」の精神で頑張ります。
きっと、これでハードルが下がるはず・・・あとは頼みましたよ、承太郎・・・

#参考資料

**基本的な知識**

- A successful Git branching model：[英語](http://nvie.com/posts/a-successful-git-branching-model/) / [日本語翻訳](http://keijinsonyaban.blogspot.jp/2010/10/a-successful-git-branching-model.html)　： Git使うなら必ずと言って良いほど話題に上がるもの

**初学者向け情報**

- [サルでもわかるGit入門](https://www.backlog.jp/git-guide/)：何かあったらとりあえず分からなくなったらここを参照してます。ありがたい！
- [マンガで分かるGit](https://codeiq.jp/magazine/category/git-ai/)：取っ付きやすさNo.1。
- [[新人教育] 何も知らない人がGitとGitHubを独学で知る](https://qiita.com/ikenji/items/367e8344490dd37e14f0)：Git学習ツール[git-it-electron](https://github.com/jlord/git-it-electron#user-content-git-it-desktop-version)の説明
- [Git、GitHubを教える時に使いたい資料まとめ](https://qiita.com/yuyakato/items/41751848add5dfd5289c)：まとめ記事でござい

**もう少し詳しく理解したい人向け**

- [Gitのリポジトリの中身をなるべく正確に理解する](https://www.kaitoy.xyz/2015/12/27/git-repository/)：実際にブランチが示すコミットがどう変わっていくのかとか、すごく分かりやすい！
- [Gitのマージを図解する](https://www.kaitoy.xyz/2015/12/28/git-merge/)：真のマージ、リベース、ファストフォワードマージ、チェリーピックを図示していただいてます。
- [ステージを理解して git をもっと便利に使う](http://daretoku-unix.blogspot.jp/2009/08/git.html)：add/stage/indexについてのもう少し詳しい説明。
- [[Git]変更を一時的に退避するgit stashの使い方イロハ](https://qiita.com/kashira2339/items/34281fee571c39471e48)：stashについてのもう少し詳しい説明。
 
**ここで説明しきれなかった操作**

- resetについて
    - [git reset についてもまとめてみる](http://d.hatena.ne.jp/murank/20110327/1301224770)：図表があって嬉しい
- rebaseについて
    - [初心者でもわかる！リベースの使い方を解説します](https://liginc.co.jp/web/tool/79390)：グラフィカルで分かりやすい
    - [git rebase についてまとめてみた](https://qiita.com/KTakata/items/d33185fc0457c08654a5)：オプションが詳しく書かれている
- checkout
    - [git checkoutを図解する](https://www.kaitoy.xyz/2016/10/08/git-checkout/)：なんて丁寧な図解！

---

追記
2017/12/27 簡易説明用に使う記事をまとめました → [Gitについて説明する時に使う資料](https://qiita.com/nh321/items/5f169054c1fe5e6ba884)

---