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


11908

git pull和之间有什么区别git fetch


364
我发现这篇关于git fetch和git pull的书面文章值得一读:longair.net/blog/2009/04/16/git-fetch-and-merge
Marcos Oliveira 2010年

50
我们的替代方法已成为git fetch; git reset --hard origin/master我们工作流程的一部分。它吹走了本地更改,使您与最新的BUT保持同步,从而确保您不只是在当前更改的基础上引入新的更改并弄乱。我们已经使用了一段时间,实际上它在实践中感觉要安全得多。只需确保先添加/提交/存储任何正在进行的工作!
迈克尔·杜兰特

25
确保您知道如何正确使用git stash。如果您要询问“拉动”和“取回”,那么也许“
储藏

35
来自Mercurial的许多人继续使用“ git pull”,认为这等同于“ hg pull”。不是。Git等同于“ hg pull”是“ git fetch”。
Serge Shultz 2015年

7
git fetch命令使用分支获取更新的代码,并且还将在您的本地获取新添加的分支,git pull命令仅获取当前分支的更新代码
Kartik Patel

Answers:


9911

用最简单的话来说,git pull请先git fetch跟一个git merge

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

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

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

Git文档– git pull

在其默认模式下,git pull是的缩写,git fetch后跟git merge FETCH_HEAD


326
“要做一个“ git pull”以使您的存储库保持最新状态” <-难道不是通过获取来完成存储库更新吗?您不是说它使本地分支机构与远程分支机构保持最新状态吗?合并:将远程分支与这些分支的本地副本合并,或者它在此处究竟合并了什么?
艾伯特2009年

193
@阿尔伯特:是的,这句话很奇怪。 git pull将始终合并到当前分支中。因此,您选择要从中拉出的分支,然后将其拉入当前分支。from分支可以是本地的也可以是远程的;它甚至可以是未注册的远程分支git remote(这意味着您在git pull命令行中传递了URL )。
直觉

128
@espertus:否。推送永远不会自动进行合并。希望用户进行拉动,在本地解决任何合并冲突,然后再推回远程。
Greg Hewgill 2011年

32
如果我在/home/alice/git fetch /home/bob什么,应该将哪些参数传递给后续参数git merge
ripper234 2011年

105
给学习Git的人们的注意:加号pull实际上无法模拟。我只是获取了一个更改,其中只有远程分支指针发生更改,并且拒绝执行任何操作。,另一方面,快进我的跟踪分支。fetchmergemergepull
罗曼·斯塔科夫

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

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


33
同意,很棒的评论。这就是为什么我讨厌git pull。什么时候让修订工具为您进行代码编辑有意义?合并两个文件不是在做什么吗?如果这两个编辑在文件中物理上分开但逻辑上不一致,该怎么办?
李·迪克森

126
@elexhobby卖空交易,git fetch仅更新您的.git/目录(又称本地存储库),而无其他内容.git/(又称工作树)。它不会更改您的本地分支机构,也不会发生master任何变化。虽然有感remotes/origin/master(请参阅参考资料git branch -avv)。如果您有更多遥控器,请尝试git remote update。这是git fetch所有命令中的一个遥控器。
蒂诺

