这些`git fetch`语法有什么区别?
我克隆了一个仓库( git clone --bare
),显然git fetch
并没有更新它,但是git fetch origin master:master
确实如此。 我不明白这些语法之间的所有细微差别:
git fetch
git fetch origin
git fetch origin master
git fetch origin master:master
origin
是我唯一的远程和master
是我唯一的分支,和帮助说:
当没有指定遥控器时,默认使用原点遥控器
那么为什么这四条线不一样呢?
编辑:三个第一个命令似乎在一个名为FEATCH_HEAD
的临时分支中FEATCH_HEAD
。 但是由于我使用的是裸副本,因此我无法使用git merge
来获取获取的结果。
编辑2:从@ 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
[remote "origin"]
url = git://anongit.freedesktop.org/mesa/mesa
+ fetch = +refs/*:refs/*
+ mirror = true
Only in mesa.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.idx
Only in mesa.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.pack
Only in mesa.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.idx
Only in mesa.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.pack
谢谢!
Andrew C的评论在这里包含了关键,但我会解释一下:
没有附加参数的git fetch
通过查看当前分支来选择远程名称,或者使用origin
(请参阅文档以获取详细信息)。 选择一个遥控器后,它会继续进行下一个表格。
git fetch remote
,再次没有额外的参数,使用给定的远程,并提取该远程的fetch =
行以获得一组“refspecs”。 然后它类似于最后的情况。
git fetch remote refspec
使用给定的远程和给定的refspec(您可以在此给出多个refspecs)来选择要更新的引用。
一旦git fetch
有远程或URL给定的远程名称,它会提取url =
行以获取URL - 它会联系远程服务器上的其他git命令,并要求它们提供所有远程存储库的引用的列表(分支,标签和其他引用,全部在refs/*
名称空间中, HEAD
的特殊添加也可以获得,但在这里通常不会使用 - 它是用于初始克隆步骤的)。
对于这样获得的每个引用, git fetch
查看你是否要求它引用该引用,如果是,请问你的git在存储库中使用了哪个名称。
再次,可用的名字是从远程获得的。 需要的名字是从你的refspecs中获得的,他们将在你的仓库中给出的名字也可以从你的refspecs中获得。
a:b
形式a:b
refspec意思是“引用a
,但在本地调用b
”。
缺少b
部分的FETCH_HEAD
意味着“参考a
,但将其放入特殊的FETCH_HEAD
文件中。” ( FETCH_HEAD
然后变得像普通引用,就像MERGE_HEAD
和ORIG_HEAD
等一样,只是它有一些额外的文本写入到它的pull
脚本中,所以它只是有时按你期望的方式工作。)
一个refspec可能包含一个通配符: refs/heads/*
表示“采取所有分支”(根据定义,分支是以refs/heads/
开头的引用)。 通常情况下, fetch =
使用Git的配置行表示, refs/heads/*:refs/remotes/origin/*
.1之前,这意味着重命名匹配的分支,与*
扩大到右边无论*
左侧匹配的冒号。 所以这会把所有分支都带过来,但将它们重新命名为origin/master
等等。 这就是常想你想为一个非--bare
库。
有时候,这也是你想要的东西了--bare
库中,并且有时不是。 特别是,有时你需要一个“镜像”存储库,它是一个简单的副本,只是简单地复制一些其他存储库。 要将一个普通的裸仓库变成这样一个镜像,你只需要修改fetch =
行:而不是refs/heads/*:refs/remotes/origin/*
这行应该读取fetch = refs/heads/*:refs/heads/*
。 事实上,你可能想用fetch = refs/*:refs/*
来引入所有的东西(标签,甚至是音符)。 当然,无论你真的想要这个,只有你可以决定。
请注意,这很常见, git clone
有一个标志可以自动设置它:使用--mirror
克隆,并且使用修改后的fetch =
行获得裸副本。
1其实这行读取的是+refs/heads/*:refs/remotes/origin/*
,也就是说,还有一个前导+
字符。 这个加号设置了“强制标志”,就好像你已经使用git fetch --force
来进行特定的引用更新。 这与这里的拼写问题没有特别的关系,但我会注意到,通常情况下,您希望强制更新远程分支(如此处所列的远程分支)以及纯粹的镜像存储库。
如果你正在镜像标签,你可能希望那些做强制更新。 理想情况下,标签永远不会改变(也不会被删除),因此在理想的世界中,这并不重要,但在现实世界中,它们有时会发生变化或被删除。
为了处理引用删除,你必须告诉git fetch
到--prune
(或者,同样地,提供--prune
到git remote update
)。 在refspecs中没有自动修剪的语法(虽然这是合理的,我还没有看到任何提议)。
上一篇: What is the difference between these `git fetch` syntaxes?
下一篇: Differences between git pull origin master & git pull origin/master