`

Git中pull对比fetch和merge

 
阅读更多

使用git fetch和git pull都可以更新远程仓库的代码到本地,但是它们之间还是有区别。今天搜了一下git pull和fetch,发现信息量很大,牵扯到git中很多概念,以我这种智商估计要完全理解很困难,所以先声明一下,下面的内容是我综合了网上的资料后,自己的理解,如有误导,敬请谅解。

 

首先,我搜索了git pull和git fetch的区别,网上的帖子很多,我主要参考了http://www.tech126.com/git-fetch-pull/这个帖子,我摘抄下主要内容。

git fetch

1
2
3
git fetch origin master
git log -p master..origin/master
git merge origin/master
  1. 从远程的origin仓库的master主分支更新最新的版本到origin/master分支上
  2. 比较本地的master分支和origin/master分支的差别
  3. 合并内容到本地master分支

另外一种fetch使用方式参考我之前的文章Git更新远程仓库代码到本地

 

git pull

1
git pull origin master

相当于git fetch 和 git merge,即更新远程仓库的代码到本地仓库,然后将内容合并到当前分支。

 

所以,简单的说git pull相当于git fetch后再做一个git merge。那么它们具体的区别如何分析呢,这就需要我们再认识下git了,先看看下面这张图:

XwVzT

我们知道,git其实有好几个区,工作区(workspace)、暂存区(index)、本地仓库(local repository),当然还有远程仓库(remote repository)。远程仓库为我们保存一份代码拷贝,如github,而工作区、暂存区和本地仓库都在本地,这就是为什么没有网络我们也照样使用git提交(commit)代码更新,因为提交仅是提交到本地仓库,待有网络之后可以再推送(push)到远程仓库。

正如上图所示,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)放到一个命令里的另外一个弊端是,你的本地工作目录在未经确认的情况下就会被远程分支更新。

单独进行下载和合并是一个好的做法,你可以先看看区别(diff),然后再决定是否和本地代码合并。而且分开来做,可以清晰的区别开本地分支和远程分支,方便选择使用。所以尽量少用git pull,多用git fetch和merge

分享到:
评论

相关推荐

    前端大厂最新面试题-git pull _git fetch.docx

    Git fetch 是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中,而 Git pull 则是将远程主机的最新内容拉下来后直接合并,即:Git pull = Git fetch + Git merge,这样可能会产生冲突,...

    Git pull命令与fetch命令的区别

    这个时候,就不得不提Git的两个命令,git fetch和git pull Git中从远程的分支获取最新的版本到本地有这样2个命令: Git fetch git fetch:相当于是从远程获取最新版本到本地,不会自动merge git fetch origin

    git fetch与git pull的区别详解

    另一方面,`git pull`命令则是`git fetch`和`git merge`的组合。当你运行`git pull`时,它首先执行`git fetch`获取远程仓库的更新,然后尝试自动将这些更新合并到你当前所在的本地分支。这就是为什么`git pull`通常...

    git-pull-branch.7z

    这个操作包括了`git fetch`(获取远程仓库的最新变更)和`git merge`(将获取的变更合并到本地分支)两步。在日常开发中,我们经常用`git pull`来保持本地代码与远程仓库的同步。 在Windows环境下,批处理脚本(....

    Git fetch和pull的详解及区别

    在Git的日常操作中,`git fetch`和`git pull`是两个常用但又略有区别的命令,它们都涉及到从远程仓库获取更新,但处理这些更新的方式有所不同。 ### `git fetch` `git fetch`命令的主要作用是从远程仓库获取最新的...

    git 视频教程

    git视频教程.5.1.Git 命令 - git fetch.mp4 git视频教程.5.2.Git 命令 - git pull.mp4 git视频教程.5.3.Git 命令 - git push.mp4 git视频教程.5.4.Git 命令 - git remote.mp4 git视频教程.5.5.Git 命令 - git ...

    详解git merge 与 git rebase的区别

    当执行 `git merge` 时,Git 会找到两个分支的最近共同祖先(在本例中是 `(3.added merge.txt file)`),然后对比这个共同祖先和两个分支的最新提交(`(6.added hello.txt file)` 和 `(5.added test.txt file)`)。...

    Git-2.37.3-64-bit_3Git-2.37.3-64-bit_3Git-2.37.3-64-bit_3Git-2.3

    对于团队项目,可以使用`git clone`下载远程仓库,`git pull`同步远程更新,`git push`推送本地更改,以及`git fetch`和`git merge`或`git rebase`来整合远程分支。 总之,Git-2.37.3-64-bit_3.exe是Git的64位...

    Git快速操作

    在开始工作前,你应该先更新本地代码到最新的版本,这可以通过`fetch`和`merge`完成,或者直接使用`pull`命令: ```bash # 更新但不合并 git fetch # 合并更新到本地 git merge # 或者直接使用 pull 命令,它包含...

    git批量拉取项目的脚本,简便快捷

    在标签“git”相关的其他知识点中,包括但不限于分支管理(如`git branch`, `git checkout`, `git merge`, `git rebase`)、提交历史查看(`git log`)、回退版本(`git reset`, `git revert`)、标签管理(`git tag...

    git图文教程中文教程

    7. **远程操作**: `git remote`命令用于管理远程仓库,`git fetch`和`git pull`用于获取远程仓库的更新,`git push`则将本地更改推送到远程。 8. **标签管理**: Git的标签功能可以标记特定的提交,通常用于发布里程...

    gitKraken常见问题解决方案

    - **Fetch与Pull的区别**: Pull操作包含了Fetch和Merge两步操作,而Fetch仅仅是从远程仓库拉取代码。如果你需要手动处理合并冲突,那么使用Fetch后再手动执行合并会更合适。 **2. 提交代码** - **将工作区的代码...

    Git权威指南第二版

    书中的另一重要部分是远程仓库的使用,包括`git remote`和`git fetch`、`git merge`以及`git rebase`等相关操作。这些功能使得开发者能够方便地与GitHub、GitLab等远程平台交互,进行代码的分享和协作。 此外,书里...

    Git-2.25.0-64-bit.zip

    在实际使用中,用户需要了解一些基本的Git命令,例如初始化一个新的Git仓库(`git init`),添加文件到暂存区(`git add`),提交暂存区的更改(`git commit`),以及与远程仓库同步(`git fetch`、`git merge`或`...

    windows git 批量 clone 脚本

    `git pull`命令结合了`git fetch`和`git merge`,可以获取远程仓库的最新更改并合并到本地分支。这个脚本会遍历每个仓库,执行`git pull`以保持代码同步。 最后,`deploy-my.bat`可能是一个针对特定用户的部署脚本...

    git文件包

    `git remote`命令用于添加、删除或查看远程仓库,`git fetch`和`git pull`用于从远程仓库获取数据,`git push`则用于将本地更改推送到远程。 在"git文件包"中可能包含的资源有Git的安装程序,这通常是Git for ...

    git pull时冲突的几种解决方式(小结)

    在Git版本控制系统中,`git pull`是一个常见的命令,用于将远程仓库的更新合并到本地分支。然而,当多人协作时,可能会出现冲突,即不同人对同一部分代码进行了不同的修改。本文将详细介绍在遇到`git pull`冲突时的...

    git工具下载更新代码

    `git branch`和`git merge`则用于处理分支管理和合并。 此外,为了更好地协作,开发者还会使用`git fetch`获取远程仓库的更新而不直接合并,以及`git rebase`来平滑地整合分支。Git还支持设置用户信息、解决冲突、...

    git-2.17.1.2-64位.zip

    如创建本地仓库(`git init`)、克隆远程仓库(`git clone`)、添加文件到暂存区(`git add`)、提交更改(`git commit`)、查看提交历史(`git log`),以及与远程仓库同步(`git fetch`、`git merge`或`git pull`...

Global site tag (gtag.js) - Google Analytics