很难理解git-fetch

时间:2009-07-01 17:54:57

标签: git git-fetch

我很难理解git-fetch的细微差别。我知道做fetch,将远程引用提取到本地跟踪分支。

我有几个问题:

  1. 本地跟踪分支是否可能不存在?如果是,那么它会自动创建吗?

  2. 如果我执行fetch并指定非追踪分支作为目的地会怎样?

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

    git-fetch <options> <repository> <refspec>
    
  4. 如何使用refspec将远程主服务器中的内容提取到其远程跟踪分支?我相信如果我现在的HEAD是主人并且我跑了

    ,这可能是可能的

    git fetch origin master

    但是,我可以使用<+?src:dest> refspec来实现同样的目的吗?我认为这将有助于我更好地理解这些概念。

    还有一个问题:

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

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

    有人可以解释这条线的确切含义吗?

4 个答案:

答案 0 :(得分:59)

首先,没有本地跟踪分支的概念,只有远程跟踪分支。因此 origin / master 来源回购中的远程跟踪分支。

通常,您执行 git fetch $ remote 更新所有远程跟踪分支,并在需要时创建新分支。

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

最后,

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

这意味着如果你这样做

git fetch origin

它实际上会:

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

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

您认为跟踪分支可能与 git pull 和合并配置相关。

答案 1 :(得分:23)

felipecanswered most of issues in question in his answer

剩下的一些(大多数来自git fetch联机帮助页;不幸的是,在某些地方有点过时了):

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

  • 您获取的分支(<dst>中的[+]<src>:<dst>)不需要驻留在remotes/<remote>/命名空间中。例如,对于镜像存储库(git clone --mirror),refspec是1到1.在过去,在单独的远程跟踪布局之前(远程跟踪引用的remotes/<remote>/命名空间之前)已获取分支进入名为 origin 的分支。即使是当前标签也会以镜像方式直接提取到tags/命名空间。

  • 如果您正在进入分支(refspec <src>:<dst>的右侧确实存在,Git会检查下载是否会导致快进,即<dst>中的当前状态是否为给定远程存储库中<src>中的状态祖先。如果不是,则不使用-f / --force选项进行git-fetch,或使用'+'作为前缀refspec (使用+<src>:<dst> refspec)fetch会拒绝更新该分支。

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

  • +refs/heads/*:refs/remotes/origin/*作为 remote.origin.fetch 配置变量的值意味着远程源中的每个分支(ref refs/heads/命名空间)被提取到refs/remotes/origin/命名空间中的分别命名的远程跟踪分支中,例如 origin 中的分支(即refs/heads/master ref)将被提取到 origin / master 远程跟踪分支(即{{1 })ref。 '+'前缀意味着即使在非快进的情况下fetch也会成功,这意味着当远程分支被重新引导或重绕(在过去重置为某个状态)或以其他方式修改时。

旁注: 您可能希望使用更高级别的git remote命令来管理远程存储库并获取更新。

答案 2 :(得分:4)

请注意,Git的主要维护者现在(Git 2.1,2014年8月)为git fetch添加了这个解释:
commit fcb14b0Junio C Hamano (gitster)

配置远程跟踪分支

  

您经常通过定期重复从中获取相同的远程存储库。为了跟踪此类远程存储库的进度,git fetch允许您配置remote.<repository>.fetch配置变量。

     

通常这样的变量可能如下所示:

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

此配置以两种方式使用:

     
      
  • 运行git fetch时未指定要在命令行上获取的分支和/或标记,例如git fetch origingit fetchremote.<repository>.fetch值用作 refspecs ---它们指定要获取的引用数据以及要更新的本地引用
      上面的示例将获取origin中存在的所有分支(即与值的左侧匹配的任何ref,refs/heads/*)并更新{{1}中相应的远程跟踪分支等级。

  •   
  • 使用显式分支和/或标记运行refs/remotes/origin/*以在命令行上获取时,例如git fetch,命令行中给出的git fetch origin master确定要获取的内容(例如,<refspec>在示例中,这是master的简写,其中turn意味着“获取'master:'分支但我没有明确说明要从命令行”更新它的远程跟踪分支“,并且示例命令将仅提取 'master'分支。
      master值确定更新哪个远程跟踪分支(如果有)   以这种方式使用时,remote.<repository>.fetch值对决定获取的内容没有任何影响(即,当命令行列出refspecs时,这些值不用作refspecs);它们仅用于决定 where 通过充当映射来存储被提取的引用。

  •   

答案 3 :(得分:2)

另请注意,使用Git 2.5+(2015年第2季度),git merge FETCH_HEAD可以合并多个git fetch&#39>

2015年3月26日commit d45366eJunio C Hamano (gitster) (由Junio C Hamano -- gitster --合并于commit bcd1ecd,2015年5月19日)

  

&#34; git merge FETCH_HEAD&#34;得知前一个&#34; git fetch&#34;可能是创建一个八达通合并,即记录多个未标记为&#34的分支;不合并&#34;;
  这使我们失去了旧式的调用&#34; git merge <msg> HEAD $commits...&#34;在实施&#34; git pull&#34;脚本;现在可以弃用旧样式语法。

git merge doc现在提到:

  

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

Git 2.13(2017年第二季度)正式退出git merge的旧语法 请commit b439165Junio C Hamano (gitster)(2015年3月26日) Junio C Hamano -- gitster --于2017年3月30日commit 1fdbfc4合并)

  

merge:drop&#39; git merge <message> HEAD <commit>&#39;语法

     

停止支持&#34; git merge <message> HEAD <commit>&#34;语法有   自2007年10月以来已弃用,并从v2.5.0开始发出弃用警告消息。

这意味着警告信息旧式&#34; 'git merge <msg> HEAD <commit>' is deprecated.&#34;不再是。