"git fetch --tags"是否包含"git fetch"?

dav*_*idA 253 git pull git-fetch git-tag

一个很好而且简单的问题 - "git fetch"的功能是一个严格的子集git fetch --tags吗?

即如果我跑git fetch --tags,有没有理由立即直接跑git fetch

怎么样git pullgit pull --tags?同样的情况?

Von*_*onC 168

注意:从git 1.9/2.0(2014年第1季度)开始,除了没有选项的同一命令行提取的内容之外,还git fetch --tags提取标记.

提交c5a84e9迈克尔·哈格蒂(mhagger) :

以前,fetch的" --tags"选项被认为等同于指定refspec

refs/tags/*:refs/tags/*
Run Code Online (Sandbox Code Playgroud)

在命令行上; 特别是,它导致remote.<name>.refspec配置被忽略.

但它并非没有取也是其他参考获取标签是非常有用的,而它能够抓取代码非常有用,除了其他的引用.
因此,请更改此选项的语义以执行后者.

如果用户想要获取唯一的标签,那么它仍然可以指定一个明确的Refspec:

git fetch <remote> 'refs/tags/*:refs/tags/*'
Run Code Online (Sandbox Code Playgroud)

请注意,1.8.0.3之前的文档对于" fetch --tags"行为的这一方面不明确.
Commit f0cb2f1(2012-12-14)fetch --tags使文档与旧行为相匹配.
此提交更改文档以匹配新行为(请参阅参考资料Documentation/fetch-options.txt).

请求除了正在获取的任何其他内容之外,还要从远程获取所有标记.


自Git 2.5(2015年第二季度)git pull --tags更加强大:

提交19d122b保罗·谭(pyokagan),2015年5月13日
(以合并JUNIOÇ滨野- gitster-提交cc77b99,2015年5月22日)

pull:删除--tags合并候选案例中的错误

由于441ed41(" git pull --tags":错误输出更好的消息.,2007-12-28,Git 1.5.4+),git pull --tags如果git-fetch没有返回任何合并候选者,将打印不同的错误消息 :

It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags
Run Code Online (Sandbox Code Playgroud)

这是因为那时git-fetch --tags会覆盖任何配置的refspecs,因此不会有合并候选者.因此引入了错误消息以防止混淆.

但是,由于c5a84e9(除了 其他内容之外还有fetch --tags fetch标签,2013-10-30,Git 1.9.0+),除了任何已配置的refspec外,还会获取标签. 因此,如果没有合并候选人情况发生,那不是因为设置了.因此,此特殊错误消息现在无关紧要.git fetch --tags
--tags

为防止混淆,请删除此错误消息.


随着Git 2.11 +(2016年第4季度)git fetch更快.

请参阅Jeff King()提交的5827a03(2016年10月13日).(由Junio C Hamano合并- -提交9fcd144,2016年10月26日)peff
gitster

fetch:使用"快速" has_sha1_file标记跟随

当从具有许多与我们正在关注的分支无关的标记的远程获取时,我们常常在检查标记指向的对象(我们不会获取!)时是否存在太多周期太小心了.

这个补丁教授fetch使用HAS_SHA1_QUICK来牺牲速度的准确性,在我们可能同时重新打包的情况下.

以下是包含的perf脚本的结果,该脚本设置了与上述情况类似的情况:

Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%
Run Code Online (Sandbox Code Playgroud)

这仅适用于以下情况:

  1. 你在客户端有很多包使得reprepare_packed_git()昂贵(最昂贵的部分是在未排序的列表中找到重复,这是目前的二次方).
  2. 您需要服务器端的大量标记引用,这些标记引用是自动跟踪的候选者(即,客户端没有).每一个都触发重新读取包目录.
  3. 在正常情况下,客户端会自动跟踪这些标记,并且在一次大的提取之后,(2)将不再是真的.
    但是,如果这些标记指向与客户端以其他方式提取的内容断开连接的历史记录,则它将永远不会自动跟随,并且这些候选项将在每次提取时影响它.

Git的2.21(2019年2月)似乎已经引入了回归时的配置remote.origin.fetch不是默认的('+refs/heads/*:refs/remotes/origin/*')

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed
Run Code Online (Sandbox Code Playgroud)


Cas*_*bel 131

注意:此答案仅对git v1.8及更早版本有效.

大部分内容已在其他答案和评论中说过,但这里有一个简明的解释:

  • git fetch获取所有分支头(或由remote.fetch配置选项指定的所有分支头),它们所需的所有提交,以及可从这些分支到达的所有标记.在大多数情况下,所有标签都可以通过这种方式访问​​.
  • git fetch --tags获取所有标签,所有提交所需的提交.它不会更新分支头,即使它们可以从提取的标签中访问.

简介:如果你真的想要完全更新,只使用fetch,你必须同时做到这两点.

它也不是"两倍慢",除非你的意思是在命令行上输入,在这种情况下别名可以解决你的问题.制作这两个请求基本上没有开销,因为他们要求提供不同的信息.

  • 请注意,`git remote update`实际上不能替代`git fetch`和`git fetch --tags`.`git remote update`不会更新已更改的现有标签,尽管它会引入新标签.只有`git fetch --tags`才会更新已有的标签. (7认同)
  • 谢谢你的评论.我在Cygwin上通过高延迟网络运行git - 当没有任何东西可以获取时(大约5秒),它的速度慢了两倍. (2认同)

dav*_*idA 48

我自己会回答这个问题.

我已经确定存在差异."git fetch --tags"可能会引入所有标记,但它不会带来任何新的提交!

事实证明,必须做到这一点才能完全"更新",即在没有合并的情况下复制"git pull":

$ git fetch --tags
$ git fetch
Run Code Online (Sandbox Code Playgroud)

这是一种耻辱,因为它的速度慢了两倍.如果只有"git fetch"有一个选项来执行它通常做的事情引入所有标签.

  • FTR,'git远程更新myRemoteRepo'效果不好 - 似乎没有做'git fetch && git fetch --tags'那样做,特别是后续合并没有效果. (4认同)
  • 我一直在做`git fetch`,它始终如一地拉下任何新提交__和__任何新标签。你运行的是哪个版本的 Git? (2认同)

gna*_*arf 31

这里的一般问题是git fetch将获取+refs/heads/*:refs/remotes/$remote/*.如果这些提交中的任何一个具有标记,那么也将获取这些标记.但是,如果遥控器上的任何分支都无法访问标记,则不会获取它们.

--tags选项将refspec切换为+refs/tags/*:refs/tags/*.你可以要求git fetch抓住两者.我很确定git fetch && git fetch -t你只需要使用以下命令:

git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"
Run Code Online (Sandbox Code Playgroud)

如果你想把它作为这个repo的默认值,你可以在默认的fetch中添加第二个refspec:

git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"
Run Code Online (Sandbox Code Playgroud)

这将为此遥控器添加第二fetch =.git/config.


我花了一段时间寻找处理项目的方法.这就是我提出的.

git fetch -fup origin "+refs/*:refs/*"
Run Code Online (Sandbox Code Playgroud)

就我而言,我想要这些功能

  • 从遥控器抓取所有头部和标签,因此请使用refspec refs/*:refs/*
  • +在refspec之前用非快进覆盖本地分支和标签
  • 如果需要,覆盖当前签出的分支 -u
  • 删除远程中不存在的分支和标记 -p
  • 并且力量确定 -f


Tim*_*her 10

在大多数情况下,git fetch应该做你想要的,即"从远程存储库中获取任何新内容并将其放入本地副本而不合并到本地分支". git fetch --tags确切地说,除了它没有获得除新标签之外的任何东西.

从这个意义上说,git fetch --tags绝不是超集git fetch.事实上恰恰相反.

git pull当然,它只不过是一个包装纸git fetch <thisrefspec>; git merge.建议您在跳转之前习惯于进行手动操作git fetch,因为它可以帮助您了解首先要做的事情.git mergegit pullgit pull

话虽如此,这种关系与之完全相同git fetch. git pull是超集git pull --tags.

  • 刚刚发现了这个问题......好吧,在我看来,`git pull`确实*不*get*all*标签,但只有那些可以从当前分支头部到达的标签.但是,`git pull --tags`获取所有标签,显然等同于`git fetch --tags`. (9认同)