【问题标题】:Can I specify in .git/config to fetch multiple refspecs?我可以在 .git/config 中指定获取多个 refspecs 吗?
【发布时间】:2013-03-08 14:04:14
【问题描述】:

我不想从原点获取每个分支,因为有很多。我只想跟踪一些(例如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

【问题讨论】:

  • 注意:从 Git 2.1(2014 年 8 月)开始,您可以使用新的 fetch 选项 --refmap=<refspec> 在每次调用的基础上覆盖 fetch refspec(仅表示一个命令):参见 @987654321 @

标签: git


【解决方案1】:

您可以在 .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 Internals - The Refspec

【讨论】:

  • 我意识到“git config remote.origin.fetch”报告的错误并不意味着它不能使用多个值。我只需要使用“git config --get-all remote.origin.fetch”以不同方式查询它
  • @Tuxdude 谢谢。是否有一个命令可以实现上述目标?我试图让我的文档对新开发人员保持简洁,我希望他们可以通过“git config remote.origin.fetch”指定多个 refspec,而不是编辑他们的 git config 文件。
  • @Danjah 类似 "+refs/heads/master:refs/remotes/origin/master'" 会起作用
【解决方案2】:

要覆盖现有的 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验证结果。

【讨论】:

  • 正是我需要的!本质上,当版本标签被更新时,这可以防止旧标签妨碍并更新(和缓存),而不会对新标签造成任何损失。您甚至可以毫无问题地回到旧标签。
  • 另一个要考虑的选项是使用git config --fixed-value --unset,后跟git config --add,如果它是在许多人可能使用的脚本中完成的。
【解决方案3】:

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

commit c5558f8Junio C Hamano (gitster)

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

教导命令注意--refmap=<lhs>:<rhs> 命令行选项,这些选项可用于覆盖使用配置的remote.*.fetch 作为参考映射。

这为您提供了新的选择:

--refmap=<refspec>

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

(Git“配置远程跟踪分支”部分也源自 Git 2.1:参见“Having a hard time understanding git fetch”)


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

参见Derrick Stolee (derrickstolee)commit b40a502(2020 年 1 月 21 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 4b69f29,2020 年 1 月 30 日)

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

签字人:Derrick Stolee

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

这可以通过使用“--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 option man page 现在包括:

--refmap=<refspec>:

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

--refmap 选项提供一个空的 &lt;refspec&gt; 会导致 Git 忽略配置的 refspec,并完全依赖作为命令行参数提供的 refspec。
有关详细信息,请参阅“Configured Remote-tracking Branches”部分。


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

参见commit a440884commit f6a65de(2020 年 4 月 5 日)Philippe Blain (phil-blain)
(由 Junio C Hamano -- gitster -- 合并到 commit fdee8b1,2020 年 4 月 22 日)

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

签字人:Philippe Blain

由于f269048754(“fetch:机会性地更新跟踪引用”,2013-05-11,Git v1.8.4-rc0 -- merge 列在batch #0),底层的git fetch 在@ 987654371@git pull](https://git-scm.com/docs/git-pull) &lt;remote&gt; &lt;branch&gt; 更新配置的远程跟踪分支。

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

更正这个例子的描述。

所以不是,对于git pull origin next

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

You now have:

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

【讨论】:

  • 一个使用 --refmap 的实际 real 示例在这里会很有用。我不确定互联网上是否存在一个明确的例子。
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 2013-06-02
    • 2018-02-23
    • 2015-06-18
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    相关资源
    最近更新 更多