简体   繁体   English

“git fetch --tags”是否包括“git fetch”?

[英]Does “git fetch --tags” include “git fetch”?

A nice and simple question - is the function of "git fetch" a strict sub-set of git fetch --tags ?一个很好而简单的问题 - “git fetch”的功能是git fetch --tags吗?

Ie if I run git fetch --tags , is there ever a reason to immediately run git fetch straight afterward?即,如果我运行git fetch --tags ,是否有理由在之后立即运行git fetch

What about git pull and git pull --tags ? git pullgit pull --tags怎么git pull --tags Same situation?一样的情况?

Note: starting with git 1.9/2.0 (Q1 2014) , git fetch --tags fetches tags in addition to what are fetched by the same command line without the option.注意:从git 1.9/2.0 (Q1 2014) 开始git fetch --tags除了没有选项的同一命令行获取的内容外, git fetch --tags获取标签。

To fetch only tags:只获取标签:

git fetch <remote> 'refs/tags/*:refs/tags/*

In details:详细说明:

See commit c5a84e9 by Michael Haggerty (mhagger) :请参阅Michael Haggerty (mhagger) 提交的 c5a84e9

Previously, fetch's " --tags " option was considered equivalent to specifying the refspec以前,fetch 的“ --tags ”选项被认为等同于指定--tags

 refs/tags/*:refs/tags/*

on the command line;在命令行上; in particular, it caused the remote.<name>.refspec configuration to be ignored.特别是,它导致remote.<name>.refspec配置被忽略。

But it is not very useful to fetch tags without also fetching other references, whereas it is quite useful to be able to fetch tags in addition to other references.但是在不获取其他引用的情况下获取标签并不是很有用,而能够其他引用之外获取标签非常有用的。
So change the semantics of this option to do the latter.所以改变这个选项的语义来做后者。

If a user wants to fetch only tags, then it is still possible to specifying an explicit refspec:如果用户希望获取标签,那么它仍然可以指定一个明确的Refspec:

 git fetch <remote> 'refs/tags/*:refs/tags/*'

Please note that the documentation prior to 1.8.0.3 was ambiguous about this aspect of " fetch --tags " behavior.请注意,1.8.0.3 之前的文档对“ fetch --tags ”行为的这一方面含糊不清。
Commit f0cb2f1 (2012-12-14) fetch --tags made the documentation match the old behavior. Commit f0cb2f1 (2012-12-14) fetch --tags使文档与旧行为相匹配。
This commit changes the documentation to match the new behavior (see Documentation/fetch-options.txt ).此提交更改文档以匹配新行为(请参阅Documentation/fetch-options.txt )。

Request that all tags be fetched from the remote in addition to whatever else is being fetched .请求除了正在获取的任何其他标签之外,还从远程获取所有标签。


Since Git 2.5 (Q2 2015) git pull --tags is more robust:从 Git 2.5(2015 年第二季度)开始, git pull --tags更加健壮:

See commit 19d122b by Paul Tan ( pyokagan ) , 13 May 2015.请参阅Paul Tan ( pyokagan )于 2015 年 5 月 13 日提交的 19d122b
(Merged by Junio C Hamano -- gitster -- in commit cc77b99 , 22 May 2015) (由Junio C gitster合并gitster 提交 cc77b99,2015年 5 月 22 日)

pull : remove --tags error in no merge candidates case pull : 在没有合并候选的情况下删除--tags错误

Since 441ed41 (" git pull --tags ": error out with a better message., 2007-12-28, Git 1.5.4+), git pull --tags would print a different error message if git-fetch did not return any merge candidates:441ed41 (" git pull --tags ": error out with a better message., 2007-12-28, Git 1.5.4+) 开始,如果git-fetch没有返回, git pull --tags将打印不同的错误消息任何合并候选人:

 It doesn't make sense to pull all tags; you probably meant: git fetch --tags

This is because at that time, git-fetch --tags would override any configured refspecs, and thus there would be no merge candidates.这是因为当时git-fetch --tags会覆盖任何配置的git-fetch --tags ,因此不会有合并候选者。 The error message was thus introduced to prevent confusion.因此引入错误消息是为了防止混淆。

However, since c5a84e9 ( fetch --tags : fetch tags in addition to other stuff, 2013-10-30, Git 1.9.0+), git fetch --tags would fetch tags in addition to any configured refspecs.但是,由于c5a84e9fetch --tags除了其他东西之外还提取标签,2013-10-30,Git 1.9.0+), git fetch --tags除了任何配置的git fetch --tags还会提取标签。
Hence, if any no merge candidates situation occurs, it is not because --tags was set.因此,如果出现没有合并候选的情况,那不是因为设置了--tags As such, this special error message is now irrelevant.因此,此特殊错误消息现在无关紧要。

To prevent confusion, remove this error message.为防止混淆,请删除此错误消息。


With Git 2.11+ (Q4 2016) git fetch is quicker.使用 Git 2.11+(2016 年第四季度), git fetch更快。

See commit 5827a03 (13 Oct 2016) by Jeff King ( peff ) .请参阅Jeff King ( peff ) 的commit 5827a03 (2016 年 10 月 13 日
(Merged by Junio C Hamano -- gitster -- in commit 9fcd144 , 26 Oct 2016) (由Junio C gitster合并-- gitster -- in commit 9fcd144 ,2016 年 10 月 26 日)

fetch : use "quick" has_sha1_file for tag following fetch :使用“快速” has_sha1_file进行标记跟踪

When fetching from a remote that has many tags that are irrelevant to branches we are following, we used to waste way too many cycles when checking if the object pointed at by a tag (that we are not going to fetch!) exists in our repository too carefully.当从具有许多与我们遵循的分支无关的标签的远程获取时,在检查由标签(我们不打算获取!)指向的对象是否存在于我们的存储库中时,我们过去常常浪费太多周期太仔细了。

This patch teaches fetch to use HAS_SHA1_QUICK to sacrifice accuracy for speed, in cases where we might be racy with a simultaneous repack.这个补丁教导 fetch 使用 HAS_SHA1_QUICK 来牺牲准确性以换取速度,在我们可能同时重新打包的情况下。

Here are results from the included perf script, which sets up a situation similar to the one described above:以下是包含的 perf 脚本的结果,它设置了一种类似于上述情况的情况:

 Test HEAD^ HEAD ---------------------------------------------------------- 5550.4: fetch 11.21(10.42+0.78) 0.08(0.04+0.02) -99.3%

That applies only for a situation where:这仅适用于以下情况:

  1. You have a lot of packs on the client side to make reprepare_packed_git() expensive (the most expensive part is finding duplicates in an unsorted list, which is currently quadratic).您在客户端有很多包使reprepare_packed_git()变得昂贵(最昂贵的部分是在未排序的列表中查找重复项,目前是二次的)。
  2. You need a large number of tag refs on the server side that are candidates for auto-following (ie, that the client doesn't have).服务器端需要大量标记引用作为自动跟踪的候选对象(即,客户端没有)。 Each one triggers a re-read of the pack directory.每一个都会触发重新读取包目录。
  3. Under normal circumstances, the client would auto-follow those tags and after one large fetch, (2) would no longer be true.在正常情况下,客户端会自动跟踪这些标签,并且在一次大提取后,(2) 不再成立。
    But if those tags point to history which is disconnected from what the client otherwise fetches, then it will never auto-follow, and those candidates will impact it on every fetch.但是,如果这些标签指向与客户端以其他方式获取的内容断开连接的历史记录,那么它将永远不会自动跟随,并且这些候选者将在每次获取时对其产生影响。

Git 2.21 (Feb. 2019) seems to have introduced a regression when the config remote.origin.fetch is not the default one ( '+refs/heads/*:refs/remotes/origin/*' )配置remote.origin.fetch不是默认配置'+refs/heads/*:refs/remotes/origin/*' )时,Git 2.21(2019 年 2 月)似乎引入了回归

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed

Git 2.24 (Q4 2019) adds another optimization. Git 2.24(2019 年第四季度)增加了另一项优化。

See commit b7e2d8b (15 Sep 2019) by Masaya Suzuki ( draftcode ) .请参阅Masaya Suzuki ( draftcode ) 提交的 b7e2d8b (2019 年 9 月 15 日
(Merged by Junio C Hamano -- gitster -- in commit 1d8b0df , 07 Oct 2019) (由Junio C gitster合并gitster 提交 1d8b0df ,2019 年 10 月 7 日)

fetch : use oidset to keep the want OIDs for faster lookup fetch : 使用oidset保留想要的 OID 以便更快地查找

During git fetch , the client checks if the advertised tags' OIDs are already in the fetch request's want OID set.git fetch期间,客户端检查广告标签的 OID 是否已经在 fetch 请求的想要的 OID 集中。
This check is done in a linear scan.该检查是在线性扫描中完成的。
For a repository that has a lot of refs, repeating this scan takes 15+ minutes.对于具有大量引用的存储库,重复此扫描需要 15 分钟以上。

In order to speed this up, create a oid_set for other refs' OIDs.为了加快速度, oid_set为其他裁判的 OID 创建一个oid_set

Note: this answer is only valid for git v1.8 and older.注意:此答案仅对 git v1.8 及更早版本有效。

Most of this has been said in the other answers and comments, but here's a concise explanation:在其他答案和评论中已经说过大部分内容,但这里有一个简洁的解释:

  • git fetch fetches all branch heads (or all specified by the remote.fetch config option), all commits necessary for them, and all tags which are reachable from these branches. git fetch获取所有分支头(或所有由 remote.fetch 配置选项指定的),它们所需的所有提交,以及可从这些分支访问的所有标签。 In most cases, all tags are reachable in this way.在大多数情况下,所有标签都可以通过这种方式访问​​。
  • git fetch --tags fetches all tags, all commits necessary for them. git fetch --tags获取所有标签,以及它们所需的所有提交。 It will not update branch heads, even if they are reachable from the tags which were fetched.不会更新分支头,即使它们可以从获取的标签中访问。

Summary: If you really want to be totally up to date, using only fetch, you must do both.总结:如果你真的想完全更新,只使用 fetch,你必须两者都做。

It's also not "twice as slow" unless you mean in terms of typing on the command-line, in which case aliases solve your problem.它也不是“慢两倍”,除非您的意思是在命令行上键入,在这种情况下别名可以解决您的问题。 There is essentially no overhead in making the two requests, since they are asking for different information.发出这两个请求基本上没有开销,因为它们请求的是不同的信息。

I'm going to answer this myself.我自己来回答这个问题。

I've determined that there is a difference.我已经确定有区别。 "git fetch --tags" might bring in all the tags, but it doesn't bring in any new commits! “git fetch --tags”可能会引入所有标签,但不会引入任何新的提交!

Turns out one has to do this to be totally "up to date", ie replicated a "git pull" without the merge:事实证明,必须这样做才能完全“最新”,即在没有合并的情况下复制“git pull”:

$ git fetch --tags
$ git fetch

This is a shame, because it's twice as slow.这是一种耻辱,因为它的速度是原来的两倍。 If only "git fetch" had an option to do what it normally does and bring in all the tags.如果只有“git fetch”可以选择做它通常做的事情引入所有标签。

The general problem here is that git fetch will fetch +refs/heads/*:refs/remotes/$remote/* .这里的一般问题是git fetch将获取+refs/heads/*:refs/remotes/$remote/* If any of these commits have tags, those tags will also be fetched.如果这些提交中的任何一个有标签,这些标签也将被获取。 However if there are tags not reachable by any branch on the remote, they will not be fetched.但是,如果远程上的任何分支都无法访问标签,则不会获取它们。

The --tags option switches the refspec to +refs/tags/*:refs/tags/* . --tags选项将--tags切换为+refs/tags/*:refs/tags/* You could ask git fetch to grab both.可以要求git fetch两者都抓取。 I'm pretty sure to just do a git fetch && git fetch -t you'd use the following command:我很确定只执行git fetch && git fetch -t你会使用以下命令:

git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"

And if you wanted to make this the default for this repo, you can add a second refspec to the default fetch:如果你想让它成为这个 repo 的默认值,你可以添加第二个 refspec 到默认的 fetch:

git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"

This will add a second fetch = line in the .git/config for this remote.这将在.git/config中为此远程添加第二个fetch =行。


I spent a while looking for the way to handle this for a project.我花了一段时间寻找处理这个项目的方法。 This is what I came up with.这就是我想出的。

git fetch -fup origin "+refs/*:refs/*"

In my case I wanted these features就我而言,我想要这些功能

  • Grab all heads and tags from the remote so use refspec refs/*:refs/*从远程获取所有头部和标签,因此使用 refspec refs/*:refs/*
  • Overwrite local branches and tags with non-fast-forward + before the refspec在 refspec 之前用非快进+覆盖本地分支和标签
  • Overwrite currently checked out branch if needed -u如果需要,覆盖当前签出的分支-u
  • Delete branches and tags not present in remote -p删除远程-p不存在的分支和标签
  • And force to be sure -f并强制确定-f

In most situations, git fetch should do what you want, which is 'get anything new from the remote repository and put it in your local copy without merging to your local branches'.在大多数情况下, git fetch应该做你想做的事情,即“从远程存储库中获取任何新内容并将其放入您的本地副本中,而无需合并到您的本地分支”。 git fetch --tags does exactly that, except that it doesn't get anything except new tags. git fetch --tags就是这样做的,除了它没有得到新标签之外的任何东西。

In that sense, git fetch --tags is in no way a superset of git fetch .在这个意义上, git fetch --tags是没有办法的一个超集git fetch It is in fact exactly the opposite.事实上恰恰相反。

git pull , of course, is nothing but a wrapper for a git fetch <thisrefspec>; git merge当然, git pull只不过是git fetch <thisrefspec>; git merge的包装器git fetch <thisrefspec>; git merge git fetch <thisrefspec>; git merge . git fetch <thisrefspec>; git merge It's recommended that you get used to doing manual git fetch ing and git merge ing before you make the jump to git pull simply because it helps you understand what git pull is doing in the first place.建议您在跳转到git pull之前习惯于手动执行git fetchgit merge ing,因为它可以帮助您首先了解git pull正在做什么。

That being said, the relationship is exactly the same as with git fetch .话虽如此,这种关系与git fetch完全相同。 git pull is the superset of git pull --tags . git pullgit pull --tags的超集。

git fetch upstream --tags

工作得很好,它只会获得新标签,而不会获得任何其他代码库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM