git - git fetch 到底做了什么?

标签 git merge fetch

现在我想 merge 一个远程分支,将其命名为 origin/branch1,与我的本地分支 branch1,因为我的合作伙伴在之后将新提交推送到远程的 branch1我们上次 merge ,自从他上次提交后我还没有提交,想从这次提交中获得更新。我使用了以下命令:

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

那不是我想要的。在做这件事之前我的想法是使用 fetch 来获取我的合作伙伴添加的内容并使远程分支 origin/branch1 被更新。但是,“Already up-to-date”表示我未能在本地 branch1 中获取更新。然后我通过

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

发现在我们上次 merge 后,它保留了旧提交的陈旧值。它表明 git fetch origin branch1 无法更新 origin/branch1。我做了另一个实验,我的搭档在他身边创建了另一个名为“branch2”的分支,并将 branch2 中的提交推送到远程源。那我还是用

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

“压缩”告诉我第一个命令在 origin 的 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 有什么区别?在什么情况下我可以通过这种组合成功让它如我所愿?

最佳答案

如果你需要知道到底是什么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我们可以阅读:

Invoked by git fetch-pack, learns what objects the other side is missing, and sends them after packing.

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

Invokes git-upload-pack on a possibly remote repository and asks it to send objects missing from this repository, to update the named heads. The list of commits available locally is found out by scanning the local refs/ hierarchy and sent to git-upload-pack running on the other end.


为了回答这个问题,git fetch remote 之间的区别和 git fetch remote branch-name , 是当你不指定 <refspec> 时参数(例如分支),它从一个或多个其他存储库中获取所有分支和/或标签(引用文献,参见:git ls-refs)以及完成其历史所需的对象。默认情况下,只有被获取的对象可以到达的标签才会被下载(例如,您最终只会得到指向您感兴趣的分支的标签)。

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

关于git - git fetch 到底做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27430312/

相关文章:

git - 使用 Git cvsimport 的加速和注意事项?

git - 在 Git 中添加要跟踪的目录;错误信息;添加的大小限制?

svn - 有人可以解释一下 Git 中使用的内容跟踪和其他 SCM 中使用的文件跟踪之间的区别吗

git - 如果两个结构相同的 git repos 从来没有任何共同的历史记录,它们可以 merge 吗?

version-control - 人们如何管理对存储在多个 (Mercurial) 存储库中的公共(public)库文件的更改?

merge - "use ' hg update' 以获得一致的结帐是什么意思?

git - Git merge 如何处理同时提交?

javascript - 抛出错误时,React-native fetch 无法设置状态

javascript - $.when 使用多个 fetch() 会破坏 Backbone 模型

javascript - ASP.NET Core 获取 POST FormData() application/x-www-form-urlencoded