Git/GitHubを独習してきたので、ここらで「正常系」についてまとめようとおもった。

### 背景とねらい

Git/GitHubを（いまさらながら）独習してきて、理解を進めるために、「正常系」についてまとめようとおもった。

正常系については[「システム設計の法則（正常系と異常系についての一般論）」](https://qiita.com/hann-solo/items/8037752ac8c3833d7b56)にて。

- Git/GitHubの「正常系」を整理
- OSS開発の「作法」で「わからないところ」を特定

ができればとおもう。

### Git/GitHubの基本ユニット

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/339da16c-a480-9703-d792-59119d3913f4.jpeg" width=80%>

全体を通じて、Git/GitHubの構成は、この基本ユニットが念頭にあるとおもわれる。「**ようするにぜんぶ、コレの応用／組み合わせだ！！**」と念じれば、頭がスッキリする（とおもう）。

以下、簡略化のために「→」の「commit」は省略する。


### localのみで運用する場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/1fa1de06-8f01-c53f-6fa1-d2eea4f29c7c.jpeg" width=80%>

もっとも単純な、localのみで運用する場合は、こうなる。ローカルのみで運用するメリットは少ないので、実際にこれだけで使うことはないだろうけれど。


### remoteとlocalで運用する場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/f6879386-7348-fbc0-a5fd-c655077569c9.jpeg" width=80%>

remoteとlocalで運用する場合も、図にすると同じかたちをしている。

慣習として、remoteは`origin`と名付けられる。remoteからlocalに`clone`したとき、特に指定しなければ`origin`と呼ばれることになる。

初回のクローンは
`$ git clone git@github.com:boo/foo.git`

２回目以降のプルは
`$ git pull origin master`

編集後にプッシュするのは
`$ git push -u origin master`としておくと次回から
`$ git push`で済むようになる。


### remoteとlocalで運用し、ブランチがある場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/fe110134-2d60-59c5-5f46-3ad70d100b56.jpeg" width=80%>

localでbranchを作成する場合は、これまでの2階層が3階層になるだけで、かたちは同じである。

branch作成は

```
$ git checkout master
```

としてmasterに移動したのち、

```
$ git branch <branch name> // branchを作成
$ git checkout <branch name> // branchに移動
```
もしくはこのふたつをあわせて行うコマンド、

```
$ git checkout -b <branch name> // branchを作成し、そこに移動
```

上図には示していないが、remote(`origin`)にブランチをプッシュするのは
`$ git push -u origin <branch name>`

- !? このとき、remote(`origin`)でも、`master`ではなく、<branch name>に分岐し、そこに`push`されるということでいいのかな？　⇒　Yes、そのとおり。branchを`push`して、`origin/master`に入ってしまうことはない。

- 図も、remote(`master`/`branch`) - local(`master`/`branch`)としたほうが議論の見通しがいいのかもしれない。今後の修正余地ということで。


### OSS開発の場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/301abda7-72ba-7fa8-2d98-4417d82f387e.jpeg" width=100%>

OSS(open source software)開発では、下記手順が推奨されている。

1. 開発元のリポジトリから、自分のremoteリポジトリに`fork`（GitHub to GitHub）
- 自分のremoteリポジトリをlocalに`clone`（GitHub to myPC）
- localのcloneから修正branchを作成し、そこで修正
- localの修正branchから自分のremoteのbranchに`push`（myPC to GitHub）
- 自分のremoteのbranchから開発元のリポジトリに`pull request`（GitHub to GitHub）
- 開発元のリポジトリで`merge`される

実戦上は、プルリク後の修正どうするか、コンフリクトどうするか、開発元でコミットが進んだものをどう取り込むか、などいろいろあるが、正常系に絞ると上記の通り。

upstream（開発元をこう名付けることが多い様子） - remote - localの３階層、それぞれにブランチがあるので６階層（upstreamのブランチを無視するとして５階層）になるが、あくまでも基本形の組み合わせにすぎない。

コマンド的にも、新規コマンドはない。「プルリクエストを送るとき、GitHub上で行う」が、これまでになかった追加操作。


### OSS開発でわからないこと

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/328d45b0-9596-a704-72a1-e9cd48c449a6.jpeg" width=100%>

<details><summary>
１回目のプルリクまでは載っているのだけれど、プルリクが通ったあとどうすればいいか（２回目はどうすればいいか）、あまり見つけられないんだなあ（探し方が悪いのだとおもうけど）。図のふたつの青い`｛`がわからなくて。</summary><div>


１）プルリクが通ったあと

- localでは修正branchを、masterに`merge`するのでいいのか？
- remoteでも修正branchを、masterに`merge`するのでいいのか？

　⇒　これらは行わず、次の２）にいけばいいのだろうか？

２）つづいて次のバージョンの修正を行う場合は

- upstreamからlocalに`pull`し、localからremoteに`push`する、でいいのか？

これでよければ、１回目と同じプロセスに入るので、問題はないのかなとおもう。まさか、もういちど`fork`からせよ、とは言わないだろうし……。

</div></details>


### 理解がすすんだこと

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/0efa6868-5b13-6ce2-1f15-dc1847fa8ee2.jpeg" width=100%>

上で「わからない」と書いたこと、わかった（気がする）。よりシンプルなので、正しいはず。

- `｝A`のところでは、**なにもしなくていい！**
- `｝B`のときには、upstreamからlocalに`pull`、localからremote（GitHub）に`push`。

スッキリ！

### 参考サイト

【試行】GitHubでforkしたり、Issueドリブンやってみる
https://qiita.com/sky0621/items/9811e874edd507a068a4
　⇒　ひと手順ずつ、コマンドと結果がのっていて、たいへん助かる！
　　　`fetch`〜`rebase`〜`squash`あたりも細かく載っている！


Github で Fork してから Pull Request をするまでの流れ
http://kik.xii.jp/archives/179
　⇒　こちらも、図式化されていて、コマンドも丁寧に書いてくださっているので助かる！
　　　`pull`〜`rebase`あたりも細かく（`squash`はない）