现在我想 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 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'
这基本上是对远程主机执行 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 togit-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/