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/
.
Best Answer
The answer has been split depending on whether there is one remote repository configured or multiple. The reason for this is that for the single remote case, some of the commands can be simplified as there is less ambiguity.
Updated for Git 2.23: For older versions, see the section at the end.
With One Remote
In both cases, start by fetching from the remote repository to make sure you have all the latest changes downloaded.
This will fetch all of the remote branches for you. You can see the branches available for checkout with:
The branches that start with
remotes/*
can be thought of as read only copies of the remote branches. To work on a branch you need to create a local branch from it. This is done with the Git commandswitch
(since Git 2.23) by giving it the name of the remote branch (minus the remote name):In this case Git is guessing (can be disabled with
--no-guess
) that you are trying to checkout and track the remote branch with the same name.With Multiple Remotes
In the case where multiple remote repositories exist, the remote repository needs to be explicitly named.
As before, start by fetching the latest remote changes:
This will fetch all of the remote branches for you. You can see the branches available for checkout with:
With the remote branches in hand, you now need to check out the branch you are interested in with
-c
to create a new local branch:For more information about using
git switch
:Prior to Git 2.23
git switch
was added in Git 2.23, prior to thisgit checkout
was used to switch branches.To checkout out with only a single remote repository:
if there are multiple remote repositories configured then it becomes a bit longer