Gitのリモートブランチとかリモートリポジトリとかをまとめる

リモートリポジトリとかリモートブランチ周りがイマイチ理解しきれていない気がするので調べた範囲でまとめてみる。

## リモートリポジトリの登録
リモートリポジトリを指定する際、URLをいちいち指定するのは面倒なのでリモートリポジトリに任意の名前をつけて登録することができ、リモートリポジトリの指定の際にその名前を使うことができる。

リモートリポジトリの登録は`git remote add <RemoteName> <RepositoryURL>`で行い、
現在登録されているリモートリポジトリは`git remote -v`で確認できる。
```
//originという名前でリモートリポジトリを登録
> git remote add origin git@github.com:user/TestRepository.git

//登録されているリモートリポジトリの確認
> git remote -v
origin  git@github.com:user/TestRepository.git (fetch)
origin  git@github.com:user/TestRepository.git (push)
```
リモートリポジトリを`clone`した際は、自動的に`origin`という名前でリモートリポジトリが登録される。


## 3種類のブランチ
### リモートブランチ
リモートリポジトリに存在するブランチ。

### リモート追跡ブランチ
**ローカルに存在するブランチ。**
最後にリモートブランチに接続した際のリモートブランチの状態を保持するブランチ。
`git fetch`した際にリモートブランチの状態を取得し、最新化される。
`.git/refs/remotes/`以下に保持される。
ブランチ名は`(remote)/(branch)`のように表される。(例: `origin/master`)

### ローカルブランチ
ローカルリポジトリに存在するブランチ。
ブランチ名は`(branch)`のように表される。（例: `master`）

## `git fetch`、`git merge`がなにをしているのか

### git fetch
リモートブランチから差分となるコミットを取得し、リモート追跡ブランチに反映する。
ローカルブランチには反映されない。
>Fetch branches and/or tags (collectively, "refs") from one or more other repositories, along with the objects necessary to complete their histories. Remote-tracking branches are updated

公式ドキュメントにもリモート追跡ブランチを更新すると書いてある。

> When git fetch is run without specifying what branches and/or tags to fetch on the command line, e.g. git fetch origin or git fetch, remote.\<repository\>.fetch values are used as the refspecs—​they specify which refs to fetch and which local refs to update

fetchは`remote.<repository>.url`で指定されているURLから、`remote.<repository>.fetch`の指定に従ってどこからどこへfetchするかを決定する。
```
remote.origin.url=git@github.com:user/TestRepository.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
```
`refs/remotes/origin/`はローカルのリモート追跡ブランチ。

### git merge
リモート追跡ブランチの状態をローカルブランチに反映させる。
> If no commit is given from the command line, merge the remote-tracking branches that the current branch is configured to use as its upstream

正確には、「上流ブランチとして設定されているブランチの内容をローカルブランチに反映させる」みたい。

## わからないところ

**ローカルブランチの上流ブランチは通常、リモート追跡ブランチを指すのか、リモートブランチを指すのか。**

公式ドキュメントの用語集には下記の通り記載されている。
>**upstream branch**
The default branch that is merged into the branch in question (or the branch in question is rebased onto). It is configured via branch.\<name\>.remote and branch.\<name\>.merge. If the upstream branch of A is origin/B sometimes we say "A is tracking origin/B".

引数なしで`git merge`した際のマージ対象との認識で、これを読む限りでは、「ローカルブランチの上流ブランチ=リモート追跡ブランチ」であるように読み取れる。
`git merge`の公式ドキュメントの引用部分を見てもそのように読み取れる。

しかしながら、`git config`の値を見る限り、`branch.main.merge`の値は以下のようになっている。
```
branch.main.remote=origin
branch.main.merge=refs/heads/main
```
`git merge`した際のマージ対象が`branch.main.merge`になる認識だが、この設定値を見る限りではリモートブランチを指しているように見える。
リモート追跡ブランチを指すのであれば、`refs/remotes/origin/main`になるのではないか？

多分前者なのかな、と思っているが、両方の説があって色々調べているうちにわからなくなってしまった。

## まとめ
- リモートリポジトリは参照しやすいように名前をつけることができる。デフォルトは`origin`。
- リモート追跡ブランチはローカルに存在し、リモートブランチに最後に接続した際の状態を保持する。
- `fetch`と`merge`をすると、リモート追跡ブランチを経由してローカルブランチにマージされる。
- 上流ブランチが通常リモート追跡ブランチを指すのかリモートブランチを指すのかはわからなかった。

## 参考
https://git-scm.com/docs/git-branch

https://ama-tech.hatenablog.com/remote-tracking-branch-and-upstream-branch

https://qiita.com/uasi/items/69368c17c79e99aaddbf

https://qiita.com/tatsuya_1995/items/4b8871709d3efe688400

https://www-creators.com/archives/4931

https://qiita.com/noritada/items/f73c8cf1846b16a37dba

https://stackoverflow.com/questions/54188133/does-branch-name-merge-represent-a-remote-tracking-branch-or-an-upstream-bra