24
@Tino你的真的是最重要的一点。人们可能不知道“远程”分支实际上是作为一堆哈希存储在中的.git/refs/remotes/origin/
克里斯(Chris

13
提取时,Git会从目标分支中收集当前分支中不存在的所有提交,并将其存储在本地存储库中 -我如何查看从远程带来的内容以及如何将其合并到本地分支中?
2014年

13
@Tino我仍然不明白的是...有什么意义?如果仅更新,为什么要使用提取.git?预期的好处是什么?在那之后我应该做什么?
BadHorsie

1209

必须将git的设计理念与更传统的源代码控制工具(如SVN)的理念进行对比。

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

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

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

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

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

通常git pull,通过执行以下操作git fetch来做到这一点:更新远程存储库的本地副本,然后将更改合并到您自己的代码存储库中,并可能合并到您的工作副本中。

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


75
从技术上讲,本地和远程存储库实际上是一个相同的库。在Git中,存储库是指向其父母的提交的DAG。从技术上讲,分支只是有意义的提交名称。本地分支和远程分支之间的唯一区别是,远程分支remoteName/ 从头开始就以Git开头是一个很好的读物。一旦您了解了Git的工作原理-它非常简单,实际上-一切都有意义。
Emil Lundberg

13
非常感谢您的解释。直到现在我才真正了解Git的设计,因此您不必具有中央存储库。每个人在描述Git时总是说“ DVCS”,但是作为一个相对较新的程序员,这对我而言毫无意义。我从未见过 CVCS,并且在与其他人(例如Github)合作时也从未与中央远程存储库打过交道,所以直到现在我仍未弄清Git的特殊之处。
布莱恩·彼得森

7
因此,基于此,为什么不建议使用cron作业进行git-fetch?始终在本地计算机上保留正在使用的遥控器的副本似乎是个好主意。实际上,我想编写一个脚本来检查过去24小时内是否更新了遥控器,并使用udev挂钩将其链接以进行互联网连接。
Brian Peterson

23
进行cron工作不是一个好主意的原因之一:通常在处理新票证或更新分支机构时,我喜欢看到所做的更改。如果在获取期间未进行更改,我会更自信地问我的程序员“'你推动了吗?'。自上次获取以来,我还了解了存储库中有多少“搅动”。这也有助于使我了解当前对此存储库进行的更改的数量和速度。
Michael Durrant

5
@Nabheet Thing是,Git是面向内容的。它仅存储一次数据,并多次指向它。这就是为什么在Git中,即使在原始文件上进行多次提交也不会对存储库的大小产生太大影响,因为大多数对象都是相同的。
cst1992 '16

886

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

在此处输入图片说明

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


154
git clone和更新的图片git merge将非常有帮助!
MEMark 2015年

19
是的,请补充git merge-它应该清楚地表明,merge单独调用与调用不同,pull因为pull仅是从远程合并,并且忽略了在本地分支(跟踪正在从中拉出的远程分支)中的本地提交。
JustAMartin

12
一张图片胜过千言万语!具有克隆和合并数据流的更新映像是否已准备就绪?除了图中已有的数据以外,还有其他数据流吗?
shikhanshu 2015年

10
@Contango,请添加克隆并合并。对于像我这样的新手会有所帮助。
出租

11
有两个图表显示了th3sly和thedarkpassenger在其他答案中的克隆和合并(如下)。
intotecho

487

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

git fetch
git diff ...origin

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


9
为什么不git diff ..origin呢?
埃里克·卡普伦

3
git diff origin和git diff ..origin似乎有效,但这种怪异的东西不起作用
Marc

19
@Compustretch不应有空格。 git diff ...origin等价于git diff $(git-merge-base HEAD origin) origin(请参阅kernel.org/pub/software/scm/git/docs/git-diff.html#_descriptiongit diff [--options] <commit>...<commit> [--] [<path>…]小节),它不同于; 从概念上讲是从当前分支分支以来所做的更改,同时还包括从当前分支分支以来在当前分支上所做的更改的相反内容。git diff origingit diff ...originoriginorigingit diff originorigin
Max Nanasy

2
没有一个..命令对我有用(在Windows上),但是git diff origin/master有效,如下所述
Brian Burns

同样在OSX上使用git 2.0.0。这些命令均无效。他们已经过时了吗?
K.-Michael Aye 2014年

372

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

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

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

因此区别将是:

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

14
origin / master是本地分支,是原始副本的副本。提取时,将更新本地:/ origin / master。一旦真正弄清git中的所有内容都是分支,这就很有意义了,并且是维护不同变更集,快速建立本地分支,合并和重新设置的一种非常有效的方法,并且通常可以从便宜的分支中获得很多价值模型。
cam8001 2013年

3
仍然令人困惑。我以为git fetch是从字面上将远程存储库上的更改下载到本地存储库中,但不要提交它们-即,仍然需要将它们添加/提交到本地存储库中。
krb686

3
仅从远程/来源(github)提取到您的本地来源。但是它不会将其合并到您的实际工作文件中。如果您执行拉动操作,它将提取并合并到您当前的工作文件中
Gerardo 2015年

223

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

在此处输入图片说明


17
我认为图片必须显示它也影响本地回购。就是说,Git pull是影响本地回购和工作副本的组合。现在看来,它只是影响工作副本。
nonopolarity

10
@太极者无极而生同意-这个图像是相当误导性,因为它使得它看起来就像git pull跳跃的获取,这当然是不准确的。
forresthopkinsa

8
“本地存储库”和“工作副本”之间有什么区别?它们都不都是本地计算机吗?
theITvideos

1
那么git fetch的用途是什么?如何查看本地存储库和工作副本有什么区别?
维卡什

1
@theITvideos不,不是。提交时,本地代码存储库是代码从工作存储库到达的位置(来自工作存储库)。(当您按下时,它将转到远程存储库)。
维卡什

218

简要地

git fetchpull但不合并。即它获取远程更新(refsobjects),但是您的本地保持不变(即origin/master得到更新但master保持不变)。

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

更多

git clone 克隆一个仓库。

git 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/


1
在我看来,如果有人只希望本地代码反映“提示”,就应该使用git clone。我在引号中加了小费,因为我认为这意味着无论是高手还是从github.com上有人“以zip下载”
Chris K

3
如果您对git fetch后的更改不满意怎么办?接下来做什么?
Kugutsumen 2015年

您在rebase上发表的文章正是我想要的。将所有内容清零,从远程进行更新,然后在工作时发生的先前提交之上重放更改的整个想法。假设它是正确的完美解释。;)
coblr

178
git-pull-从另一个存储库或本地分支获取并合并
概要

git pull…
描述

使用给定的参数运行git-fetch,并调用git-merge合并 
检索到当前分支的头。使用--rebase,调用git-rebase
而不是git-merge。

请注意,您可以使用。(当前目录)作为<repository>拉
从本地存储库中获取-合并本地分支机构时,这很有用 
进入当前分支。

还要注意,这些选项用于git-pull本身和底层git-merge 
必须在用于git-fetch的选项之前给出。

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


5
非常有趣,但是我看不到您想要“仅代码”的用例。等等,当您提取代码时会发生什么?它被擦除了吗?远程更改会发生什么?如果不合并,如何在不删除代码的情况下将其放入回购中?
e-satis

11
@ e-satis:远程分支也存储在本地计算机上。因此,当您执行git fetch此操作时,将从存储库中获取更改并更新您的本地远程分支。它不会影响跟踪本地远程分支的本地分支,因此也不会影响您的工作副本。现在,当您执行操作时merge,它将把获取的更改与本地分支合并。
jeffreyveon 2011年

fetch命令的一个简单用例:执行涉及其他人最近提交的耗时的操作,例如合并或代码检查,仅访问最新的本地存储库而无需网络连接,因为您以前使用fetch下载快速所需的一切(例如,当您访问其他开发人员并连接到其他存储库的网络时)。pull命令将下载相同的提交,但是执行合并将是不可取的。
洛伦佐·加蒂

163

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

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

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

35
因为您已经获取了更改,所以您可能要跳过拉操作,而只是做“ git rebase origin”作为最后一步。原因是自从您进行获取以来,某人可能已经在一段时间内推送了更改,而您对差异进行审核时并没有获取这些更改。
贾斯汀·欧姆斯

158

短期和简单的答案是,git pull仅仅是git fetch其次git merge

请注意,无论您是否喜欢它git pull都会自动合并,这一点非常重要。当然,这可能会导致合并冲突。假设您的遥控器是origin,分支机构是master。如果git diff origin/master在拉之前,您应该对潜在的合并冲突有所了解,并可以相应地准备本地分支。

除了拉动和推入之外,某些工作流程还涉及git rebase,例如本工作流程,我从链接文章中对此进行解释:

git pull origin master
git checkout foo-branch
git rebase master
git push origin foo-branch

如果您发现自己处于这种情况下,您可能会很想尝试git pull --rebase。除非您真的非常了解自己在做什么,否则我建议您不要这样做。此警告来自的man页面git-pull,版本2.3.5

这是潜在的危险操作模式。它会重写历史记录,当您已经发布该历史记录时,这并不是一个好兆头。除非您已仔细阅读git-rebase(1),否则不要使用此选项。


2
@JustinOhms如果git pull --rebase在给定情况下不是正确的事情,那么分两步完成是否正确?如果这是正确的事情,那么分两步进行操作还有什么好处?
卡兹(Kaz)

@Kaz-因为变基不是自动的。首先获取更改,使您可以作出判断。它无法解决您已经推送的重新基准化历史记录的问题。它可以让您查看是否可以安全地重新存储尚未推送的更改。
贾斯汀·欧姆

2
@JustinOhms您如何确定重新设置更改是否安全?我只是尝试git rebase,如果混乱了就回溯,在这种情况下,我不妨做git pull --rebase。但是,也许您还有其他方法?
卡兹(Kaz)

3
@KaZ gitk允许您直观地查看分支结构。它将显示您相对于所获取内容的本地头,远程控制器和分支结构的位置。这样,您可以确保您不对基于祖先的提取的更改进行重新基准化,该祖先位于已推送到远程对象的祖先之前。
贾斯汀·欧姆

rebase在尚未推送的本地分支上工作时使用。如果您正在远程存在的分支上工作,则rebase可能会导致一些令人讨厌的问题,因此您应该选择常规的merge
Justus Romijn 2014年

151

好的,这是有关git pull和的一些信息git fetch,因此您可以了解实际的区别...用简单的词来说,访存可获取最新数据,但不会更改代码,也不会弄乱您当前的本地分支代码,但会取get代码更改并将其合并到本地分支,继续阅读以获得有关每个分支的更多详细信息:

git获取

它将所有引用对象以及任何新分支下载到本地存储库中。

从一个或多个其他存储库中获取分支和/或标签(统称为“ refs”),以及完成其历史记录所需的对象。远程跟踪分支已更新(有关控制此行为的方法,请参见下面的说明)。

默认情况下,任何指向要获取的历史记录的标记也将被获取;效果是获取指向您感兴趣的分支的标签。可以使用--tags或--no-tags选项或通过配置remote..tagOpt来更改此默认行为。通过使用显式获取标签的refspec,您还可以获取不指向您感兴趣的分支的标签。

git fetch既可以从单个命名存储库或URL进行获取,也可以一次从多个存储库获取(如果给出)并且有一个远程目录。配置文件中的条目。(请参阅git-config 1)。

如果未指定任何远程,默认情况下将使用源远程,除非为当前分支配置了上游分支。

获取的ref的名称以及它们指向的对象名称将写入.git / FETCH_HEAD。脚本或其他git命令(例如git-pull)可以使用此信息。


git pull

它将更改从远程应用于本地的当前分支 ...

将更改从远程存储库合并到当前分支。在默认模式下,git pull是git fetch的简写,其次是git merge FETCH_HEAD。

更精确地讲,git pull使用给定的参数运行git fetch并调用git merge将检索到的分支头合并到当前分支中。使用--rebase,它将运行git rebase而不是git merge。

应该是传递给git-fetch 1的远程存储库的名称。可以命名任意远程引用(例如标签名称),甚至可以命名具有相应远程跟踪分支的引用集合(例如ref / head /:refs / remotes / origin /),但通常是名称远程存储库中的分支。

和的默认值是从git-branch --track设置的当前分支的“远程”和“合并”配置中读取的。


我还创建了视觉下面告诉你如何git fetchgit pull一起工作...

git pull和git fetch


9
如果您喜欢该图像,则请查看git备忘单,所有git命令的用法
汤姆(Tom)

3
克隆是否还会影响本地存储库(从远程复制所有历史记录)?
汤姆·洛雷多'18

135

在此处输入图片说明

这种交互式的图形表示形式对于理解git很有帮助:http : //ndpsoftware.com/git-cheatsheet.html

git fetch只需将更改从远程“下载”到本地存储库即可。git pull下载更改并将其合并到您的当前分支中。“在其默认模式下,git pull是的缩写,git fetch后跟git merge FETCH_HEAD。”


18
人们,请单击链接与不同的列进行交互。该备忘单是我所见过的最好的资源,可以充分理解每个命令之间的差异。
M. LuisaCarrión16年

该答案必须到顶部
Tessaracter19年

126

奖金:

说到上述答案中的“提取与提取”,我想分享一个有趣的技巧,

git pull --rebase

上面的命令是我的git一生中最有用的命令,它节省了很多时间。

在将新的提交推送到服务器之前,请尝试使用此命令,它将自动同步最新的服务器更改(通过访存+合并),并将您的提交放在git日志的顶部。无需担心手动拉/合并。

有关详细信息,请访问:http : //gitolite.com/git-pull--rebase


4
不错的提示,尽管值得向新的git用户提及重新设置修改提交哈希值的基础(我发现令人惊讶的是subversion)。
AlexMA'9

1
您能解释一下git pull和之间的区别git pull --rebase吗?
shaijut

2
请在上面的答案中查看有关此方法的严厉警告:stackoverflow.com/a/6011169/241244

118

我喜欢对情况有一些直观的了解,以掌握这些东西。也许其他开发人员也希望看到它,所以这是我的补充。我不确定这是否正确,如果发现任何错误,请发表评论。

                                         LOCAL SYSTEM
                  . =====================================================    
================= . =================  ===================  =============
REMOTE REPOSITORY . REMOTE REPOSITORY  LOCAL REPOSITORY     WORKING COPY
(ORIGIN)          . (CACHED)           
for example,      . mirror of the      
a github repo.    . remote repo
Can also be       .
multiple repo's   .
                  .
                  .
FETCH  *------------------>*
Your local cache of the remote is updated with the origin (or multiple
external sources, that is git's distributed nature)
                  .
PULL   *-------------------------------------------------------->*
changes are merged directly into your local copy. when conflicts occur, 
you are asked for decisions.
                  .
COMMIT            .                             *<---------------*
When coming from, for example, subversion, you might think that a commit
will update the origin. In git, a commit is only done to your local repo.
                  .
PUSH   *<---------------------------------------*
Synchronizes your changes back into the origin.

拥有远程镜像的一些主要优点是:

  • 性能(滚动所有提交和消息,而无需尝试通过网络进行压缩)
  • 关于您本地仓库状态的反馈(例如,我使用Atlassian的SourceTree,这将为我提供一个灯泡,指示相对于原产地,我是在前还是在后。该信息可以用GIT FETCH更新)。

git pull也不会执行合并,即一直进行到工作副本吗?
Kamiel Wanrooij 2014年

好的,是的,它将所有更改放入您的工作副本中,然后您可以将其自己提交到本地存储库中。我将更新视觉效果。
Justus Romijn 2014年

@JustusRomijn拉是否还会更新本地存储库?在原件和工作副本星号之间不应该有一个星号吗?
user764754 2015年

2
@ user764754拉动时,您的工作副本将获得更改(也可能需要解决一些冲突)。您仍然必须将其提交到本地存储库中。
Justus Romijn 2015年

@JustusRomijn:感谢您的说明。如果您可以通过说明诸如reset,cherry pick等操作对存储库状态的影响来使图更全面,那就太好了。
jith912

106

我也为此感到挣扎。实际上,我是通过Google搜索完全相同的问题来到这里的。读完所有这些答案后,我的脑海中终于有了一幅图画,我决定尝试着眼于2个存储库和1个沙箱的状态以及随着时间推移执行的操作,同时观察它们的版本。这就是我的想法。如果我在任何地方搞砸了,请纠正我。

三个回购协议:

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - fetch               -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     -                     -
- @ R01             -     - @ R01+              -     - @R01+               -
---------------------     -----------------------     -----------------------

三个回购

---------------------     -----------------------     -----------------------
- Remote Repo       -     - Remote Repo         -     - Remote Repo         -
-                   -     - gets pushed         -     -                     -
- @ R01             -     - @ R02               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Repo        -     - Local Repo          -     - Local Repo          -
- pull              -     -                     -     - pull                -
- @ R01             -     - @ R01               -     - @ R02               -
---------------------     -----------------------     -----------------------

---------------------     -----------------------     -----------------------
- Local Sandbox     -     - Local Sandbox       -     - Local Sandbox       -
- Checkout          -     - new work done       -     - merged with R02     -
- @ R01             -     - @ R01+              -     - @R02+               -
---------------------     -----------------------     -----------------------

这有助于我理解为什么获取非常重要。


读起来并不难:这些框代表回购的状态,在该行的第2行报告了操作之后,每一行的时间从左到右变化。标签R0n是git中的标签,带有+的标签尚未提交。Sanbox用于您的工作文件夹,不同于存储已提交内容的repo文件夹。
user1708042

96

GIT提取GIT拉之间的差异可以通过以下情形来解释: 请记住,图片说得比单词要响亮!,我提供了图片表示法)

让我们举个例子,您正在与团队成员一起进行项目。因此,他们将成为项目的一个主要分支,所有贡献者必须将其分叉到自己的本地存储库,然后在该本地分支上进行修改/添加模块,然后再推送回主要分支。

因此, 当您在本地存储库中分叉主项目时,这两个分支的初始状态将如下所示-(AB并且C该项目的模块已经完成)

在此处输入图片说明

现在,你已经开始了新的模块(假设上工作D),当你完成D你想要它推到主分支模块,但与此同时发生的事情是你的一个队友已经制定了新的模块EF并修改C
因此,现在发生的事情是您的本地存储库缺少项目的原始进度,因此将更改推到主分支可能会导致冲突,并可能导致模块D故障。

在此处输入图片说明

为避免此类问题并与项目的原始进度并行进行,它们有两种方法:

1. Git Fetch-将下载对Origin / main分支项目所做的所有更改,这些更改在您的本地分支中不存在。并且将等待Git Merge命令将已获取的更改应用于您的存储库或分支。

在此处输入图片说明

因此,现在您可以在将文件合并到存储库之前仔细监视文件。而且D由于Modified ,您还可以根据需要进行修改C

在此处输入图片说明

2. Git Pull-这会用origin / main分支更新您的本地分支,即,实际上它是Git Fetch和Git的合并一个接一个的组合。 但这可能会导致发生冲突,因此建议在干净副本中使用Git Pull。

在此处输入图片说明


1
如果您可以将“主分支”更改为“远程回购”,那将是一个很好的答案。
Qibiron谁

87

我们只是说:

git pull == git fetch + git merge

如果运行git pull,则无需将数据合并到本地。如果运行git fetch,则意味着必须运行git merge才能将最新代码获取到本地计算机。否则,如果不合并,将不会更改本地机器代码。

因此,在Git Gui中,当您提取数据时,必须合并数据。提取本身不会在您的本地更改代码。您可以通过一次获取并查看来检查更新代码时的代码。不会更改的代码。然后合并...您将看到更改的代码。


3
我宁愿说git pull == git fetch + git merge:)
melvynkim 2013年

