リポジトリのフォークの仕方

##リポジトリのフォーク
**大人数開発におけるリポジトリ管理**
通常、1つのリポジトリを共有して複数人で開発する場合、リポジトリの設定からCollaboratorsを設定して、コミット・プッシュを他のユーザーに許可することになります。人数が少ない内はこの方法で問題ないのですが、もしも数100人、数1000人が関わるプロジェクトになった場合、個別に設定するのは手間になります。
また、全員が1つのリモートリポジトリを参照して開発を行うことを防ぎたいケースも考えられます。「masterブランチを直接編集してプッシュしてしまった」といった事例が発生した際に、自分以外の数1000人の開発者に影響が発生してしまうのは、円滑に開発を行う上で好ましくありません。
全員で1つのリポジトリを共有していると、「ちょっとした変更をmasterブランチにマージして実験的な動作確認を行う」ことも難しくなってしまいます。
上記で挙げた問題は全て、「自身のGithubアカウント上に、共有したいリポジトリのコピーを作成し、そこで好きに作業を行う」ことで解決できます。これを実現するためにGithubにはフォークという機能が備わっています。
###フォーク
フォークとは、自分以外のGithubユーザーが公開しているリポジトリをコピーして、自分のGithub上に新しいリポジトリを作成することを指します。フォークしたリポジトリは、フォーク元のリポジトリからは独立した全く新しいリポジトリになるため、自由にコミットしたりプッシュしたりマージしたりすることができます。
フォークしたリポジトリの最大の特徴は、フォーク元のリポジトリに対してプルリクエストを作成できる点にあります。 フォークを行うことによって、元々のリポジトリ・他の開発者の開発環境を汚染することなく、必要な差分のみを安全にプルリクエストとして取り込むことが可能になります。
###リポジトリをフォーク
今回はGithubが公開している練習用のリポジトリ"Spoon-Knife"というのがあるので、それを使用します。
[練習用のリポジトリ"Spoon-Knife"](https://github.com/octocat/Spoon-Knife)にアクセスします。
①画面右上に表示されている"Fork"ボタンをクリックします。すると、リポジトリのフォークが開始されます。
フォークが完了すると、通常のリポジトリと同様に、ディレクトリ構成とREADMEが表示されます。
②次に、フォークしたリポジトリをローカル環境にクローンします。ターミナルからgit cloneを実行します。
ターミナル

```
$ git clone git@github.com:[Githubのユーザー名]/Spoon-Knife.git
```
※ もし、クローン時に権限のエラーが生じた場合は、以下を実行してください。
【例】ターミナル

```
# 上記コマンドでエラーが生じた場合は以下を実行
$ git clone https://github.com/[Githubのユーザー名]/Spoon-Knife.git
```
③フォークしたリポジトリをクローンできたら、作業用のブランチを作成してファイルを編集します。
今回は練習なので、READMEを書き換えてみます。
エディタでSpoon-Knifeディレクトリ直下のREADME.mdを開きます。
元々書いてある内容を、好きなように修正してみます。
④READMEの修正を行ったら、変更をコミットして、作業ブランチをリモートにプッシュします。
プッシュを行ったら、ブラウザ上でフォークしたリポジトリのURLにアクセスして、「New pull request」ボタンをクリックします。
⑤プルリクエスト作成画面では、マージ先のブランチとマージ元のブランチを選択する必要がありますが、リポジトリをフォークしている場合は、「どのリポジトリからどのリポジトリに対してプルリクエストを作成するか」も選ぶことができます。今回は「フォークしたリポジトリの作業用ブランチ」から「フォーク元のリポジトリのmasterブランチ」に向かってプルリクエストを作成します。
⑥リポジトリとブランチを設定したら、後は通常の場合と同じです。プルリクエストのタイトルを入力し、「Create pull request」ボタンを押すと、プルリクエストが作成されます。
⑦フォーク元のリポジトリにプルリクエストが作成されています。
作成されたプルリクエストは、元々のリポジトリの持ち主か、許可されたユーザーのみマージすることができます。
⑧今回はフォーク元のリポジトリにプルリクエストを作成できるかどうか試すことが目的なので、最後にプルリクエストをcloseします。
##フォーク元の変更をローカルに反映させたい場合
自分のローカルのリポジトリで作業用ブランチを作成する際には、ローカルのリポジトリの状態をフォーク元のリポジトリの最新の状態に合わせたいです。この場合は、フォーク元のリポジトリをリモートリポジトリとして追加することで、git pullなどのコマンドでローカルのリポジトリを最新の状態に追従できるようになります。
※Github Desktopなどのクライアントツールを使っている場合、下記の作業を行わなくてもupstreamがリモートリポジトリとして登録されている可能性があります。
###git remoteコマンド
git remoteコマンドはリモートリポジトリを確認するためのコマンドです。Githubを使ってソースコードを管理している場合、デフォルトではoriginという名前でリモートリポジトリが登録されています。ローカルのmasterブランチをリモートのmasterブランチの状態に追従させる際に実行するgit pull origin masterは、originという名前で登録されているリモートリポジトリのmasterブランチから差分を持ってくるという意味になります。
###git remote addコマンド
git remote addコマンドは、リモートリポジトリを追加するためのコマンドです。ローカルリポジトリは、複数のリポジトリをリモートリポジトリとして登録できます。git remote add <リモートリポジトリの名前> <リモートリポジトリのパス>のようにコマンドを実行することによって、フォーク元のリポジトリからコードをpullできるようになります。
**リモートリポジトリを確認**
ターミナルでローカルのSpoon-Knifeディレクトリに移動し、現時点でのリポートリポジトリを確認してみます。
ターミナル

```
$ git remote
origin
```
originが現在リモートリポジトリとして登録されていることが分かります。git remoteコマンドは、-vオプションをつけて実行すると、登録されているリモートリポジトリのパスを確認できます。
ターミナル

```
$ git remote -v
origin  git@github.com:<自分のユーザー名>/Spoon-Knife.git (fetch)
origin  git@github.com:<自分のユーザー名>/Spoon-Knife.git (push)
```
git@github.com:<ユーザー名>/Spoon-Knife.gitのように、フォークしたリポジトリのパスが表示されたと思います。ここまでのコマンドの実行結果から、自分のGithub上にあるSpoon-Knifeリポジトリを、originという名前でリモートリポジトリとして登録していることが分かります。
###フォーク元のSpoon-Knifeをリモートリポジトリに追加
git remote addコマンドを使って、フォーク元のリポジトリをリモートリポジトリに追加します。慣習として、フォーク元のリポジトリはupstreamという名前で登録されることが多いため、今回もこれに従います。
ターミナル

```
$ git remote add upstream git@github.com:octocat/Spoon-Knife.git
```
もう一度git remote -vコマンドを実行してみます。
ターミナル

```
$ git remote -v
origin  git@github.com:<自分のユーザー名>/Spoon-Knife.git (fetch)
origin  git@github.com:<自分のユーザー名>/Spoon-Knife.git (push)
upstream    git@github.com:octocat/Spoon-Knife.git (fetch)
upstream    git@github.com:octocat/Spoon-Knife.git (push)
```
upstreamという名前でフォーク元のリポジトリへのパスが表示されていたら登録に成功です。
最後に、upstreamからローカルにコードをプルできるかどうか試します。
ターミナル

```
$ git pull upstream master
 * branch            master     -> FETCH_HEAD
Already up to date.
```
フォークしてから元々のリポジトリに特に変更がなければ、"Already up to date" = "既に最新の状態"と表示されます。追加で登録したupstreamと、自分のローカルリポジトリの状態を比べて、差分の検出を試みていることが分かり、正常にリモートを追加できていることが分かります。
###参考サイト
[Forking Projects (Github公式)]
(https://guides.github.com/activities/forking/)
[基本的なGitコマンドまとめ]
(https://qiita.com/2m1tsu3/items/6d49374230afab251337)