38

我不想从原点获取每个分支,因为有很多。我只想跟踪一些(例如,master)和我的分支(在my_name子目录下组织)。我可以执行以下操作:

$ git fetch origin refs/heads/my_name/*:refs/remotes/origin/my_name/* refs/heads/master:refs/remotes/origin/master refs/heads/some_branch:refs/remotes/origin/some_branch

我想将上述“集合”的 refspecs 指定为git fetch. 我试过了

$ git config 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

它失败:

$ git config remote.origin.fetch
refs/heads/my_name/*:refs/remotes/origin/my_name/*
error: More than one value for the key remote.origin.fetch: refs/heads/master:refs/remotes/origin/master

我也尝试了以下方法,但它也失败了:

$ git config remote.origin.fetch 'refs/heads/my_name/*:refs/remotes/origin/my_name/* refs/heads/master:refs/remotes/origin/master refs/heads/some_branch:refs/remotes/origin/some_branch'
$ git fetch
fatal: Invalid refspec 'refs/heads/my_name/*:refs/remotes/origin/my_name/* refs/heads/master:refs/remotes/origin/master refs/heads/some_branch:refs/remotes/origin/some_branch'

注意:Git 1.7.11

4

4 回答 4

43

您可以在您的中添加以下行.git/config以指定多个 refspecs 进行提取:

[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

+如果您还想覆盖获取非快进引用,则可以在 refspec 之前添加前缀,如下所示:

[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

请注意,不支持部分通配(即a/b/ca*不支持,但支持a/b/*)。

10.5 Git 内部结构——Refspec

于 2013-03-19T19:31:20.080 回答
27

要覆盖现有的 fetch refspec(s),而无需手动编辑.git/config,您可以根据需要使用--unset-all后跟--add

对于问题中所需的参考规范示例,它将是:

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

然后用于git config --get-all remote.origin.fetch验证结果。

于 2017-04-07T14:32:00.577 回答
4

注意:如果您想在一次调用中从不同的 refspec获取(临时覆盖配置中注册的 fetch refspec),您可以从 Git 2.1(2014 年 8 月)开始这样做。

请参阅Junio C Hamano ( )提交 c5558f8gitster

自从引入远程跟踪分支的机会性更新以来,大约从 f269048 ( fetch: opportunistically update tracking refs, 2013-05-11) 开始,在 v1.8.4 时代进行了一些更新,即使在指定 refspec 时,配置也总是会启动remote.*.fetch要获取的内容在命令行中给出,并且无法在每次调用时禁用或覆盖它

教命令时要注意--refmap=<lhs>:<rhs>命令行选项,可用于覆盖配置remote.*.fetch为 refmap 的使用。

这为您提供了新的选择:

--refmap=<refspec>

获取命令行上列出的 refs 时,使用指定的 refspec(可以多次给出)将 refs 映射到远程跟踪分支,而不是remote.*.fetch远程存储库的配置变量的值。
有关详细信息,请参阅“配置的远程跟踪分支”部分。

(那个 Git “配置的远程跟踪分支”部分也可以追溯到 Git 2.1:请参阅“很难理解git fetch”)


在 Git 2.25.1(2020 年 2 月)中,“git fetch --refmap=" 选项获得了更好的文档。

请参阅Derrick Stolee ( ) 的提交 b40a502(2020 年 1 月 21 日(由Junio C Hamano 合并 -- --4b69f29 提交中,2020 年 1 月 30 日)derrickstolee
gitster

fetch: 记录和测试 --refmap=""

签字人:Derrick Stolee

为了防止在 ' ' 调用期间长时间阻塞git fetch,用户可能希望为后台 ' git fetch' 进程设置时间表。
但是,由于 Git 添加远程时配置中设置的默认 refspec,这些运行将更新 refs/remotes 分支。
因此,用户在前台获取期间不会注意到远程 refs 何时更新。事实上,他们可能希望这些 refs 保持原样,以便他们可以使用上次前台 fetch 调用中的 refs。

这可以通过使用 ' --refmap=' 和自定义 refspec 覆盖配置的 refspec 来完成:

git fetch --refmap='' <remote> +refs/heads/*:refs/hidden/<remote>/*

填充自定义参考空间并下载一组新的可达对象。
这种调用允许发生一些事情:

  1. 如果 refs 已更新,我们会下载一个新包。2、由于存在refs/hidden分支,GC不会删除新下载的数据。
  2. 启用后,fetch.writeCommitGraph参考/隐藏参考用于更新提交图文件。

为了避免 refs/hidden 目录被无限制填充,--prune可以包含该选项。当提供这样的 refspec 时,该--prune选项不会删除远程 refs,而只会删除目标 refspace 中的 refs。

更新文档以阐明 ' --refmap=""' 的工作原理并创建测试以保证这种行为在未来仍然存在。

所以git fetch选项手册页现在包括:

--refmap=<refspec>:

获取命令行上列出的 refs 时,使用指定的 refspec(可以多次给出)将 refs 映射到远程跟踪分支,而不是remote.*.fetch远程存储库的配置变量的值。

<refspec>为选项提供空--refmap值会导致 Git 忽略配置的 refspecs 并完全依赖作为命令行参数提供的 refspecs。
有关详细信息,请参阅“配置的远程跟踪分支”部分。


请注意,我们在过去 7 年左右对远程跟踪分支进行的更积极的更新并未反映在文档中,该文档已在 Git 2.27(2020 年第二季度)中得到纠正。

请参阅Philippe Blain ( ) 的commit a440884commit f6a65de(2020 年 4 月 5 日(由Junio C Hamano 合并 -- --提交 fdee8b1中,2020 年 4 月 22 日)phil-blain
gitster

pull doc:更正过时的示例描述

签字人:Philippe Blain

由于f269048754 (" fetch: opportunistically update tracking refs", 2013-05-11, Git v1.8.4-rc0 -- merge在批次#0中列出) git fetch[git pull中的底层](https://git-scm.com/docs/git-pull) <remote> <branch>更新了配置的远程跟踪分支。

但是,文档的“示例”部分中的示例git pull仍然表明情况并非如此。

更正此示例的描述。

所以,而不是,对于git pull origin next

这会在 FETCH_HEAD 中临时留下一个副本next,但不会更新任何远程跟踪分支。
使用远程跟踪分支,同样可以通过调用 fetch 和 merge 来完成:

你现在有

next这会在 FETCH_HEAD中临时留下一个副本,并更新远程跟踪分支origin/next
同样可以通过调用 fetch 和 merge 来完成:

于 2014-08-02T18:12:40.097 回答
2

回答我自己关于缺乏示例的抱怨refmap。这是一个在不与配置交互的情况下从 VSO(Visual Studio Online)签出拉取请求的示例。

$ git fetch --refmap='+refs/pull/*/merge:refs/remotes/origin/pr/*' origin refs/pull/1415/merge $ git checkout pr/1415

于 2018-03-14T01:54:41.040 回答