2
但是git pull --rebase = git fetch + git rebase
Tino 2013年

83

git fetch将代码从远程服务器下拉到本地存储库中的跟踪分支。如果你的遥控器被命名为origin(默认值),那么这些分支会内origin/,例如origin/masterorigin/mybranch-123等等。这些都不是你当前的分支,它们是本地从服务器这些分支的副本。

git pull会执行操作,git fetch但是还会将代码从跟踪分支合并到该分支的当前本地版本中。如果您尚未准备好进行更改,git fetch请先进行。


78

git fetch将检索远程分支机构,这样就可以git diffgit merge它们与当前分支。git pull将在当前分支跟踪的远程分支上运行访存,然后合并结果。您可以git fetch用来查看远程分支是否有任何更新,而无需将其与本地分支合并。


73

Git获取

您可以将更改从源下载到本地分支下载。Fetch向远程存储库询问其他人进行的所有提交,但您没有在本地存储库上进行的提交。Fetch下载这些提交并将其添加到本地存储库。

Git合并

您可以使用merge命令应用通过提取下载的更改。合并将采用从提取中检索的提交,并尝试将它们添加到本地分支。合并将保留本地更改的提交历史记录,这样,当您与push共享分支时,Git将知道其他人如何合并您的更改。

吉特拉

