一文读懂 Git fetch 和 Git pull 的终极区别(带实验结果)

news/2024/9/29 14:59:07

Git pull 是一个 Git 命令用来同时执行 git fetch 和 git merge。本文分享了这两个命令的区别和用法。

Git 命令是非常流行的,尤其是在分布式版本控制系统中,可以对远端的仓库进行同步。开发者需要根据项目实际所需来选择合适的命令。在本文章中,我们将解释 git fetch 和 git pull 之间的区别,并且为两者不同的使用场景做一个详述。

Git fetch 和 git pull 的基本知识

Git fetch 和 git pull 都是用来从远端仓库更新信息的 Git 命令。所以,他们有什么区别呢?Git fetch 将更新从远端仓库下载到本地,但是不会对当前工作目录做任何变更。因为变更并没有被合入到本地分支,因此你可以在不打断当前工作流的情况下从远端仓库检出变更。另一方面,git pull 也能像 git fetch 一样从远端仓库拉取最新的变更,但是它却会把变更自动合入到当前分支。相比于 git fetch,git pull 直接将远端仓库的变更应用到本地工作目录中。

什么是 git fetch

git fetch 从远端仓库拉取最新的提交历史,但是不会对当前的本地工作目录产生任何影响。即使在获取(fetch)远端变更后,这些变更也不会在本地分支上有所反应。它的主要用途是:当你想要从远端仓库获取最新的状态,然后对变更被合入到本地仓库之前对变更做预览。为了将获取的变更应用到本地分支,你还需要手动执行 git merge 或者 git rebase。

什么是 git pull

git pull 命令是将 git fetch和 git merge(或 git rebase)结合在了一起。这能够让你从远端仓库拉取(fetch)变更并且将变更自动应用到当前的本地分支上。

当用 git fetch 从远端仓库获取变更时,变更并没有应用到本地分支,而执行 git pull 命令会自动将变更从远端仓库应用到本地分支上。

Git pull 特别适合将远程变更快速反映到本地分支上,但这可能会导致冲突,因此要小心使用,特别是当多人协作时。

什么时候用 git fetch

Git fetch 是一个从远端仓库拉取最新变更信息的命令。获取的信息并不直接反映在本地分支。使用 git pull 命令则会将所有的变更都反映到本地分支上,包括不正确的或者有问题的变更,统统搞到本地分支上。

当变更同时在远端和本地分支上进行时,或者当团队内的新入职员工进行操作时,使用 git fetch 是比较安全的,可以先用 git fetch 获取变更内容,然后再执行 merge 或者 rebase 命令。

什么时候用 git pull

Git pull 是一个比 git fetch 执行更多流程的命令。Git pull 可以同时执行 git fetch 和 git merge 或 git rebase 命令。因此,当你特别希望远端变更能及时反映到本地分支上的时候,就用 git pull 吧。

实验验证

在极狐GitLab 上创建一个 Repo,存储一个 README.md 和 1.txt 文件,其中 1.txt 文件内容如下:

cat 1.txt
1111
2222
3333

首先,保持本地和远端仓库的一致性。然后在远端仓库上将 2222改为 2233。这时候远端仓库和本地仓库之间的代码就存在差异了,本地仓库落后远端仓库一个 commit:

file

Git fetch 验证

根据前面文章的描述,执行 git fetch命令会拉取远端仓库的最新信息,但是不会将其合并到被爱分支。也就是说在本地执行 git fetch命令后,会看到变更拉取的信息,但是查看 1.txt 的内容,依旧是 2222,验证一下结论:


# fetch 变更
git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 315 bytes | 315.00 KiB/s, done.
From jhma.jihulab.net:devsecops1/aid143d7e..75eadda  main       -> origin/main# 查看 1.txt 内容
cat 1.txt
1111
2222
3333

可以看到 1.txt 中依旧是 2222。然后手动执行一下 git merge或者 git rebase,再查看结果:

# 执行 git rebase 命令
git rebase
Successfully rebased and updated refs/heads/main.# 查看 1.txt 内容
cat 1.txt
1111
2233
3333

Git pull 验证

再对远端代码做一下修改,将 1.txt 中的 3333改为 3322。先确定本地分支上的内容,然后执行 git pull,最后再确认本地分支上的内容:

# 本地分支内容查看
cat 1.txt
1111
2233
3333# git pull 命令
git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 321 bytes | 321.00 KiB/s, done.
From jhma.jihulab.net:devsecops1/ai75eadda..e66df87  main       -> origin/main
Updating 75eadda..e66df87
Fast-forward1.txt | 2 +-1 file changed, 1 insertion(+), 1 deletion(-)# 再次查看本地分支内容1111
2233
3322

可以看到远端分支的 3333直接变成了 3322,直接反映在了本地分支上。

进阶试验

下面来制造一个冲突,来进一步查看 git fetch 和 git pull 之间的差别。整体测试流程为:

  1. 在远端仓库新建一个 branch-1分支;
  2. 将远端仓库中 branch-1分支上的 3333改为 4444;
  3. 将本地 branch-1分支上的 3333改为 5555;
  4. 分别执行 git fetch 和 git pull 命令查看结果

