本文介绍了这些`git fetch`语法有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我裸着克隆了一个仓库( git clone --bare ),显然是 git fetch doesn' t更新它,但是 git fetch origin master:master 确实如此。我不明白这些语法之间的所有细微差别: git fetch git fetch origin git fetch origin master origin 是我唯一的远程, master 是我唯一的分支, b $ b 那么为什么这四条线是不一样的? 编辑:在一个名为 FEATCH_HEAD 的临时分支中获取。但是由于我使用的是裸副本,因此我无法使用 git merge 来获取提取的结果。 Edit2:从@ torek的回答中,我做了一个小测试,分析了一个--bare和一个--mirror克隆目录。结果如下: diff -ru mesa.bare.git / config mesa.mirror.git / config --- mesa.bare.git / config 2014-10-14 20:01:42.812226509 -0400 +++ mesa.mirror.git / config 2014-10-14 20:00:53.994985222 -0400 @@ -4,3 +4,5 @@ bare = true [remoteorigin] url = git://anongit.freedesktop.org/mesa/mesa + fetch = + refs / *:refs / * + mirror = true 仅在mesa.bare.git / objects / pack中:pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.idx 仅在mesa.bare.git / objects / pack:pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.pack 仅在mesa.mirror.git / objects / pack中:pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.idx 仅在mesa.mirror.git / objects /包:pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.pack 谢谢! 解决方案 Andrew C的评论在这里包含了关键字,但我会解释一下: c $ c> git fetch ,没有额外的参数,通过查看当前分支来选择远程名称,或者使用 origin 了解详情)。选择远程后,它会继续下一个表单。 code>,再次没有额外的参数,使用给定的远程,并提取该远程的 fetch = 行来获得一组refspecs。然后它与前一个案例类似。 > 使用给定的远程和给定的refspec(您可以在此给出多个refspecs)来选择要更新的引用。 一旦 git fetch 具有远程或URL给定的远程名称,它将提取 url = line来获得URL - 它与远程服务器上的其他git命令联系,并要求它们列出所有远程存储库的引用(分支,标记和其他引用,全部位于 refs / * name-spaces,并且还有一个特殊的 HEAD ,这也是可以获得的,克隆步骤)。 对于每个这样获得的引用, git fetch 会看到您是否要求它将该引用如果是这样的话,你要求git在你的存储库中使用什么名称。 同样,t他的名字可用是从远程获得的。名称想要是从您的refspecs中获得的,它们将在您的存储库中提供的名称也可以从您的refspecs获得。 A refspec的形式 a:b 表示引用 a ,但将其称为 b 缺少 b 部分的refspec表示引用 a ,但将其放入特殊的 FETCH_HEAD 文件中。 ( FETCH_HEAD 然后变得像一个普通的引用,像 MERGE_HEAD 和 ORIG_HEAD 等等,除了它有一些写入它的额外文本用于 pull 脚本,所以它有时会按照您期望的方式工作。) 一个refspec可能包含一个通配符: refs / heads / * 表示取所有分支 ,以 refs / heads / 开头的引用)。通常你的git配置中的 fetch = 行表示 refs / heads / *:refs / remotes / origin / * 。 1 与前面一样,这意味着重命名匹配的分支,右边的 * 展开为 * 在匹配的冒号左边。因此,这会将所有分支结束,但将它们重命名为 origin / master 等。这通常是你想要一个非 - - 裸存储库。 有时候,这也是你想要的 - 裸露存储库,有时不是。特别是,有时你需要一个镜像存储库,它是一个简单的副本,只是简单地复制一些其他存储库。要将一个普通的裸仓库变成这样一个镜像,您只需修改 fetch = 行:而不是 refs / heads / *:refs / remotes / origin / * 该行应该读取 fetch = refs / heads / *:refs / heads / * 。事实上,你可能想用 fetch = refs / *:refs / * 来带过所有东西(标签,甚至注释)。当然,无论你真的想要这个,只有你自己可以决定。 请注意这很常见, c>有一个标志可以自动设置它:用 - mirror 克隆,你可以得到一个修改过的 fetch = 1 实际上这行读取 + refs / heads / *:refs / remotes / origin / * ,即还有一个前导 + 字符。这个加号设置了强制标志,就好像你已经使用了 git fetch --force 来进行特定的引用更新。这与这里的拼写问题没有特别的关系,但我会注意到,通常情况下,您希望强制更新远程分支(如此处所列的远程分支)以及纯镜像存储库。 如果您正在镜像标签,那么您可能希望那些人进行强制更新。理想情况下,标签永远不会改变(也不会被删除),因此在理想的世界中,这并不重要,但在现实世界中,它们有时会发生变化或被删除。 为了处理引用删除,你必须告诉 git fetch 到 - prune (或者同样地,提供 --prune 到 git remote update )。在refspecs中没有用于自动修剪的语法(尽管这是合理的,我还没有看到任何提议)。 I've bare-cloned a repository (git clone --bare) and apparently git fetch doesn't update it, but git fetch origin master:master does. I don't understand all the nuances between these syntaxes:git fetchgit fetch origingit fetch origin mastergit fetch origin master:masterorigin is my only remote and master is my only branch, and the help says:So why these four lines aren't the same?Edit: the three first commands seems to fetch in a temporary branch called FEATCH_HEAD. But since I'm using a bare clone, I can't use git merge to get the fetched results.Edit2: From @torek's answer, I made a small test and diff'ed a --bare and a --mirror clone directories. Here is the result:diff -ru mesa.bare.git/config mesa.mirror.git/config--- mesa.bare.git/config 2014-10-14 20:01:42.812226509 -0400+++ mesa.mirror.git/config 2014-10-14 20:00:53.994985222 -0400@@ -4,3 +4,5 @@ bare = true [remote "origin"] url = git://anongit.freedesktop.org/mesa/mesa+ fetch = +refs/*:refs/*+ mirror = trueOnly in mesa.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.idxOnly in mesa.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.packOnly in mesa.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.idxOnly in mesa.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.packThanks! 解决方案 Andrew C's comment contains the key here, but I'll expound a bit:git fetch, with no additional arguments, chooses a remote name by looking at the current branch, or uses origin (see the documentation for details). Having chosen a remote, it then proceeds as for the next form.git fetch remote, again with no additional arguments, uses the given remote, and extracts the fetch = lines for that remote to obtain a set of "refspecs". It then proceeds similarly to the last case.git fetch remote refspec uses the given remote and the given refspec (you may give multiple refspecs here) to choose what references to update.Once git fetch has a remote or URL—given the name of a remote, it extracts the url = line to obtain the URL—it contacts the other git commands on the remote server and asks them for a list of all of the remote repository's references (branches, tags, and other references, all in the refs/* name-spaces, with a special addition for HEAD which is also obtainable but not generally used here—it's there for the initial clone step).For each reference thus obtained, git fetch sees whether you have asked it to bring that reference over, and if so, what name you asked git to use in your repository.Again, the names available are obtained from the remote. The names wanted are obtained from your refspecs, and the names they will be given in your repository are also obtained from your refspecs.A refspec of the form a:b means "take reference a, but call it b locally."A refspec missing the b part means "take reference a, but put it into the special FETCH_HEAD file." (FETCH_HEAD then becomes like a normal reference, like MERGE_HEAD and ORIG_HEAD and so on, except that it has some extra text written to it meant for the pull script, so it only sometimes works the way you might expect.)A refspec may contain a wildcard character: refs/heads/* means "take all branches" (branches being, by definition, references that begin with refs/heads/). Normally the fetch = line in your git configuration says refs/heads/*:refs/remotes/origin/*.1 As before, this means to rename the matched branch, with the * on the right expanding to whatever the * on the left of the colon matched. So this brings all branches over, but renames them as origin/master and the like. That's normally want you want for a non---bare repository.Sometimes that's also what you want for a --bare repository, and sometimes it's not. In particular, sometimes you want a "mirror" repository, which is a bare clone that simply slave-copies some other repository. To change an ordinary bare repository into such a mirror, you simply need to modify the fetch = line: instead of refs/heads/*:refs/remotes/origin/* the line should read fetch = refs/heads/*:refs/heads/*. In fact, you may want to bring over everything (tags and even notes) with fetch = refs/*:refs/*. Whether you actually want this is something only you can decide, of course.Note that this is common enough that git clone has a flag to set it up automatically: clone with --mirror and you get a bare clone with the modified fetch = line.1Actually the line reads +refs/heads/*:refs/remotes/origin/*, i.e., there is also a leading + character. This plus-sign sets the "force flag", as if you had used git fetch --force, for that particular reference-update. This is not particularly relevant to the spelling issues here, but I'll note that usually you want a forced update for remote branches like the one listed here, and also for pure mirror repositories.If you're mirroring tags, you probably want those to do forced-update. Ideally, of course, tags never change (nor are deleted) so in an ideal world this would not matter, but in the real world they do sometimes change, or get deleted.To handle reference deletion, you must tell git fetch to --prune (or, similarly, supply --prune to git remote update). There is no syntax in refspecs for automatic pruning (although it would be reasonable, I have not seen any proposal for it). 这篇关于这些`git fetch`语法有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 09-04 20:09