提取和合并经常一起运行,以至于创建了将两者(合并)的命令。Pull先进行提取,然后进行合并以将下载的提交添加到本地分支中。


52

git pull和之间的唯一区别git fetch是:

git pull 从远程分支中提取并合并。

git fetch 仅从远程分支获取,但不合并

即git pull = git fetch + git merge ...


1
而且,如果git认为您落后于提交并且可以“快进”,这对我都没有帮助,这在我结束rm -rf整个工作并重新开始时就可以了。愚蠢的Git,请让我了解最新信息,以便我可以重新开始工作?
克里斯K

46

简单来说,如果您要在没有任何互联网连接的情况下跳上飞机...在出发之前,您可以 git fetch origin <master>。它会将所有更改取到您的计算机中,但将其与本地开发/工作区分开。

在飞机上,您可以更改本地工作区,然后将其与获取的内容合并,并解决潜在的合并冲突,而无需连接到Internet。而且,除非有人对远程存储库进行了新的冲突更改,否则一旦到达目的地,您就git push origin <branch>可以开始喝咖啡。


从这个很棒的Atlassian教程中

git fetch命令将提交,文件和引用从远程存储库下载到本地存储库。

当您想查看其他所有人正在从事的工作时,获取就是您要做的。它与SVN更新类似,它使您可以查看中央历史记录的进展情况,但是并不会强迫您将更改实际合并到存储库中。Git 将获取的内容与现有的本地内容隔离开来,它绝对 不会影响您的本地开发工作。必须使用该git checkout命令显式签出获取的内容。这使得在将提交与本地存储库集成之前,可以获取一种安全的方式来查看提交。

