git fetch究竟做了什么? [英] What does git fetch really do?

查看:1539
本文介绍了git fetch究竟做了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我想合并一个远程分支,将它命名为 origin / branch1 ,并与我的本地分支 branch1 ,因为我的合作伙伴在我们上次合并后在远程将一个新的提交推送到了branch1,并且自他上次提交以来我没有提交并且想要从此提交获取更新。我使用了下面的命令:
$ b $ pre $ git fetch origin branch1
压缩...
* branch branch1 - > FETCH_HEAD
$ git merge origin / branch1
已经是最新的



这不是我想要的。这样做之前我的想法是使用fetch获取我的合作伙伴添加的内容,并使远程分支 origin / branch1 得到更新。但是,已经最新意味着我无法获得本地分支中的更新1。然后,我通过

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

,发现它在上次合并后保持旧提交的陈旧值。它告诉 git fetch origin origin branch1 不能更新 origin / branch1 。我做了另一个实验,我的合作伙伴在他的身边创建了另一个名为branch2的分支,并将分支2中的提交推送到远程原点。然后,我仍然使用

  $ git fetch origin branch2 
压缩...
$ git merge origin / branch2
没有分支名为origin / branch2

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



当我用 git替换 git fetch origin branch#后所有的 git merge s按照我的预期工作。



然而,我经常看到

  $ git fetch远程分支名称
$ 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.01 3625 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'
从github.com:FOO/BAR
*分支大师 - > 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 ,它接收来自另一个存储库的缺少对象。
$ b

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


调用git fetch-pack

$ b


$ b


调用> git-upload-pack 在一个可能的远程仓库中,并要求它发送这个仓库中缺少的对象,以便更新被命名的头。本地可用的提交列表通过扫描本地refs / hierarchy发现,并发送到另一端运行的 git-upload-pack







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

和当你使用明确的分支和/或标签运行时,git首先确定需要获取什么,然后只获取相关的参考(分支或标签)。例如。 git fetch origin master 将仅提取master分支。


Now I want to merge a remote branch, naming it origin/branch1, with my local branch branch1, as my partner pushed a new commit to branch1 on remote after our last merge, and I haven't committed since his last commit and want to get update from this commit. I used the following commands:

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

That was not what I intended. What was in my mind before doing this was using fetch to get what my partner added and made the remote branch origin/branch1 being updated. However, the "Already up-to-date" means I failed to get the updates in my local branch1. Then I checked the sha1 value of origin/branch1 by

$ git ls-remote origin

and found that it kept the stale value of old commit after we merged last time. It tells that the git fetch origin branch1 cannot update origin/branch1. I did another experiment, where my partner created another branch named "branch2" in his side and pushed a commit in branch2 to the remote origin. Then I still used

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

The "Compressing" told me that the first command downloaded something in branch2 in origin successfully, however, the second command told me that there was no branch named origin/branch2! Thus I concluded that neither could git fetch origin branchname update origin/branchname locally, nor could it create a remote branch if it doesn't exist.

After I replace git fetch origin branch# with git fetch origin, all the git merges worked as I expected.

However, I often see the combination of

$ git fetch remote branch-name
$ git merge remote/branch-name

So my question is what is the difference between git fetch remote and git fetch remote branch-name? And in what conditions could I succeed in letting it work as my wish by this combination?

解决方案

If you need to know what exactly git fetch is doing or any other git command, just prefix it with GIT_TRACE=1, so it'll give you trace output with any other commands which are invoked, e.g.

$ 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'

which basically is doing ssh to the remote host, running git-upload-pack which send objects packed back to git-fetch-pack which receives missing objects from another repository.

In man git-upload-pack we can read:

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

And in man git-fetch-pack we can read:

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.


To answer the question, the difference between git fetch remote and git fetch remote branch-name, is that when you don't specify <refspec> parameter (such as branch), it fetches all branches and/or tags (refs, see: git ls-refs) from one or more other repositories along with the objects necessary to complete their histories. By default only tags which are reachable by the objects that are fetched are downloaded (e.g. you end up only with tags that point at branches that you are interested in).

And when you run with explicit branches and/or tags, git first determines what needs to be fetched, then getting only the relevant refs (branches or tags). E.g. git fetch origin master will fetch only the master branch.

这篇关于git fetch究竟做了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