现在我想合并一个远程分支,将它命名origin/branch1
为我的本地分支branch1
,因为我的合作伙伴在我们上次合并后向远程分支 1推送了一个新提交,并且自他上次提交以来我没有提交过,并希望从中获取更新犯罪。我使用了以下命令:
$ git fetch origin branch1
Compressing...
*branch branch1 ->FETCH_HEAD
$ git merge origin/branch1
Already up-to-date
Run Code Online (Sandbox Code Playgroud)
那不是我想要的。在这样做之前,我的想法是使用 fetch 来获取我的合作伙伴添加的内容并origin/branch1
更新远程分支。但是,“已经是最新的”意味着我无法在本地分支 1 中获取更新。然后我检查的SHA1值origin/branch1
由
$ git ls-remote origin
Run Code Online (Sandbox Code Playgroud)
发现在我们上次合并后它保留了旧提交的陈旧值。它告诉git fetch origin branch1
无法更新origin/branch1
。我做了另一个实验,我的伙伴在他身边创建了另一个名为“branch2”的分支,并将 branch2 中的提交推送到远程源。那我还是用
$ git fetch origin branch2
Compressing...
$ git merge origin/branch2
No branch named "origin/branch2"
Run Code Online (Sandbox Code Playgroud)
“压缩”告诉我第一个命令在 origin 中成功下载了 branch2 中的东西,但是,第二个命令告诉我没有名为 origin/branch2 的分支!因此我得出结论,既不能在本地git fetch origin branchname
更新origin/branchname
,也不能在不存在的情况下创建远程分支。
在我用 替换git fetch origin branch#
后git fetch origin
,所有的git merge
s 都按我的预期工作。
但是,我经常看到组合
$ git fetch remote branch-name
$ git merge remote/branch-name
Run Code Online (Sandbox Code Playgroud)
所以我的问题是git fetch remote
和之间有什么区别git fetch remote branch-name
?在什么条件下,我可以通过这种组合成功地让它如我所愿?
如果您需要知道究竟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'
Run Code Online (Sandbox Code Playgroud)
它基本上是对远程主机执行 ssh,运行git-upload-pack
它发送打包的git-fetch-pack
对象,然后从另一个存储库接收丢失的对象。
在man git-upload-pack
我们可以读到:
由 调用
git fetch-pack
,了解对方缺少哪些对象,打包后发送。
而在man git-fetch-pack
我们可以看到:
在
git-upload-pack
可能的远程存储库上调用并要求它发送此存储库中缺少的对象,以更新命名的头。本地可用的提交列表是通过扫描本地 refs/ 层次结构找到的,并发送到git-upload-pack
另一端运行。
要回答这个问题,之间的区别git fetch remote
和git fetch remote branch-name
,就是当你不指定<refspec>
参数(如分公司),它获取所有分支机构和/或标签(参见:git ls-refs
)从一个或多个其他存储库连同所需物品来完成他们的历史。默认情况下,仅下载可通过获取的对象访问的标签(例如,您最终只会获得指向您感兴趣的分支的标签)。
当您使用显式分支和/或标签运行时,git 首先确定需要获取的内容,然后仅获取相关的 refs(分支或标签)。例如git fetch origin master
将只获取主分支。