In git, how do I check out a remote repository's remote branches?
I have a local repository cloned from a bare remote repository. The following command lists al the remote repository's branches.
$ git ls-remote <remote>
74bd3eb190edb39db04f6c0c4dbbb9e1e96bc6db refs/remotes/test
85de54d6ae813c624b9623983e6b0a4948dae0fe refs/remotes/trunk
I want to checkout and track that remote's remot开发者_开发百科e branch trunk. How do I do that?
Note that this is different from checking out a remote repository's local branch. This is how the remote repository looks like.
$ git branch -a
master
remotes/test
remotes/trunk
After running git fetch < remote > to fetch all of the remote repository's branches, I get this output in the local repository.
$ git branch -r
repo/HEAD -> repo/master
repo/master
You can fetch any ref from any remote (as long as the server is willing to give it to you). The key to fetching refs outside refs/heads/
is to supply full ref paths that start with refs/
. If desired, you can even pull from repositories that are not configured as remotes (git fetch can take a URL instead of a remote name).
By default, configured remotes will only fetch from the remote repository’s refs/heads/
namespace, so they will not pick up anything inside refs/remotes/
. But, you could refer to a ref inside it by using a complete ref like refs/remotes/trunk
(remotes/trunk
might also work, but might also be ambiguous).
If the fetched refspec does not specify a destination ref, it will be stored in the special FETCH_HEAD ref.
Fetch a repository’s refs/remote/trunk
into FETCH_HEAD and check it out as a detached HEAD:
git fetch remote-name-or-url refs/remotes/trunk &&
git checkout FETCH_HEAD
Same, but create a named, local branch instead of using a detached HEAD:
git fetch remote-name-or-url refs/remotes/trunk &&
git checkout -b trunk-from-remote FETCH_HEAD
Same, but directly into a local branch:
git fetch remote-name-or-url refs/remotes/trunk:trunk-from-remote &&
git checkout trunk-from-remote
If you are working with a configured remote, you can rewrite its remote.<remote-name>.fetch
configuration and add an extra entry to automate fetching from both refs/heads/
and refs/remotes/
.
# fetch branchs of remote into remote-name/heads/*
git config remote.remote-name.fetch '+refs/heads/*:refs/remotes/remote-name/heads/*' &&
# fetch remotes of remote into remote-name/remotes/*
git config --add remote.remote-name.fetch '+refs/remotes/*:refs/remotes/remote-name/remotes/*'
To avoid possible collisions, the above example configures fetch to store refs into disjoint namespaces (…/heads/
and …/remotes/
). You can pick different names if you like. If you are sure there will be no conflicts, you can even stuff them both directly under refs/remotes/remote-name/
.
Good question! I know that this works; can't think of anything else that does off the top of my head:
git fetch origin refs/remotes/trunk
git checkout FETCH_HEAD
# or make a branch to check out
git checkout -b remote-trunk FETCH_HEAD
It's odd, by the way, that those remote refs aren't of the form refs/remotes/<remote-name>/<branch-name>
... maybe I misunderstood the names, but the method does work.
Actually, I've found a satisfying solution to this. Adding a remote sets up a refspec to fetch and pull its local heads. I set up another remote which I call /repo-remotes/ which fetch the remote's remote refs. The .git/config file ends up looking like this
[remote "repo"]
url = ssh://git@<hostname>:<port>/repo
fetch = +refs/heads/*:refs/remotes/repo/*
[remote "repo-remotes"]
url = ssh://git@<hostname>:<port>/repo
fetch = +refs/remotes/*:refs/remotes/repo-remotes/*
I can then do this.
$ git fetch repo-remotes
$ git checkout -b remote-trunk --track remotes/repo-remotes/trunk
Which sets up a local branch tracking the remote repository's remote branch /trunk/.
git.exe checkout --track -b trunk refs/remotes/trunk
精彩评论