git fetch merge rebase squash

2023-11-17

合并分类

合并分支的时候,默认是有三种选项的,分别是

普通的 merge
squash merge
rebase merge

区分 merge 和 rebase

更多参考GIT使用rebase和merge的正确姿势

准备

假设我们有如下图一所示仓库,该仓库有master和develop两个分支,且develop是在(3.added merge.txt file)commit处从master拉出来的分支。
在这里插入图片描述

merge

假设现在HEAD在(6.added hello.txt file)处,也就是在master分支最近的一次提交处,此时执行git merge develop 处于 master 分支,将 develop 分支 merge 到 master 分支, 结果如下图所示
在这里插入图片描述
工作原理就是:git 会自动根据两个分支的共同祖先即 (3.added merge.txt file)这个 commit 和两个分支的最新提交即 (6.added hello.txt file) 和 (5.added test.txt file) 进行一个三方合并,然后将合并中修改的内容生成一个新的 commit,即图二的(7.Merge branch ‘develop’)。

这是merge的效果,简单来说就合并两个分支并生成一个新的提交

rebase

假设初始状态也是图一所显示的。两个分支一个master,一个develop,此时HEAD在(6.added hello.txt file)处,git rebase develop 处于 master 分支,将 develop 分支 merge 到 master 分支 ,结果如下图三所示。
在这里插入图片描述
可以看见develop分支分出来分叉不见了,下面来解释一下它的工作原理:

在执行git rebase develop之前,HEAD在(6.added hello.txt file)处,当执行rebase操作时,git 会从两个分支的共同祖先 (3.added merge.txt file)开始提取当前分支(此时是master分支)上的修改,即 (6.added hello.txt file)这个commit,再将 master 分支指向 目标分支的最新提交(此时是develop分支)即(5.added test.txt file) 处,然后将刚刚提取的修改应用到这个最新提交后面

简单来说,就是 先找到公共祖先合并祖先之后的 commit , 将 delvelop 分支在祖先之后的 commit 放到祖先 commit 之后,然后把 master 在祖先之后的 commit 放到 develop 最新 commit 之后

如果提取的修改有多个,那git将依次应用到最新的提交后面,如下两图所示,图四为初始状态,图五为执行rebase后的状态。

在这里插入图片描述
在这里插入图片描述
简单来说,git rebase 提取操作有点像git cherry-pick一样,执行rebase后依次将当前(master)的提交cherry-pick到目标分支(develop)上,然后将在原始分支(master)上的已提交的commit删除。

比如,develop 上的 5 commit 和 master 上的 6 commit 实际上是相同的修改,所以会把 当前(master)分支的 6 commit 删除

举个例子,那上图四、五来说,在master分支上执行rebase操作后,git 对比 develop 和 master 分支的5 commit 是相同的,所以删除 master 的 5 commit ,将 7、8commit依次挪到 develop 的 5 commit后面。

merge OR rebase

那什么时候用merge,什么时候用rebase呢?
再举个例子:
初始状态如下图六所示:
和之前一样的是,develop分支也是在 (3.added merge.txt file)处从master分支拉取develop分支。不一样的是两个分支各个commit的时间不同develop分支的4提交早于master分支的5提交develop分支的6提交晚于master的5提交早于master的7提交。
在这里插入图片描述
在上图情况下,在master分支的7commit处,执行git merge develop,结果如下图所示:
在这里插入图片描述
执行git rebase develop,结果如下图所示:
在这里插入图片描述

总结

可以看出merge结果能够体现出时间线,但是rebase会打乱时间线
rebase看起来简洁,但是merge看起来不太简洁

最终结果是都把代码合起来了,所以具体怎么使用这两个命令看项目需要。

普通 Merge

说到合并分支,可能我们最熟悉的操作是这样的:

先切换到目标分支:git checkout master
执行命令:git merge devel
删除旧分支(可以在上面一同做):git branch -D devel
提交到远程分支:git push origin master

