'git pull' 和'git fetch' 有什么区别?

主持人注意:鉴于此问题已经发布了67 个答案 (其中一些已删除),请在发布另一个问题之前考虑您是否正在贡献新内容

git pullgit fetch什么区别?

答案

用最简单的术语来说, git pull进行git fetch然后进行git merge

您可以随时执行git fetch来更新refs/remotes/<remote>/下的远程跟踪分支。

此操作绝不会更改refs/heads下您自己的任何本地分支,并且可以安全地执行而不更改您的工作副本。我什至听说有人在后台执行 cron 作业中定期运行git fetch (尽管我不建议这样做)。

git pull是您要执行的操作,以使本地分支的远程版本保持最新,同时还更新其他远程跟踪分支。

Git 文档– git pull

在默认模式下, git pullgit fetch简写,其次是git merge FETCH_HEAD

  • 当您使用pull ,Git 会尝试自动为您完成工作。 它是上下文相关的 ,因此 Git 会将所有提交的提交合并到您当前正在使用的分支中pull 自动合并提交,而无需您先对其进行审查 。如果您不严密管理分支机构,则可能会遇到频繁的冲突。

  • fetch ,Git 会从目标分支中收集当前分支中不存在的所有提交,并将它们存储在本地存储库中 。但是, 它不会将它们与当前分支合并 。如果您需要使存储库保持最新状态,但是正在进行某些可能会在更新文件时中断的工作,则此功能特别有用。要将提交集成到您的 master 分支中,请使用merge

将 git 的设计原理与更传统的源代码控制工具(如 SVN)的原理进行对比很重要。

Subversion 是使用客户端 / 服务器模型设计和构建的。服务器是一个单一的存储库,几个客户端可以从服务器获取代码,对其进行处理,然后将其提交回服务器。假定客户端在需要执行操作时可以始终与服务器联系。

Git 旨在支持一种更加分布式的模型,而无需一个中央存储库(尽管您当然可以使用一个存储库)。还设计了 git,以便客户端和 “服务器” 不需要同时处于联机状态。 Git 的设计目的是使链接不可靠的人甚至可以通过电子邮件交换代码。可以完全断开连接并刻录 CD 以通过 git 交换代码。

为了支持该模型,git 会使用您的代码维护一个本地存储库,以及一个附加的本地存储库,该本地存储库反映了远程存储库的状态。通过在本地保留远程存储库的副本,即使无法访问远程存储库,git 也可以找出所需的更改。稍后,当您需要将更改发送给其他人时,git 可以将它们作为一组更改从远程存储库已知的时间点进行传输。

  • git fetch是说 “使远程存储库的本地副本最新” 的命令。

  • git pull说 “将远程存储库中的更改带到我自己保存代码的位置。”

通常, git pull通过执行git fetch来使远程存储库的本地副本保持最新,然后将更改合并到您自己的代码存储库以及可能的工作副本中来实现。

要记住的是,您的工作站上通常至少有三个项目的副本 。一个副本是您自己的存储库,具有自己的提交历史记录。第二个副本是您正在编辑和构建的工作副本。第三个副本是远程存储库的本地 “缓存” 副本。

这是奥利弗 · 斯蒂尔Oliver Steele)关于所有这些如何组合的图像

在此处输入图片说明

如果有足够的兴趣,我想我可以更新图像以添加git clonegit merge ...

git fetch一个用例是,以下内容将告诉您自上次拉取以来远程分支中的任何更改...,因此您可以在执行实际拉取之前进行检查,这可能会更改当前分支和工作副本中的文件。

git fetch
git diff ...origin

有关 diff 命令中的双点和三点语法,请参见: https ://git-scm.com/docs/git-diff

我花了一点时间来了解有什么区别,但这只是一个简单的解释。本地master中的master是分支。

克隆存储库时,会将整个存储库提取到本地主机。这意味着到那时您有一个指向HEAD的原点 / 主指针和指向同一HEAD主指针。

当您开始工作并提交时,您可以将主指针前进到HEAD + 您的提交。但是原始 / 主指针仍然指向克隆时的状态。

因此区别将是:

  • 如果执行git fetch ,它将仅获取远程存储库( GitHub )中的所有更改,并将 origin / master 指针移至HEAD 。同时,您的本地分支主管将继续指向其所在位置。
  • 如果您执行git pull ,它将基本上进行提取(如前所述)并将所有新更改合并到您的 master 分支中,并将指针移至HEAD

有时视觉表示会有所帮助。

在此处输入图片说明

简要地

git fetchpull类似,但不会合并。即,它获取远程更新( refsobjects ),但是本地保持不变(即, origin/master已更新,但master保持不变)。

git pull从远程下拉并立即合并。

更多

git clone克隆一个仓库。

git rebase将当前分支中不在上游分支中的内容保存到临时区域。现在,您的分支与开始更改之前的分支相同。因此, git pull -rebase将拉下远程更改,倒回本地分支,在当前分支的顶部逐一重放git pull -rebase的更改,直到最新为止。

另外, git branch -a将向您确切显示所有分支 - 本地和远程的最新情况。

这篇博客文章很有用:

git pull,git fetch 和 git clone(以及 git rebase)之间的区别 - Mike Pearce

并涵盖了git pullgit fetchgit clonegit rebase

====

更新

我以为我会对此进行更新,以显示您实际上如何在实践中使用它。

  1. 从远程更新本地仓库(但不要合并):

    git fetch
  2. 下载更新后,让我们看一下区别:

    git diff master origin/master
  3. 如果您对这些更新感到满意,请合并:

    git pull

笔记:

在步骤 2:有关本地和远程之间差异的更多信息,请参见: 如何将本地 git 分支与其远程分支进行比较?

在第 3 步:在此处执行git rebase origin可能更准确(例如,在快速更改的仓库上)。参见@Justin Ohms的其他回答。

另请参阅: http : //longair.net/blog/2009/04/16/git-fetch-and-merge/

git-pull - Fetch from and merge with another repository or a local branch
SYNOPSIS

git pull   …
DESCRIPTION

Runs git-fetch with the given parameters, and calls git-merge to merge the 
retrieved head(s) into the current branch. With --rebase, calls git-rebase 
instead of git-merge.

Note that you can use . (current directory) as the <repository> to pull 
from the local repository — this is useful when merging local branches 
into the current branch.

Also note that options meant for git-pull itself and underlying git-merge 
must be given before the options meant for git-fetch.

如果您希望合并历史记录,那么您会选择拉扯;如果您只是 “想要编码解码器”,那么您会获取,因为有人在这里标记了一些文章。

您可以从远程存储库中获取内容,查看差异,然后进行合并。

这是一个名为origin的远程存储库和一个名为master的分支的示例,该分支跟踪远程分支的origin/master

git checkout master                                                  
git fetch                                        
git diff origin/master
git rebase origin master