当下载从远程存储库内容,git pullgit fetch命令可用来完成任务。您可以考虑 git fetch这两个命令的“安全”版本。它将下载远程内容,但不会更新本地存储库的工作状态,而使当前工作保持不变。git pull是更积极的选择,它将为活动的本地分支下载远程内容,并立即执行git merge以为新的远程内容创建合并提交。如果您有待处理的变更,这将导致冲突并启动合并冲突解决流程。


git pull

  • 您没有任何隔离。
  • 它影响您​​的本地发展。
  • 不需要显式签出。因为它隐式地做了一个git merge
  • 这基本上是不安全的。好斗
  • git fetch仅影响您的地方不同.git/refs/remotes,git pull将同时影响您.git/refs/remotes .git/refs/heads/

嗯...所以,如果我不使用来更新工作副本git fetch,那么我在哪里进行更改?Git提取将新提交存储在哪里?

好问题。它将其放置在与工作副本隔离的位置。但是又在哪里?让我们找出答案。

在项目目录(即执行git命令的位置)中:

  1. ls。这将显示文件和目录。我知道,没什么好酷的。

  2. 现在做ls -a。这将显示点文件,即以.You 开头的文件,然后将可以看到名为的目录.git

  3. cd .git。显然,这将更改您的目录。
  4. 有趣的来了; 做ls。您将看到目录列表。我们正在寻找refs。做cd refs
  5. 看看所有目录中都有什么很有趣,但让我们集中讨论其中两个。headsremotes。也cd可以用来检查它们的内部。
  6. git fetch您所做的任何操作都会更新/.git/refs/remotes目录中的项目。它不会更新/.git/refs/heads目录中的任何内容。
  7. 任何人 git pull都将首先执行git fetch,更新/.git/refs/remotes目录中的项目,然后与您的本地目录合并,然后更改/.git/refs/heads目录中的标题。