首先看执行 git fetch 的结果:

# 执行 git fetch 命令
git fetch origin branch-1
From jhma.jihulab.net:devsecops1/ai* branch            branch-1   -> FETCH_HEAD# 查看 branch-1 分支上的内容
cat 1.txt
1111
2222
5555

可以看到 1.txt 文件中的 3333 变成了 5555。这个符合预期,因为 git fetch 会拉取变更,但是不会合并到本地分支,接着执行 git merge 或者 git rebase 命令:

git merge
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Automatic merge failed; fix conflicts and then commit the result.

提示冲突,然后打开 1.txt 文件查看:

1111
2222
<<<<<<< HEAD
5555
=======
4444
>>>>>>> refs/remotes/origin/branch-1

可以看到冲突的内容,此时解决冲突的时候,只要确保保留哪些内容即可,比如保留 4444那就把 5555删除,然后重新提交代即可:

# 提交代码
git add . && git commit -m "fix confilict"
[branch-1 77f28b1] fix confilict# 推动代码
git push origin branch-1
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 511 bytes | 511.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for branch-1, visit:
remote:   http://jhma.jihulab.net/devsecops1/ai/-/merge_requests/new?merge_request%5Bsource_branch%5D=branch-1
remote:
To jhma.jihulab.net:devsecops1/ai.git55ce9b9..77f28b1  branch-1 -> branch-1

前面是 git fetch 在面对冲突时候的表现。还是最开始的条件,如果直接执行 git pull 会有什么不同吗?

# 远端 branch-1 分支内容
1111
2222
5555# 本地 branch-1 分支内容
1111
2222
4444# git pull 命令
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Automatic merge failed; fix conflicts and then commit the result.# 查看冲突内容
1111
2222
<<<<<<< HEAD
5555
=======
4444
>>>>>>> a91c399bb2772f5a121830638d138264df27c9ee

剩下的冲突解决和上面的就一样了。

总结

Git fetch 和 Git pull 虽然都是从远端仓库将变更拉取到本地的命令,但是两者在作用上有所不同,简言之:Git fetch 拉取变更但是不将变更应用到本地分支;Git pull 拉取变更同时将变更应用到本地分支,可以理解为 Git pull = Git fetch + Git merge(or rebase)

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66181.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

pbootcms的图片裁剪确保无论图片是横图还是竖图,都能居中裁剪

解决方案找到裁剪缩略图的方法:文件位置:/core/function/file.php 搜索:function cut_img,大约在447行优化cut_img方法:实现居中裁剪功能优化代码 以下是优化后的cut_img函数代码: // 剪切图片 function cut_img($src_image, $out_image = null, int $new_width = null, …

Online DDL

MySQL在线DDL特性提供了即时支持instant 、copy方式,还有原表in-place方式。有些过程中也允许并发DML。 语法:ALTER TABLE tbl_name , alter_option: {...}, ALGORITHM [=] {DEFAULT | INSTANT | INPLACE | COPY} LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}为了避免在执…

pbootcms提示提交失败,请使用POST方式提交

在PbootCMS中,如果你在模板在线留言功能中遇到“提交失败,请使用POST方式提交!”的错误,通常是因为URL名称使用了系统保留的关键字。为了避免这类问题,可以遵循以下建议: 1. 系统保留关键字 PbootCMS系统中有一些保留的关键字,这些关键字不能用作URL名称。以下是一些常见…

ElementUI中实现el-table表格列宽自适应,列根据内容自动撑满,内容不换行

一、概述 在表格宽度固定时,实现内容不换行,表格自动显示滚动条 当前显示效果: 期望实现效果: 二、实现思路 遍历表格数组,每次都构建一个隐藏的span元素,获取该元素的宽度,对比保存最大值 代码如下:```typescript /*** 表格列宽自适应* @param prop 属性* @param reco…

PbootCMS模板如何调用友情链接

在PbootCMS中,使用友情链接标签可以方便地输出指定分组的友情链接。下面是一个详细的示例,展示了如何使用该标签以及如何控制输出的内容。 友情链接标签示例 1. 基本用法{pboot:link num=3 gid=1}<a href="[link:link]" target="_blank">[link:nam…

getBeansOfType源码解析

org.springframework.beans及org.springframework.context这两个包是Spring IoC容器的基础,其中重要的类有BeanFactory,BeanFactory是IoC容器的核心接口,其职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖关系。 ApplicationContext作为BeanFactory的子…

KubeSphere 社区双周报|2024.09.13-09.26

KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2024.09.13-09.26。 贡献者名单新晋 KubeSphere co…

pbootcms模板如何做好防护

为了提高PbootCMS模板的安全性,可以采取以下步骤进行防护: 第一步:重命名数据文件夹将data文件夹的名字换成其他名称,例如mydata。mv data mydata第二步:修改数据库配置文件打开config文件夹中的database.php文件。 将文件中的data名称改为与第一步中相同的名称(例如myda…