开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