一个很好的相关答案也可以在“ git fetch”本身放置哪里?

另外,从Git分支命名约定文章中查找“斜杠表示法” 。它可以帮助您更好地了解Git如何将事物放置在不同目录中。


看实际差异

做就是了:

git fetch origin master
git checkout master

如果远程主服务器已更新,您将收到以下消息:

Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

如果您不fetch这样做,git checkout master那么您本地的git将不会知道添加了2个提交。它只会说:

Already on 'master'
Your branch is up to date with 'origin/master'.

但这是过时且不正确的。这是因为git只会根据已知信息给您反馈。尚未提交的新提交遗忘了...


在本地工作分支时,是否有任何方法可以查看远程所做的新更改?

某些IDE(例如Xcode)非常智能,并使用a的结果,git fetch并且可以注释当前工作分支的远程分支中已更改的代码行。如果该行已被本地更改和远程分支更改,则该行将用红色注释。这不是合并冲突。这是潜在的合并冲突。在git pull从远程分支执行此操作之前,可以使用此提示来解决将来的合并冲突。

在此处输入图片说明


有趣的提示:

如果您获取了一个远程分支,例如:

git fetch origin feature/123

然后它将进入您的remotes目录。您的本地目录仍然不可用。但是,它通过DWIM简化了您到该远程分支的签出(执行我的意思):

