很难理解git-fetch

我很难理解git-fetch的细微差别。 我明白,做一个fetch ,获取远程参考本地跟踪分支。

我有几个问题,但:

  1. 本地跟踪分支是否可能不存在? 如果是的话,它会自动创build?

  2. 如果我做一个fetch并指定一个非跟踪分支作为目的地会发生什么?

  3. git-fetch的手册页指定:

     git-fetch <options> <repository> <refspec> 

我将如何使用refspec从远程主站获取内容到远程跟踪分支? 我相信这可能是可能的,如果我现在的头是主人,我跑

git fetch origin master

但是,我可以使用<+?src:dest> refspec来实现相同的function吗? 我想这会帮助我更好地理解这些概念。

还有一个问题:

我的.git / config文件具有以下用于抓取的行(仅显示相关的行):

 fetch = +refs/heads/*:refs/remotes/origin/* 

有人可以解释一下这一行究竟是什么意思?

首先,没有这样的本地跟踪分支的概念,只有远程跟踪分支。 所以origin / master原始回购中master的远程跟踪分支。

通常你做git fetch $ remote ,它会更新所有的远程跟踪分支,并在需要时创build新分支。

但是,您也可以指定一个refspec,但不会触及您的远程跟踪分支,取而代之的是,它将获取您指定的分支并将其保存在FETCH_HEAD上,除非您指定了目的地。 一般来说,你不想搞砸这个。

最后,

 fetch = +refs/heads/*:refs/remotes/origin/* 

这意味着如果你这样做

 git fetch origin 

它实际上会做:

 git fetch origin +refs/heads/*:refs/remotes/origin/* 

这意味着远程头/ foobar将是本地遥控器/起源/ foobar ,加号表示即使他们不快速前进,他们也会更新。

也许你认为跟踪分支是与git pull和合并configuration相关的东西。

在他的回答中, felipec 回答了大多数有问题的问题 。

剩下的几个(大部分来自git fetch manpage;这在一些地方有点过时,不幸):

  • 如果远程跟踪分支 (追踪某个远程存储库中某个分支的分支)不存在,则会创build它。

  • 你读取的分支( [+]<src>:<dst> )不需要驻留在remotes/<remote>/命名空间中。 例如,对于镜像库( git clone --mirror ), git clone --mirror是1到1.在单独的远程布局之前(远程跟踪参考的远程remotes/<remote>/命名空间之前) 分支被提取到称为原点的分支中。 即使是当前的标签也是以镜像的方式直接进入tags/名字空间的。

  • 如果您正在进入分支(refspec <src>:<dst>的右侧),Git将检查下载是否会导致快进,也就是说,如果<dst>当前状态是<src>的状态的祖先<src>在给定的远程仓库中,如果不是,并且不使用-f / --force选项来进行git-fetch,或者在refspec前面添加'+'(使用+<src>:<dst> refspec)会拒绝更新那个分支。

  • git fetch origin master相当于git fetch origin master: ,而不是git fetch origin master:master ; 它将分支(远程原点 )的提取值存储在FETCH_HEAD中 ,而不是存储在分支或远程跟踪remotes/origin/master分支中。 它可以跟着git merge FETCH_HEAD 。 通常不是直接使用,而是作为一次性拉动而不设置远程跟踪分支的一部分: git pull <URL> <branch>

  • +refs/heads/*:refs/remotes/origin/*作为remote.origin.fetchconfigurationvariables的值,意味着远程原点中的每个分支(ref in refs/heads/ namespace)被提取到分别命名的远程跟踪分支refs/remotes/origin/命名空间,例如原始 分支(即refs/heads/master ref)将被提取到原始/主远程跟踪分支(即refs/remotes/origin/master ref)中。 “+”前缀表示即使在非快进的情况下,取指也会成功,这意味着当远程分支被重新设置或重绕(重置为过去的某个状态)或以其他方式修改时。

旁注:你可能会想要使用更高级别的git remote命令来pipe理远程存储库并获取更新。

请注意,Git的主要维护者现在(Git 2.1,2014年8月)添加了对git fetch解释:
(见Junio C gitstergitster ) 提交fcb14b0 :

configuration的远程跟踪分支

您经常通过定期和反复地从相同的远程存储库进行交互。 为了跟踪这样一个远程仓库的进度, git fetch允许你configurationremote.<repository>.fetchconfigurationvariables。

通常这样的variables可能看起来像这样:

 [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* 

这种configuration有两种使用方式:

  • git fetch在没有指定在命令行上获取哪些分支和/或标签的情况下运行时,例如git fetch origin或者git fetchremote.<repository>.fetch值被用作remote.<repository>.fetch —它们指定要获取哪个ref和哪些地方参考更新
    上面的例子将获取origin中存在的所有分支(即任何与值左侧相匹配的ref, refs/heads/* ),并更新refs/remotes/origin/*相应的远程跟踪分支层次结构。

  • git fetch在命令行上使用显式分支和/或标签来获取时,例如git fetch origin master ,命令行给出的<refspec>决定了要获取什么(例如master ,对于master:是一个短手,而这又意味着“获取' master ''分支,但是我没有明确地说明用它从命令行更新的什么远程跟踪分支”),而示例命令将获取' master “分支。
    remote.<repository>.fetch值确定哪个远程跟踪分支(如果有的话)被更新。
    当以这种方式使用时, remote.<repository>.fetch值在决定获取的内容时没有任何作用(即,当命令行列表参考时,这些值不被用作refspecs)。 它们仅用于通过充当映射来确定被提取的ref的存储位置。

还要注意的是,在Git 2.5+(Q2 2015)中, git merge FETCH_HEAD可以合并多个git fetch

见Junio C gitstergitster ) ,2015年3月26日的提交d45366e 。
(由Junio C gitster合并- gitster – in commit bcd1ecd ,2015年5月19日)

git merge FETCH_HEAD ”得知前面的“ git fetch ”可以创build一个Octopus合并,即logging多个没有标记为“不合并”的分支。
这允许我们在执行“ git pull ”脚本时失去一个老式的调用“ git merge <msg> HEAD $commits... ”; 旧式的语法现在可以被弃用。

git merge doc现在提到:

FETCH_HEAD (并且没有其他提交)时, 通过先前的git fetch调用进行合并logging在.git/FETCH_HEAD文件中的分支将合并到当前分支


Git 2.13(2017年第二季度)正式退休了旧的git merge语法。
参见Junio C gitstergitster )的 提交b439165 (2015年3月26日) 。
(由Junio C gitster合并- gitster – in commit 1fdbfc4 ,2017年3月30日)

mergegit merge <message> HEAD <commit> '语法

停止支持自2007年10月以来已弃用的“ git merge <message> HEAD <commit> ”语法,并自v2.5.0以来发出弃用警告消息。

这意味着老式的“ 'git merge <msg> HEAD <commit>' is deprecated.的警告信息'git merge <msg> HEAD <commit>' is deprecated.