[英]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 pull
和git 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 (seeDocumentation/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 casepull
: 在没有合并候选的情况下删除--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 ifgit-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.但是,由于c5a84e9 (
fetch --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 followingfetch
:使用“快速”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:这仅适用于以下情况:
- 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()
变得昂贵(最昂贵的部分是在未排序的列表中查找重复项,目前是二次的)。- 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.
每一个都会触发重新读取包目录。
- 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
: useoidset
to keep the want OIDs for faster lookupfetch
: 使用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就我而言,我想要这些功能
refs/*:refs/*
refs/*:refs/*
+
before the refspec+
覆盖本地分支和标签-u
-u
-p
-p
不存在的分支和标签-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 fetch
和git 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 pull
是git pull --tags
的超集。
git fetch upstream --tags
工作得很好,它只会获得新标签,而不会获得任何其他代码库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.