Can I specify in .git/config to fetch multiple refspecs?
You can add the following lines in your .git/config
to specify multiple refspecs for fetch:
[remote "origin"]
fetch = refs/heads/my_name/*:refs/remotes/origin/my_name/*
fetch = refs/heads/master:refs/remotes/origin/master
fetch = refs/heads/some_branch:refs/remotes/origin/some_branch
You can add the prefix +
before the refspec, if you would like to override fetching non-fast-forward references as well, like this:
[remote "origin"]
fetch = +refs/heads/my_name/*:refs/remotes/origin/my_name/*
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/some_branch:refs/remotes/origin/some_branch
Note that partial globbing is not supported (i.e. a/b/ca*
is not supported, but a/b/*
is).
10.5 Git Internals - The Refspec
Answering my own complaint about lack of examples for refmap
. Here's an example of checking out a pull request from VSO (Visual Studio Online) without interacting with the config.
$ git fetch --refmap='+refs/pull/*/merge:refs/remotes/origin/pr/*' origin refs/pull/1415/merge
$ git checkout pr/1415
To overwrite the existing fetch refspec(s), without having to manually edit .git/config
, you can use --unset-all
followed by as many --add
as needed.
For the example desired refspecs in the question, it would be:
git config --unset-all remote.origin.fetch
git config --add remote.origin.fetch +refs/heads/my_name/*:refs/remotes/origin/my_name/*
git config --add remote.origin.fetch +refs/heads/master:refs/remotes/origin/master
Then use git config --get-all remote.origin.fetch
to verify the result.
Note: if you want to fetch from a different refspec on a single invocation (overriding temporarily the fetch refspec registered in the config), you can do so since Git 2.1 (August 2014).
See commit c5558f8 by Junio C Hamano (gitster
):
Since the introduction of opportunistic updates of remote-tracking branches, started at around f269048 (
fetch
: opportunistically update tracking refs, 2013-05-11) with a few updates in v1.8.4 era, theremote.*.fetch
configuration always kicks in even when a refspec to specify what to fetch is given on the command line, and there is no way to disable or override it per-invocation.Teach the command to pay attention to the
--refmap=<lhs>:<rhs>
command-line options that can be used to override the use of configuredremote.*.fetch
as the refmap.
That gives you the new option:
--refmap=<refspec>
When fetching refs listed on the command line, use the specified refspec (can be given more than once) to map the refs to remote-tracking branches, instead of the values of
remote.*.fetch
configuration variables for the remote repository.
See section on "Configured Remote-tracking Branches" for details.
(That Git "Configured Remote-tracking Branches" section also dates from Git 2.1: see "Having a hard time understanding git fetch
")
With Git 2.25.1 (Feb. 2020), "git fetch --refmap=" option has got a better documentation.
See commit b40a502 (21 Jan 2020) by Derrick Stolee (derrickstolee
).
(Merged by Junio C Hamano -- gitster
-- in commit 4b69f29, 30 Jan 2020)
fetch
: document and test --refmap=""Signed-off-by: Derrick Stolee
To prevent long blocking time during a '
git fetch
' call, a user may want to set up a schedule for background 'git fetch
' processes.
However, these runs will update the refs/remotes branches due to the default refspec set in the config when Git adds a remote.
Hence the user will not notice when remote refs are updated during their foreground fetches. In fact, they may want those refs to stay put so they can work with the refs from their last foreground fetch call.This can be accomplished by overriding the configured refspec using '
--refmap=
' along with a custom refspec:git fetch --refmap='' <remote> +refs/heads/*:refs/hidden/<remote>/*
to populate a custom ref space and download a pack of the new reachable objects.
This kind of call allows a few things to happen:
- We download a new pack if refs have updated. 2. Since the refs/hidden branches exist, GC will not remove the newly-downloaded data.
- With
fetch.writeCommitGraph
enabled, the refs/hidden refs are used to update the commit-graph file.To avoid the refs/hidden directory from filling without bound, the
--prune
option can be included. When providing a refspec like this, the--prune
option does not delete remote refs and instead only deletes refs in the target refspace.Update the documentation to clarify how '
--refmap=""
' works and create tests to guarantee this behavior remains in the future.
So the git fetch
option man page now includes:
--refmap=<refspec>:
When fetching refs listed on the command line, use the specified refspec (can be given more than once) to map the refs to remote-tracking branches, instead of the values of
remote.*.fetch
configuration variables for the remote repository.Providing an empty
<refspec>
to the--refmap
option causes Git to ignore the configured refspecs and rely entirely on the refspecs supplied as command-line arguments.
See section on "Configured Remote-tracking Branches" for details.
Note that the more aggressive updates to remote-tracking branches we had for the past 7 years or so were not reflected in the documentation, which has been corrected with Git 2.27 (Q2 2020).
See commit a440884, commit f6a65de (05 Apr 2020) by Philippe Blain (phil-blain
).
(Merged by Junio C Hamano -- gitster
-- in commit fdee8b1, 22 Apr 2020)
pull doc
: correct outdated description of an exampleSigned-off-by: Philippe Blain
Since f269048754 ("
fetch
: opportunistically update tracking refs", 2013-05-11, Git v1.8.4-rc0 -- merge listed in batch #0), the underlyinggit fetch
in[
git pull](https://git-scm.com/docs/git-pull) <remote> <branch>
updates the configured remote-tracking branch for .However, an example in the 'Examples' section of the
git pull
documentation still states that this is not the case.Correct the description of this example.
So instead of, for git pull origin next
:
This leaves a copy of
next
temporarily in FETCH_HEAD, but does not update any remote-tracking branches.
Using remote-tracking branches, the same can be done by invoking fetch and merge:
You now have:
This leaves a copy of
next
temporarily in FETCH_HEAD, and updates the remote-tracking branchorigin/next
.
The same can be done by invoking fetch and merge: