git fetch真的有用吗?

时间:2014-12-11 18:54:34

标签: git merge fetch

现在我想合并一个远程分支,将其命名为origin/branch1,与我的本地分支branch1合并,因为我的合作伙伴在我们上次合并后将一个新的提交推送到远程的branch1,我没有&# 39;自上次提交以来已提交,并希望从此提交获得更新。我使用了以下命令:

$ git fetch origin branch1
Compressing...
*branch branch1 ->FETCH_HEAD
$ git merge origin/branch1
Already up-to-date

那不是我的意图。在做这件事之前我的想法是使用fetch来获取我的合作伙伴添加的内容并使远程分支origin/branch1更新。然而,"已经是最新的"意味着我无法在我的本地分支1获取更新。然后我通过

检查了origin/branch1的sha1值
$ git ls-remote origin

发现它在我们上次合并后保留了旧提交的陈旧值。它告诉git fetch origin branch1无法更新origin/branch1。我做了另一个实验,我的合作伙伴创建了另一个名为" branch2"在他身边,并将branch2中的提交推送到远程源。然后我还是用了

$ git fetch origin branch2
Compressing...
$ git merge origin/branch2
No branch named "origin/branch2"

"压缩"告诉我第一个命令成功地在branch2中下载了一些东西,然而,第二个命令告诉我没有名为origin / branch2的分支!因此,我得出结论,git fetch origin branchname本地也不能更新origin/branchname,如果它不存在,也不能创建远程分支。

git fetch origin branch#替换为git fetch origin后,所有git merge都按预期工作。

但是,我经常看到

的组合
$ git fetch remote branch-name
$ git merge remote/branch-name

所以我的问题是git fetch remotegit fetch remote branch-name之间有什么区别?在什么条件下,我可以通过这种组合让它按照我的意愿行事?

2 个答案:

答案 0 :(得分:3)

如果您需要知道git fetch正在做什么或任何其他git命令,只需在其前面添加GIT_TRACE=1,这样它就会为您提供跟踪输出以及任何其他命令被调用,例如

$ GIT_TRACE=1 git fetch origin master
03:08:15.704945 git.c:348               trace: built-in: git 'fetch' 'origin' 'master'
03:08:15.706183 run-command.c:347       trace: run_command: 'ssh' 'git@github.com' 'git-upload-pack '\''FOO/BAR.git'\'''
03:08:16.006394 run-command.c:347       trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet'
03:08:16.013096 run-command.c:347       trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all'
03:08:16.013625 exec_cmd.c:129          trace: exec: 'git' 'rev-list' '--objects' '--stdin' '--not' '--all'
03:08:16.016617 git.c:348               trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all'
From github.com:FOO/BAR
 * branch            master     -> FETCH_HEAD
03:08:16.153070 run-command.c:347       trace: run_command: 'gc' '--auto'
03:08:16.153748 exec_cmd.c:129          trace: exec: 'git' 'gc' '--auto'
03:08:16.157704 git.c:348               trace: built-in: git 'gc' '--auto'

基本上是对远程主机执行ssh,运行git-upload-pack,它将打包回来的对象发送回git-fetch-pack,从另一个存储库接收丢失的对象。

man git-upload-pack我们可以阅读:

  

git fetch-pack调用,了解对方遗失的对象,并在打包后发送。

man git-fetch-pack我们可以阅读:

  

在可能的远程存储库上调用git-upload-pack并要求它发送此存储库中缺少的对象,以更新指定的头。通过扫描本地引用/层次结构并发送到另一端运行的git-upload-pack,可以找到本地可用的提交列表。

要回答这个问题,git fetch remotegit fetch remote branch-name之间的区别在于,当您未指定<refspec>参数(例如分支)时,它会获取所有分支和/或标签(参考:git ls-refs)来自一个或多个其他存储库以及完成其历史记录所需的对象。默认情况下,只下载被提取的对象可以访问的标记(例如,您最终只会使用指向您感兴趣的分支的标记)。

当您使用显式分支和/或标记运行时,git首先确定需要提取的内容,然后仅获取相关的引用(分支或标记)。例如。 git fetch origin master将只获取主分支。

答案 1 :(得分:0)

  

运行git-upload-pack,将打包的对象发送回git-fetch-pack,后者从另一个存储库接收丢失的对象。

您可以在Git 2.19(第3季度)上看到有关git fetch-pack的更多信息,因为过去看到看到带注释的标记指向提交以外的对象时,“ git fetch-pack --all”通常会不必要地失败。

请参见commit c12c9dfKirill Smelkov (navytux)(2018年6月13日)。
帮助者:Junio C Hamano (gitster)
请参见commit e9502c0Jeff King (peff)(2018年6月11日)。
帮助者:Junio C Hamano (gitster)
(由Junio C Hamano -- gitster --commit 0079732中合并,2018年6月28日)

  

Fetch-pack --all因中的异常标签而损坏   5f0fc64fetch-pack:消除虚假错误消息,2012-09-09,Git v1.8.0),   并且仅在e9502c0中得到了修复(提取包:请勿尝试提取   --all删除值,2018-06-11)。

     

fetch-pack:请勿尝试使用--all

获取果皮值      

当“ fetch-pack --all”在遥控器上看到 tag-to-blob 时,它将尝试同时获取标签本身(“ refs / tags / foo”)和剥离的值远程广告(“ refs/tags/foo^{}”)。
  要求后者指向的对象可能导致upload-pack抱怨“不是我们的引用”,因为它不会用OUR_REF标记去皮的对象(除非它们被OUR_REF标记)。   在其他裁判的顶端)。

     

可以说upload-pack 应该标记那些被剥皮的物体。但这是过去从未有过的,因为客户通常只会索要标签并期望剥皮   价值。
  这就是“ git fetch”以及旧版本“ fetch-pack --all”的工作方式。

     

Let's explicitly test all relevant cases with 4 tag objects指向

     
      
  • 1)斑点
  •   
  • 2)一棵树
  •   
  • 3)提交,然后
  •   
  • 4)另一个标签对象。
  •   
     

所引用的标记对象本身是从常规refs/tags/*下引用的   命名空间。

     

在e9502c0(Git 2.19)之前fetch-pack --all失败,例如这样:

    .../git/t/trash directory.t5500-fetch-pack/fetchall$ git ls-remote ..
    44085874...        HEAD
    ...
    bc4e9e1f...        refs/tags/tag-to-blob
    038f48ad...        refs/tags/tag-to-blob^{} # peeled
    520db1f5...        refs/tags/tag-to-tree
    7395c100...        refs/tags/tag-to-tree^{} # peeled

    .../git/t/trash directory.t5500-fetch-pack/fetchall$ git fetch-pack --all ..
    fatal: A git upload-pack: not our ref 038f48ad...
    fatal: The remote end hung up unexpectedly