“git fetch --tags”是否包括“git fetch”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1204190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does "git fetch --tags" include "git fetch"?
提问by davidA
A nice and simple question - is the function of "git fetch" a strict sub-set of git fetch --tags
?
一个很好而简单的问题 - “git fetch”的功能是 ? 的严格子集git fetch --tags
?
I.e. 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
? Same situation?
怎么样git pull
和git pull --tags
?一样的情况?
采纳答案by VonC
Note: starting with git 1.9/2.0 (Q1 2014), git fetch --tags
fetches tags in addition towhat are fetched by the same command line without the option.
注意:从git 1.9/2.0 (Q1 2014) 开始,除了没有选项的同一命令行获取的内容之外,还git fetch --tags
获取标签。
See commit c5a84e9by Michael Haggerty (mhagger):
Previously, fetch's "
--tags
" option was considered equivalent to specifying the refspecrefs/tags/*:refs/tags/*
on the command line; in particular, it caused the
remote.<name>.refspec
configuration to be ignored.But it is not very useful to fetch tags without also fetching other references, whereas it isquite useful to be able to fetch tags in addition toother references.
So change the semantics of this option to do the latter.If a user wants to fetch onlytags, then it is still possible to specifying an explicit 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.
Commit f0cb2f1(2012-12-14)fetch --tags
made the documentation match the old behavior.
This commit changes the documentation to match the new behavior (seeDocumentation/fetch-options.txt
).Request that all tags be fetched from the remote in addition to whatever else is being fetched.
以前, fetch 的 "
--tags
" 选项被认为等同于指定 refspecrefs/tags/*:refs/tags/*
在命令行上;特别是,它导致
remote.<name>.refspec
配置被忽略。但是在不获取其他引用的情况下获取标签并不是很有用,而能够在其他引用之外获取标签是非常有用的。 所以改变这个选项的语义来做后者。
如果用户想要获取唯一的标签,那么它仍然可以指定一个明确的Refspec:
git fetch <remote> 'refs/tags/*:refs/tags/*'
请注意,1.8.0.3 之前的文档对“
fetch --tags
”行为的这一方面含糊不清。
Commit f0cb2f1(2012-12-14)fetch --tags
使文档与旧行为相匹配。
此提交更改了文档以匹配新行为(请参阅 参考资料Documentation/fetch-options.txt
)。请求除了正在获取的任何其他标签之外,还从远程获取所有标签。
Since Git 2.5 (Q2 2015) git pull --tags
is more robust:
由于 Git 2.5(2015 年第二季度)git pull --tags
更加健壮:
See commit 19d122bby Paul Tan (pyokagan
), 13 May 2015.
(Merged by Junio C Hamano -- gitster
--in commit cc77b99, 22 May 2015)
见提交19d122b由保罗·谭(pyokagan
),2015年5月13日
(以合并JUNIOÇ滨野- gitster
-在提交cc77b99,2015年5月22日)
pull
: remove--tags
error in no merge candidates caseSince 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: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. The error message was thus introduced to prevent confusion.However, since c5a84e9(
fetch --tags
: fetch tags in addition toother stuff, 2013-10-30, Git 1.9.0+),git fetch --tags
would fetch tags in addition to any configured refspecs.
Hence, if any no merge candidates situation occurs, it is not because--tags
was set. As such, this special error message is now irrelevant.To prevent confusion, remove this error message.
pull
:--tags
在没有合并候选的情况下删除错误由于441ed41("
git pull --tags
": error out with a better message., 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
这是因为在那个时候,
git-fetch --tags
会覆盖任何配置的 refspecs,因此不会有合并候选者。因此引入错误消息是为了防止混淆。但是,由于c5a84e9(
fetch --tags
:除了其他内容之外还获取标签,2013-10-30,Git 1.9.0+),git fetch --tags
除了任何配置的引用规范之外,还会获取标签。
因此,如果出现没有合并候选的情况,那不是因为--tags
设置了。因此,此特殊错误消息现在无关紧要。为防止混淆,请删除此错误消息。
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
).
(Merged by Junio C Hamano -- gitster
--in commit 9fcd144, 26 Oct 2016)
请参阅Jeff King ( ) 的commit 5827a03(2016 年 10 月 13 日)。(由Junio C Hamano合并-- --在提交 9fcd144,2016 年 10 月 26 日)peff
gitster
fetch
: use "quick"has_sha1_file
for tag followingWhen 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.
Here are results from the included perf script, which sets up a situation similar to the one described above:
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%
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).- You need a large number of tag refs on the server side that are candidates for auto-following (i.e., 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.
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.
- 您在客户端有很多包来制作
reprepare_packed_git()
昂贵的(最昂贵的部分是在未排序的列表中查找重复项,目前是二次的)。- 服务器端需要大量标记引用作为自动跟踪的候选对象(即,客户端没有)。每一个都会触发重新读取包目录。
- 在正常情况下,客户端会自动跟踪这些标签,并且在一次大提取后,(2) 不再成立。
但是,如果这些标签指向与客户端以其他方式获取的内容断开连接的历史记录,那么它将永远不会自动跟随,并且这些候选者将在每次获取时对其产生影响。
Git 2.21 (Feb. 2019) seems to have introduced a regression when the config remote.origin.fetch
is notthe default one('+refs/heads/*:refs/remotes/origin/*'
)
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
Git 2.24 (Q4 2019) adds another optimization.
Git 2.24(2019 年第四季度)增加了另一项优化。
See commit b7e2d8b(15 Sep 2019) by Masaya Suzuki (draftcode
).
(Merged by Junio C Hamano -- gitster
--in commit 1d8b0df, 07 Oct 2019)
请参阅Masaya Suzuki ( )提交的 b7e2d8b(2019 年 9 月 15 日)。(由Junio C Hamano合并-- --在commit 1d8b0df,2019 年 10 月 7 日)draftcode
gitster
fetch
: useoidset
to keep the want OIDs for faster lookupDuring
git fetch
, the client checks if the advertised tags' OIDs are already in the fetch request's want OID set.
This check is done in a linear scan.
For a repository that has a lot of refs, repeating this scan takes 15+ minutes.In order to speed this up, create a
oid_set
for other refs' OIDs.
fetch
: 用于oidset
保留想要的 OID 以便更快地查找在 期间
git fetch
,客户端检查广告标签的 OID 是否已经在获取请求的想要的 OID 集中。
该检查是在线性扫描中完成的。
对于具有大量引用的存储库,重复此扫描需要 15 分钟以上。为了加快速度,请
oid_set
为其他裁判的 OID创建一个。
回答by Cascabel
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. In most cases, all tags are reachable in this way.git fetch --tags
fetches all tags, all commits necessary for them. It will notupdate branch heads, even if they are reachable from the tags which were fetched.
git fetch
获取所有分支头(或所有由 remote.fetch 配置选项指定的)、它们所需的所有提交以及可从这些分支访问的所有标签。在大多数情况下,所有标签都可以通过这种方式访问。git fetch --tags
获取所有标签,它们所需的所有提交。它不会更新分支头,即使它们可以从获取的标签中访问。
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.
它也不是“慢两倍”,除非您的意思是在命令行上键入,在这种情况下别名可以解决您的问题。发出这两个请求基本上没有开销,因为它们请求的是不同的信息。
回答by davidA
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", i.e. 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 andbring in all the tags.
这是一种耻辱,因为它的速度是原来的两倍。如果只有“git fetch”可以选择做它通常做的事情并引入所有标签。
回答by gnarf
The general problem here is that git fetch
will 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.
这里的一般问题是git fetch
fetch +refs/heads/*:refs/remotes/$remote/*
。如果这些提交中的任何一个有标签,这些标签也将被获取。但是,如果远程上的任何分支都无法访问标签,则不会获取它们。
The --tags
option switches the refspec to +refs/tags/*:refs/tags/*
. You couldask git fetch
to grab both. I'm pretty sure to just do a git fetch && git fetch -t
you'd use the following command:
该--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/*"
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.
这将fetch =
在.git/config
此遥控器的 中添加第二行。
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/*
- Overwrite local branches and tags with non-fast-forward
+
before the refspec - Overwrite currently checked out branch if needed
-u
- Delete branches and tags not present in remote
-p
- And force to be sure
-f
- 从遥控器获取所有头部和标签,因此使用 refspec
refs/*:refs/*
+
在 refspec 之前用非快进覆盖本地分支和标签- 如果需要,覆盖当前签出的分支
-u
- 删除远程中不存在的分支和标签
-p
- 并强制确定
-f
回答by Tim Visher
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 --tags
does exactly that, except that it doesn't get anything except new tags.
在大多数情况下,git fetch
应该做你想做的,即“从远程存储库中获取任何新内容并将其放在本地副本中,而不合并到本地分支”。 git fetch --tags
正是这样做的,除了它没有得到新标签之外的任何东西。
In that sense, git fetch --tags
is in no way a superset of git fetch
. It is in fact exactly the opposite.
从这个意义上说,git fetch --tags
绝不是 的超集git fetch
。事实上恰恰相反。
git pull
, of course, is nothing but a wrapper for a 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 <thisrefspec>; git merge
. 建议您在跳转到之前先习惯于手动操作git fetch
,因为它可以帮助您首先了解正在做什么。git merge
git pull
git pull
That being said, the relationship is exactly the same as with git fetch
. git pull
is the superset of git pull --tags
.
话虽如此,这种关系与 完全相同git fetch
。 git pull
是 的超集git pull --tags
。
回答by PAnand
git fetch upstream --tags
works just fine, it will only get new tags and will not get any other code base.
工作得很好,它只会获得新标签,而不会获得任何其他代码库。