假设合并之前的这样的:
在这里插入图片描述
我们这么上述操作之后,分支的 commit 历史将会是这样的:
在这里插入图片描述
看上去是一条直直的 commit line,我们在devel 分支中的 commit也是一个不差得保留在了 master 中。但是很多时候,我们并不需要那么多的 commit,假设你给一个开源项目提交一个 Bug Fixes,然后一个简单的修改因为你的粗心大意 pull request 了十几个 commit 过去,如果作者给你 merge 了,这就在这个项目的历史长河中增加了十几个 commit 啊,以后的人看 commit history 估计都崩溃了吧;同时,当你 merge 之后发现有问题,想回滚都麻烦

squash merge

在使用 git 的过程中,可能你遇到过想要合并多个 commit 为一个,然后很多人会告诉你用 git commit --amend,然后你发现里面有你的多个 commit 历史,你可以通过 pick 选择squash 合并等等。同样得,merge 的时候也可以这么干,你只需要这么简单的两步:

切换到目标分支:git checkout master
以 squash 的形式 merge:git merge --squash devel

你会发现,在 master 分支上居然有未提交的修改,然后你就需要在 master 上主动提交了修改,注意,这里是你 commit 的,也就是改变了 commit 的 author。结果是这样的:

在这里插入图片描述

比前面普通的 merge 来说,我们只有一个 commit 了,不管在分支中 commit 了多少,这里都只有一个

rebase merge

下面的 master 分支,最新的 P 记录没有 commit
在这里插入图片描述

我们既想合并 commits又想保留作者的信息,那么有没有什么好办法呢?肯定是有的啦,这个时候我们可以尝试一下 rebase,操作步骤是这样的:

先切换到 devel 分支:git checkout devel
变基:git rebase -i master
切换回目标分支:git checkout master
合并: git merge devel

这里完成了第二步之后我想你应该大概知道发生了什么事了,我们在devel里面对照 master 进行了变基,所谓的变基其实就是找到两个分支共同的祖先,然后在当前分支上合并从共同祖先到现在的所有 commit,所以我们在第二步的时候会选择怎么处理这些 commit,然后我们就得到了一个从公共commit 到现在的单个 commit,这个时候别人讲我们这个 commit 合并到 master 也只会在 master 上留下一个 commit 记录,就像这样:
在这里插入图片描述

总结

rebase 可以保持 master 分支整洁易于识别 author容易回滚
squash 可以保持 master 分支整洁,但是 master 中 author 都是 maintainer,而不是原 owner容易回滚
普通merge 不能保持 master 分支整洁,但是保持了所有的 commit history, 回滚时麻烦

操作复杂程度 rebase > squash > 普通merge
回滚复杂度 rebase = squash > 普通merge

fetch

git pull origin dev 相当于以下两句
		git fetch origin dev	代码拉到本地版本库
		git merge origin/dev	把本地版本库代码合并到工作区

git pull origin dev -r  相当于
		git fetch origin dev
		git rebase origin/dev

在项目中经常使用git pull来拉取代码,git pull相当于是git fetch + git merge,如果此时运行git pull -r,也就是git pull --rebase,相当于git fetch + git rebase

平时在拉代码时,还是使用 git pull,在合并时再考虑使用 git fetch + git merge

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