git checkout feature/123

您不再需要执行以下操作:

git checkout -b feature/123 origin/feature/123

有关更多信息,请点击此处


1
我喜欢这个答案
Kid_Learning_C

44

Git允许按时间顺序将较早的提交应用于较新的提交。因此,在存储库之间传输提交的操作分为两个步骤:

  1. 将新的提交从远程分支复制到本地仓库中的该远程分支的副本。

    (回购到回购操作) master@remote >> remote/origin/master@local

  2. 将新提交集成到本地分支

    (内部回购操作) remote/origin/master@local >> master@local

有两种方法可以执行步骤2。您可以:

  1. 在最后一个共同祖先之后分叉本地分支,并添加与本地存储库独有的提交平行的新提交,通过合并提交,关闭分叉来最终确定。
  2. 在最后一个共同祖先之后插入新提交,然后重新应用本地存储库唯一的提交。

git术语来说,步骤1是git fetch,步骤2是git mergegit rebase

git pullgit fetchgit merge


36

Git使用两个命令获取从远程到本地的最新版本的分支:

  1. git fetch:Git将从远程到本地获取最新版本,但是不会自动合并。      git fetch origin master git log -p master..origin/master git merge origin/master

         上面的命令意味着从远程将主分支的最新版本从远程下载到起源主分支。然后比较本地主分支和原始主分支。最后,合并。

  2. git pull:Git将从远程获取最新版本并合并到本地。

        git pull origin master

         上面的命令等效于git fetchgit merge。实际上,这git fetch可能更安全,因为在合并之前,我们可以看到更改并决定是否合并。


