Pull vs. fetch and merge in Git

Both git fetch and git pull can update the code of the remote repository to the local, but there are still differences between them. I searched git pull and fetch today, and found that there is a lot of information, and it involves many concepts in git. It is difficult to fully understand with my IQ, so let me state first. The following content is after I have synthesized the information on the Internet. , my own understanding, if there is misleading, please forgive me.

 

First of all, I searched for the difference between git pull and git fetch. There are many posts on the Internet. I mainly refer to this post http://www.tech126.com/git-fetch-pull/ , and I excerpted the main content.

git fetch

1
2
3
git fetch origin master
git log -p master..origin /master
git merge origin /master
  1. Update the latest version from the master branch of the remote origin repository to the origin/master branch
  2. Compare the difference between the local master branch and the origin/master branch
  3. Merge content to local master branch

For another way to use fetch, refer to my previous article Git to update the remote repository code to the local .

 

git pull

1
git pull origin master

Equivalent to git fetch and git merge, that is, update the code of the remote warehouse to the local warehouse, and then merge the content into the current branch.

 

So, to put it simply, git pull is equivalent to git fetch and then a git merge. So how to analyze their specific differences, which requires us to know git again, first look at the following picture:

XwVzT

We know that git actually has several areas, workspace, staging area (index), local repository (local repository), and of course remote repository (remote repository). The remote repository saves a copy of the code for us, such as github, and the workspace, staging area and local repository are all local, which is why we still use git to commit code updates without a network, because commits are only submitted to The local warehouse can be pushed to the remote warehouse after the network is available.

正如上图所示,git fetch是将远程仓库的更新获取到本地仓库,不影响其他区域。而git pull则是一次性将远程仓库的代码更新到工作区(同时也会更新本地仓库)。

 

通常来说,git fetch和merge与git pull的区别已经很明显了,但是如果想再了解下git是如何操作的,则需要我们了解下分支这个git的强大特性(分支的概念确实太牛逼了,我不确定我的理解是否是正确的)。

 

分支

分支(branches)是用来标记特定的代码提交,每一个分支通过SHA1sum值来标识,所以对分支进行的操作是轻量级的——你改变的仅仅是SHA1sum值。所以为什么git提倡大家多使用分支,因为它即轻量级又灵活。简单的说,分支有两种:

本地分支(local branches)” ,当你输入“git branch”时显示的:

1
2
$ git branch
   * master

远程分支(remote branches)” ,当你输入“git branch -r”是显示的:

1
2
$ git branch -r
   origin /master

 

如果你对分支在本地是如何存储感兴趣的话,看看项目中的下面文件,文件里面存的就是一个SHA1sum值:

  • .git/refs/head/[本地分支]
  • .git/refs/remotes/[正在跟踪的分支]

 

我们来看看远程分支,Pro Git这本书描述的非常好。远程分支(remote branch)是对远程仓库中的分支的索引。它们是一些无法移动的本地分支;只有在 Git 进行网络交互时才会更新。远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置。

我们用 (远程仓库名)/(分支名) 这样的形式表示远程分支。比如我们想看看上次同 origin 仓库通讯时 master 分支的样子,就应该查看 origin/master 分支。如果你和同伴一起修复某个问题,但他们先推送了一个 iss53 分支到远程仓库,虽然你可能也有一个本地的 iss53 分支,但指向服务器上最新更新的却应该是 origin/iss53 分支。

 

下面我把Pro Git中的例子摘抄过来。假设你们团队有个地址为 git.ourcompany.com 的 Git 服务器。如果你从这里克隆,Git 会自动为你将此远程仓库命名为 origin,并下载其中所有的数据,建立一个指向它的 master 分支的指针,在本地命名为 origin/master,但你无法在本地更改其数据。接着,Git 建立一个属于你自己的本地 master 分支,始于 origin 上 master 分支相同的位置,你可以就此开始工作:

18333fig0322-tn

这样,我们在本地仓库的本地分支和远程分支都有了,并且起始于同一位置。

 

如果你在本地 master 分支做了些改动(在本地工作区commit了代码到本地仓库),与此同时,其他人向 git.ourcompany.com 推送了他们的更新,那么服务器上的 master 分支就会向前推进,而与此同时,你在本地的提交历史正朝向不同方向发展。不过只要你不和服务器通讯,你的 origin/master 指针仍然保持原位不会移动:

18333fig0323-tn

注意这里的本地分支已经前移,而远程分支还保持不动,而远程仓库的master其实也已经前移,所以可以说本地的远程分支origin/master是过时的。

 

可以运行 git fetch origin 来同步远程服务器上的数据到本地。该命令首先找到 origin 是哪个服务器(本例为 git.ourcompany.com),从上面获取你尚未拥有的数据,更新你本地的数据库(仓库),然后把 origin/master 的指针移到它最新的位置上:

18333fig0324-tn

现在大家能看到git fetch的作用了吗?

 

接下来还没完,我们来看看git的高级玩儿法。为了演示拥有多个远程分支(在不同的远程服务器上)的项目是如何工作的,我们假设你还有另一个仅供你的敏捷开发小组使用的内部服务器 git.team1.ourcompany.com。可以用第二章中提到的 git remote add 命令把它加为当前项目的远程分支之一。我们把它命名为 teamone,以便代替完整的 Git URL 以方便使用:

18333fig0325-tn

注意这里是多个远程分支,不同的远程服务器。

 

现在你可以用 git fetch teamone 来获取小组服务器上你还没有的数据了。由于当前该服务器上的内容是你 origin 服务器上的子集,Git 不会下载任何数据,而只是简单地创建一个名为 teamone/master 的远程分支,指向 teamone 服务器上 master 分支所在的提交对象 31b8e:

18333fig0326-tn

由此你在本地就有了两个远程分支,作为指向两个远程服务器上 master 分支的索引。

 

好了,不扯远了,总结下git fetch和git pull:

  • git fetch is the command that says “bring my local copy of the remote repository up to date.”
  • git pull says “bring the changes in the remote repository where I keep my own code.”

 

由于git pull把过程的细节都隐藏了起来,以至于你不用去了解git中各种类型分支的区别和使用方法。当然,多数时候这是没问题的,但一旦代码有问题,你很难找到出错的地方。看起来git pull的用法会使你吃惊,简单看一下git的使用文档应该就能说服你。
将下载(fetch)和合并(merge)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。

It's a good practice to download and merge separately, you can first look at the difference (diff), and then decide whether to merge with the native code. And do it separately, you can clearly distinguish the local branch and the remote branch, which is convenient for selection and use. So try to use git pull less and use git fetch and merge more .

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326686668&siteId=291194637