git fetch merge rebase squash 的相关文章

  • GIT 和 Ruby:如何从 ruby​​ 脚本内部取消设置 GIT_DIR 变量?

    我编写了一个非常简单的 部署 脚本作为我的post update挂钩到我的裸 git 存储库中 变量如下 live domain mydomain com staging domain stage mydomain com git repo
  • 使用 Github Actions 进行部署

    我在用Github作为我的源代码控制 并使用Github 操作作为我的 CI CD 解决方案 我在某处有一个专用的 Windows Server 它接受发表我的仓库的版本 我有一个 Github Action 它可以构建 测试 发布和部署
  • 检查 Git 中是否需要 pull

    如何检查远程存储库是否已更改并且需要拉取 现在我使用这个简单的脚本 git pull dry run grep q v Already up to date changed 1 但它比较重 有没有更好的办法 理想的解决方案是检查所有远程分支
  • Smartgit:自动插入提交消息

    有没有办法使用钩子脚本在 Smartgit 中自动插入提交消息 重击 如果用户提交了他的更改 我想预加载提交消息字段 我没有看到任何SmartGit配置 http www syntevo com smartgit documentation
  • VS Code 在交互式变基期间不会等待我 [重复]

    这个问题在这里已经有答案了 如果我使用交互式变基git rebase i使用为 Git 配置的默认编辑器 一切都运行良好 如果我在我的全局中添加以下内容 gitconfig core editor C Program Files x86 M
  • 创建多个 git 分支的联合分支

    我希望能够在现有分支之上分层其他分支 并独立修改这些分支 这很有用 例如 允许将各个子项目的二进制文件统一到同一个项目中bin目录 一般来说 给定的文件仅存在于一层中 理想情况下 我想我会使用 unionfs 来完成此任务 但它必须以某种方
  • 结帐时出现 Git 错误:“致命:引用不是树”

    当我决定弄清楚为什么我正在从事的项目如此重要时 这一切就开始了 我运行了以下脚本 git rev list objects all git cat file batch check objecttype objectname objects
  • Git撤销本地分支删除

    我刚刚删除了错误的分支 并进行了一些我需要的实验性更改git branch D branchName 如何恢复分支 您可以使用git reflog http git scm com docs git reflog查找分支最后一次提交的 SH
  • 有什么方法可以从提交的消息中获取提交的 SHA 值吗?

    当做一个git tag 我并不总是擅长记住 HEAD 6 例如 是包含的还是排他的 鉴于我的大多数提交都以问题号为前缀 我想知道是否有一些神奇的命令可以从其消息的一部分中搜索提交 SHA 我知道这很容易做到git log并从那里开始工作 但
  • git merge --squash 和 gitcherry-pick 有什么区别?

    如果我在标准的主功能工作流程中工作 那么将功能分支压缩到主功能分支和将其挑选到主功能分支之间有什么区别 分支示例 m1 m2 master f1 f2 feature 我认为两者都有相同的输出 即 m1 m2 m3 master f1 f2
  • git 清除远程仓库

    如果我将错误的初始提交 或多个 推送到远程存储库 并且只想清除 销毁它 我可以通过命令来完成吗 将其从服务器中完全删除非常重要 这样它就不会占用磁盘空间 例如 今天我推送了一个完整的 Visual Studio 项目 其中包含 dll sd
  • 我如何才能看到 Github 风格的东西,例如 git -repo 的打孔卡和时间线?

    我正在寻找一个可以可视化 git repo 工作的软件 我喜欢 Github 的一些功能和 Bitbucket 的一些功能 所以我不想使用它们 因为它们并不完美 我正在寻找创建类似视觉特征的方法 下面你可以找到一些部分 但仍然缺少很多谜题
  • Github 页面 - 禁用除单个站点之外的所有站点的自定义域重定向?

    I ve been using github pages since a long time and use the custom domain redirection feature to redirect my user website
  • 将 GIT 存储库中的文件标记为暂时忽略

    我们正在从 Perforce 迁移到 GIT 当然 我希望存储库中有一些文件 但个人开发人员不应该定期签入它们 诸如 eclipse 项目文件之类的东西 每个开发人员可能会获得初始的 project 文件 但随后会根据自己的环境稍微调整它
  • 使用 git 将一系列小的合并从 master 压缩到我的分支中,同时保留对 master 的引用?

    我有一个非常复杂的合并要做 部分问题在于我浪费了太多时间 因此要纳入我的分支的更改量是巨大的 为了让事情变得更容易 我选择这样做git merge origin master 20 then git merge origin master
  • 在 Jenkins 项目中加载私有存储库子模块

    我目前正试图让詹金斯 克隆项目及其子模块 使用部署密钥配置为 Github 私有存储库验证 Jenkins CI https stackoverflow com questions 5212304 authenticate jenkins
  • 当更改提交给子模块时,如何触发詹金斯中的构建?

    我们有一个带有外部子模块的 git 存储库 当子模块更改时 我们必须触发构建 您能否向我们建议如何使用 xtrigger 插件轮询子模块上的更改 使用 shell 脚本或监视文件还是其他更好 有关我们构建过程的更多信息 步骤1 使用子模块克
  • 将 Maven 项目从 Git 导入到 Eclipse 中

    如何获得选择从 Maven 和 Git 导入并让 Eclipse 正确生成我的项目的效果 要将我的项目导入 Eclipse 我可以选择 File gt import gt maven 然后导入所有 Maven 项目并可以正常构建 或者我可以
  • git repo 的 tar/untar 后,gitk 显示“本地未提交的更改,未签入索引”

    我有一个包含小型 git 存储库的目录 git status 和 gitk all 显示没有未提交的更改 如果我使用以下命令 tar 压缩该目录 tar czf git repo tar gz git repo 然后将此 tar 文件传输到
  • Git 预提交挂钩未在 Windows 上运行

    我刚刚开始研究 Git 挂钩 但我似乎无法让它们运行 我设置了一个本地存储库 因此我的项目文件夹中现在有一个 git 目录 我已将名为 pre commit cmd 的 cmd 文件添加到 C path to my project git

