リモートリポジトリとかリモートブランチ周りがイマイチ理解しきれていない気がするので調べた範囲でまとめてみる。
リモートリポジトリの登録
リモートリポジトリを指定する際、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
をすると、リモート追跡ブランチを経由してローカルブランチにマージされる。 - 上流ブランチが通常リモート追跡ブランチを指すのかリモートブランチを指すのかはわからなかった。
参考