36

git pull和之间有什么区别git fetch

要了解这一点,您首先需要了解本地git不仅维护本地存储库,还维护远程存储库的本地副本。

git fetch使远程存储库的本地副本保持最新状态。例如,如果您的远程存储库是GitHub-您可能希望将远程存储库中所做的所有更改都提取到远程存储库的本地副本中。这将允许您执行比较或合并之类的操作。

git pull另一方面,它将使远程存储库中的更改降至您保留自己的代码的位置。通常,首先git pullgit fetch更新远程存储库的本地副本,然后将更改合并到您自己的代码存储库中,并可能合并到您的工作副本中。


34

git pull ==(git fetch + git merge)

git fetch不会更改为本地分支。

如果您已经有一个本地存储库,并为所需项目设置了远程设置,则可以使用git fetch获取现有远程设备的所有分支和标签。...提取不会对本地分支进行任何更改,因此您需要将远程分支与成对的本地分支合并以合并新的提取更改。来自github


33

力求清晰和简单。

混帐拉命令实际上是shortcutgit的取指随后混帐合并混帐重订根据您的配置命令。您可以配置您的Git存储库,以便git pull是先获取后是重新建立基础。


33

一个适合初学者的简单图形表示,

在此处输入图片说明

这里,

git pull  

将从存储库中获取代码,并使用您的本地库进行基础...在git pull中,可能会创建新的提交。

但在 ,

git获取

将从存储库中获取代码,我们需要使用 git rebase

例如:我要从服务器主服务器获取并将其重新放置在本地主服务器中。

1)git pull(变底会自动完成):

git pull origin master

这里起源的远程回购是你的分支

2)git fetch(需要手动重新设置基准):

git fetch origin master

它将从源获取服务器更改。并且它将一直存在于您的本地环境中,直到您自己重新建立基础为止。我们需要通过检查代码来手动解决冲突。

git rebase origin/master

这会将代码重新设置为本地代码。在此之前,请确保您在正确的分支中。


很好的图形,但是您可能想解释为什么当图形显示“合并”时使用“重新设置”。
Guntram Blohm支持Monica

1
merge将代表另一个分支提交,并产生包含提交作为参考的新提交。但是rebase将从另一个分支复制提交,它不会创建新的提交而不是复制
Mohideen bin Mohammed

33

实际上,Git维护您自己的代码和远程存储库的副本。

该命令git fetch通过从远程存储库获取数据来使本地副本保持最新状态。我们之所以需要这样做,是因为其他人可能已经对代码进行了一些更改,而您想保持自己的最新状态。

该命令git pull将远程存储库中的更改带到您保留自己的代码的位置。通常,git pull这是通过首先执行“ git fetch”来实现的,以使远程存储库的本地副本保持最新,然后将更改合并到您自己的代码存储库中,并可能合并到您的工作副本中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.