随机推荐

  • 网关模式/网桥模式/旁路模式的区别

    网关模式 网桥模式 旁路模式的区别如下 EG设备有三种工作模式 网关模式 网桥模式和旁路模式 比较常用的是网关模式和桥模 式 1 网关模式是把设备当作网络出口 支持NAT和路由选路下报文转发的部署方式 2 桥模式是把设备作为桥接 串接在内网
  • 【SqlServer】如何把本地SqlServer数据库部署到远程服务器上

    这里笔者使用的使用SqlServer2012 本机和远程环境均为Win7 1 选中需要部署的数据库 右击 任务 分离 选中删除连接 2 现在在左侧的表中就看不见刚才那个数据了 3 在本地找到分离出来的数据库的位置 该位置就是读者建立数据库的
  • 厌烦了Ctrl+CV ?试试用node自动生成重复代码文件

    前言 相信在我们日常遇到的项目中 无论是在前端网站还是后台管理系统中都会有功能类似的页面 我们在开发这些功能类似的页面的时候 为了提高效率 一般都会运用我们的CV大法 但是当我们CV久了之后 会不会觉得这样的开发方式有些许枯燥 我们能不能通
  • 孙子算经 之 物不知数(韩信点兵)

    孙子算经 作者不可考 成书于四 五世纪南北朝时期 传本分三卷 它是算经十书之一 中国古代最重要的数学著作之一 其下卷26题 物不知数 为其最重要的成就之一 今有物 不知其数 三三数之 剩二 五五数之 剩三 七七数之 剩二 问 物几 何 答曰
  • 解决下载文件时报:Could not find acceptable representation

    今天在写一个文件打包下载的接口的时候一直报错误 文件是可以下载的但是后台打印的日志信息出现 Could not find acceptable representation错误 我之前百度给我的结果是由于我的返回值是json字符串 而由于
  • STM32F1各个工作状态下的工作电流

    低功耗操作实验 文章非原创 从其他网站上摘录 如果侵犯到到 麻烦联系删除 实验目的 测量 STM32 在各种状态下的功耗 包括在不同时钟频率下 32M 8M 1M 100K 10K 不同振荡器 内部 外部 不同模式 活动 睡眠 停机 待机
  • 经纬度查询_查询经纬度并自动转换格式(升级版)附带下载

    链接 https pan baidu com s 1Ysjwdu9griOXzw50RvfF1A 提取码 iwvv 链接 https share weiyun com 8ECyYM8g 密码 bwqmk8 1 史上最齐全的CAD下载资源 2
  • 二进制方式部署kubernetes集群

    二进制方式部署kubernetes集群 1 部署k8s常见的几种方式 1 1 kubeadm Kubeadm 是一个 k8s 部署工具 提供 kubeadm init 和 kubeadm join 用于快速部署 Kubernetes 集群
  • [python]多线程socket端口探测(包含top50-1000)

    这个脚本是基于tcp的 以下链接是基于tcp udp的自动切换的脚本 比这个脚本方便多了 实现UDP TCP的多线程端口探测 包含TOP 50 1000 sGanYu的博客 CSDN博客 多线程扫描工具 import optparse im
  • 数学建模常用的四大模型

    目录 1 评价模型 2 优化模型 3 分类模型 4 预测模型 本文主要介绍数学建模的四大模型分类 分别是评价模型 优化模型 分类模型 预测模型 关注公众号 数模乐园 回复 买 获得更多数模教程 1 评价模型 评价模型可以处理难于完全定量分析
  • ftp服务器查看所有文件夹,查看ftp服务器所有文件夹

    查看ftp服务器所有文件夹 内容精选 换一换 对于本文档的应用示例 查看 HOME tools projects Custom Engine main cpp中所需输入数据如下所示 ASIC场景 以root用户登录Host侧服务器 在 ho
  • R大数定律(Python切比雪夫不等式验证大数定律)模拟圆周率

    大数定律 在概率论中 大数定律 LLN 是描述大量执行相同实验的结果的定理 根据规律 大量试验所得结果的平均值应接近预期值 并随着试验次数的增加而趋于接近预期值 LLN 很重要 因为它保证了一些随机事件的平均值的长期稳定结果 例如 虽然赌场
  • 【Hive】Hive分区表

    分区作为一种提高数据操作灵活性的手段 被广泛应用于关系型数据库中 在Hive中我们同样可以采用分区的方式来提高数据操作效率 不同于关系型数据库 如Oracle Hive的分区表既可以是内部表 也可以是外部表 本篇文章主要介绍如何在Hive中
  • ValueError:optimizer got an empty parameter list 的一个可能错误

    ValueError optimizer got an empty parameter list基本都跟 init 及其里面的代码有关 比如下划线打错了 init拼错了 没有super 没在 init 函数内定义网络等 本次具体如下 今天有
  • 计数排序基础思路

    所谓计数排序 也可以称为散列表 也是一种简单的哈希桶 今天 小编带大家来了解计数排序的基本思路 一 基本思路 以升序为例 计数排序通俗来讲 分为三个步骤 首先制作包含所有要排序的数的桶 相同的数制作一个桶即可 以2 3 6 1 4 1 2
  • eclipse如何配置Maven

    Maven 翻译为 专家 内行 是 Apache 下的一个纯 Java 开发的开源项目 基于项目对象模型 缩写 POM 概念 Maven利用一个中央信息片断能管理一个项目的构建 报告和文档等步骤 Maven 是一个项目管理工具 可以对 Ja
  • C++:unique_ptr

    Code C program to illustrate the use of unique ptr include
  • Go_一文入门网络编程:常见协议、通信过程、Socket、CS/BS、TCP/UDP

    网络编程三要素 ip地址 端口 协议 在网络通信协议下 不同计算机上运行的程序 可以进行数据传输 IP地址 IP地址是一种在互联网协议中用于识别和定位设备的32位或128位数字地址 它是一个设备在网络上的唯一标识符 用于在互联网上定位和识别
  • 【房价网房价信息爬虫】整站40万条房价数据并行抓取,可更换抓取城市

    写在前面 学习数据采集 先转载下来 之后在学习 这次的爬虫是关于房价信息的抓取 目的在于练习10万以上的数据处理及整站式抓取 数据量的提升最直观的感觉便是对函数逻辑要求的提高 针对Python的特性 谨慎的选择数据结构 以往小数据量的抓取
  • git fetch merge rebase squash

    合并分类 在合并分支的时候 默认是有三种选项的 分别是 普通的 merge squash merge rebase merge 区分 merge 和 rebase 更多参考GIT使用rebase和merge的正确姿势 准备 假设我们有如下图