这些`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_HEADORIG_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 (或者,同样地,提供--prunegit remote update )。 在refspecs中没有自动修剪的语法(虽然这是合理的,我还没有看到任何提议)。

    链接地址: http://www.djcxy.com/p/3955.html

    上一篇: What is the difference between these `git fetch` syntaxes?

    下一篇: Differences between git pull origin master & git pull origin/master