当前位置: 首页 > news >正文

Git 操作补充:cherry-pick、变基

1. 挑选提交合并 git cherry-pick

对于多分支的代码库,将代码从一个分支转移到另一个分支是一种常见的需求,这可以分成两种情况:一种情况是,你需要另一个分支的所有代码变动,那么就采用 git merge;另一种情况是,你只需要部分代码变动(某几个提交),这时可以采用 git cherry-pick,语法为:git cherry-pick <commitHash>,将指定提交合并到另一个分支。

2f4a81027087445aa0fc72902e651f1e.png

举例来说,假设代码仓库有 master 和 feature 两个分支,提交历史如下,现在将 feture 分支的提交 f 应用到 master 分支。

a - b - c - d   Master
    \
     e - f - g Feature

# 切换到 master 分支
$ git checkout master# Cherry pick 操作
$ git cherry-pick f

上面的操作完成以后,代码库就变成了下面的样子(master 分支的末尾增加了一个提交 f)。

a - b - c - d - f   Master
    \
     e - f - g Feature

# 参数为分支名,表示转移该分支的最新一次提交。
$ git cherry-pick feature# 一次转移多个提交
$ git cherry-pick <HashA> <HashB>
# 上述命令能将 A 和 B 两个提交应用到当前分支,这会在当前分支生成两个对应的新提交。# 转移一系列的连续提交,可以使用下面的简便语法
$ git cherry-pick A..B 
# 上述命令将转移从 A 到 B (不包括A)的所有提交,A、B的顺序一定要正确:提交 A 必须早于提交 B,否则命令将失败,但不会报错。# 转移从 A 到 B (包括A)的所有提交
$ git cherry-pick A^..B

ec5676717d4a44fb9d7ef120f5eece5a.png

f20365bb4c9742039291e7948f4d5b20.png

2. 变基 git rebase

在 Git 中,整合来自不同分支的修改,除了 merge,还有一种方法,变基 rebase。git rebase 命令基本是一个自动化的 cherry-pick 命令,它计算出一系列的提交,然后在其地方以同样的顺序一个一个的 cherry-pick 它们。

Git 中有一些修改会覆盖提交历史,列举如下,在使用这些命令时,需要谨慎操作,以免不小心覆盖提交历史,导致代码丢失或者出现其他问题。

  1. 使用 git commit --amend 命令修改最近一次提交的信息,会覆盖最近一次提交的记录。
  2. 使用 git rebase 命令修改提交记录,这会修改提交的 SHA-1 校验和,覆盖提交历史。
  3. 使用 git reset 命令回滚到之前的提交,这会删除之后的提交历史。
  4. 使用 git push --force 命令强制推送修改,这会覆盖远程分支的提交历史。

2.1 Case 1:git rebase <upstream> 

假设在一个项目开发过程中,分叉到两个不同分支,每个分支都提交了更新。

221a800f41d94e82ba3e96cf4b49dc24.png

可以使用 merge 命令整合分支,它会把两个分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。

8112f27713554289a3e0e665db65d4a6.png

还有一种方法:使用变基 git rebase 整合分支,git rebase 的语法可以简写为:git rebase [--onto <newbase>] [<upstream> [<branch>]],表示将 <branch> 分支从 <upstream> 开始的提交应用到 <newbase> 分支上。具体来说,它会将 <branch> 分支自 <upstream> 之后的提交移动到 <newbase> 分支的最新提交之后,使得 <branch> 分支的提交历史看起来像是在 <newbase>分支的基础上进行的。

可以省略的参数是 <newbase> 和 <branch>;如果省略 --onto 参数,将以 <upstream> 参数指定的分支作为基底进行变基操作。也就是说,将当前所在分支(HEAD 指向的分支)与 <upstream> 参数指定的分支之间的差异应用到 <upstream>分支上;如果省略 <branch>,将把当前所在分支,即 HEAD 指向的分支,作为 <branch> 参数传递给 git rebase 命令。

a253d049fccf40d29a1ab83d925b7d72.png

 eecfdff7d6e74857841bdab01e03dc9c.png

cd0ef0e94dc54f628a7dac0ced001776.png

$ git checkout experiment$ git rebase master

cae1c32f1ad64e5790312c8e47d06196.png

接下来运行 git checkout master 回到 master 分支,然后运行 git merge experiment 进行一次快进合并。C4' 指向的快照就和使用 merge 得到的 C5 指向的快照一模一样,这两种整合方法的最终 结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。

一般这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁,例如向某个其他人维护的项目贡献代码时。在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。

2.2 Case2:git rebase [--onto <newbase>] [<upstream> [<branch>]] 

假设你的项目提交历史如下:你创建了一个特性分支 server,为服务端添加了一些功能,提交了 C3 和 C4。然后从 C3 上创建了特性分支 client,为客户端添加 了一些功能,提交了 C8 和 C9。 最后,你回到 server 分支,又提交了 C10。

 

fce3bb3187aa4e1abf4fee7e11a054c0.png

你希望将 client 中的修改合并到 master 主分支并发布,但暂时并不想合并 server 中的修改,因为它们还需要经过更全面的测试。这时,你可以使用 git rebase 命令的 --onto 选项,选择在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),将它们应用在 master 分支上。

运行命令:git rebase --onto master server client,其含义是:“取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重放一遍”。然后将 client 合并到 master。

$ git rebase --onto master server client
$ git checkout master
$ git merge client
$ git rebase master server
$ git checkout master
$ git merge server$ git branch -d client
$ git branch -d server

96e938c7a0dc427382c2b6605d8dd16b.png

a236b007a71844b78bafeed4cbfadf28.png

f7fae58aca3b499eaecc6ab0bee289ea.png

cbb969796b774ecfb0663ab1fec376f9.png

2.3 Case3:变基使用不当的风险

警告:不要对仓库外有副本的分支执行变基。如果你遵循这条金科玉律,就不会出差错。 否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。-- Scott Chacon

只要你把变基命令当作是在推送前清理提交使之整洁的工具,并且只在从未推送至共用仓库的提交上执行变基命令,就不会有事。 假如在那些已经被推送至公用仓库的提交上,执行变基命令,并因此丢弃了一些别人的开发所基于的提交,那你就有大麻烦了,你的同事也会因此鄙视你。

2.3.1 变基使用不当的例子

假设你从一个中央服务器克隆然后在它的基础上进行了一些开发,提交历史如图所示:

cd8fe74a24ee45db86e0de3c8cd1c722.png

一段时间后,其他项目成员向中央服务器提交了一些修改,其中包括一次合并。 

fa280b6e7b0a4175a54ea83fb7e8ee2d.png

你抓取了这些在远程分支上的修改,并将其合并到你本地的开发分支,你的提交历史如下:

b2e13ae3c22c44198d9ebcadccf9bfd4.png

接下来,这个成员又决定把合并操作回滚,改用变基,并用 git push --force 命令强制推送修改,这会覆盖远程分支的提交历史。

ff017e3d657147bea6979bd5ddab87ad.png

此时,你从服务器抓取更新,会发现多出来一些新的提交。如果你执行 git pull 命令,你将合并来自两条提交历史的内容,生成一个新的合并提交 C8。

5bca425180ad49f79af227deef5bcae7.png

此时,如果你执行 git log 命令,你会发现有两个提交的作者、日期、日志居然是一样的,这会令人感到混乱。 此外,如果你将这一堆又推送到服务器上,实际上是将那些已经被变基抛弃的提交又找了回来,这会令人感到更加混乱。很明显对方并不想在提交历史中看到 C4 和 C6,因为之前就是他把这两个提交通过变基丢弃的。

2.3.2 解决方法

如果团队中的某人强制推送并覆盖了一些你所基于的提交,你需要做的就是检查你做了哪些修改,以及他们覆盖了哪些修改。

方案1:git fetch + git rebase:在一个被变基然后强制推送的分支上再次执行变基

对于这种,有人推送了经过变基的提交,并丢弃了你的本地开发所基于的一些提交,不要使用 git pull,而是先 git fetch,再执行 git rebase teamone/master, Git 将会:

  • 检查哪些提交是我们的分支上独有的(C2,C3,C4,C6,C7)
  • 检查其中哪些提交不是合并操作的结果(C2,C3,C4)
  • 检查哪些提交在对方覆盖更新时并没有被纳入目标分支(C2 和 C3,C4 其实就是 C4')
  • 把查到的这些提交应用在 teamone/master 上面

想要上述方案有效,还需要对方在变基时确保 C4' 和 C4 是几乎一样的。 否则变基操作将无法识别,并新建另一个类似 C4 的补丁(而这个补丁很可能无法整洁的整合入历史,因为补丁中的修改已经存在于某个地方了)。

2b20418f71984ad3a9f8d0dead792d9d.png方案2:使用 git pull --rebase 而不是直接用 git pull

如果你或你的同事在某些情形下,不得不强制推送经过变基的提交,请一定要通知每个人执行 git pull --rebase 命令,这样尽管不能避免麻烦,但能有所缓解。

 

 

 

相关文章:

Git 操作补充:cherry-pick、变基

1. 挑选提交合并 git cherry-pick 对于多分支的代码库&#xff0c;将代码从一个分支转移到另一个分支是一种常见的需求&#xff0c;这可以分成两种情况&#xff1a;一种情况是&#xff0c;你需要另一个分支的所有代码变动&#xff0c;那么就采用 git merge&#xff1b;另一种情…...

在 PostgreSQL 中,如何处理大规模的文本数据以提高查询性能?

文章目录 一、引言二、理解 PostgreSQL 中的文本数据类型三、数据建模策略四、索引选择与优化五、查询优化技巧六、示例场景与性能对比七、分区表八、数据压缩九、定期维护十、总结 在 PostgreSQL 中处理大规模文本数据以提高查询性能 一、引言 在当今的数据驱动的世界中&…...

秋招提前批面试经验分享(下)

⭐️感谢点开文章&#x1f44b;&#xff0c;欢迎来到我的微信公众号&#xff01;我是恒心&#x1f60a; 一位热爱技术分享的博主。如果觉得本文能帮到您&#xff0c;劳烦点个赞、在看支持一下哈&#x1f44d;&#xff01; ⭐️我叫恒心&#xff0c;一名喜欢书写博客的研究生在读…...

零基础STM32单片机编程入门(七)定时器PWM波输出实战含源码视频

文章目录 一.概要二.PWM产生框架图三.CubeMX配置一个TIME输出1KHZ&#xff0c;占空比50%PWM波例程1.硬件准备2.创建工程3.测量波形结果 四.CubeMX工程源代码下载五.讲解视频链接地址六.小结 一.概要 脉冲宽度调制(PWM)&#xff0c;是英文“Pulse Width Modulation”的缩写&…...

【ubuntu自启shell脚本】——在ubuntu中如何使用系统自带的启动应用程序设置开机自启自己的本地shell脚本

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、设置开机自启shell脚本1.使用 gnome-session-properties2.测试的shell例程代码 总结 前言 在Ubuntu系统中设置开机自启脚本是一种重要的自动化方法。开机自…...

nodejs配置国内镜像

# 设置淘宝镜像 npm config set registry https://registry.npmmirror.com# 查看镜像源 npm get registry...

【JavaEE】多线程进阶

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.锁策略1.1悲观锁和乐观锁1.2重量级锁和轻量级锁1.3自旋锁和挂起等待锁1.4可…...

大模型LLM面试常见算法题-包括Attention和Transformer常见面试题

大模型&#xff1a; 位置编码有哪些&#xff1f; 介绍LoRA与QLoRA RAG和微调的区别是什么&#xff1f; 哪些因素会导致LLM的偏见&#xff1f; 什么是思维链&#xff08;CoT&#xff09;提示&#xff1f; Tokenizer的实现方法及原理 解释一下大模型的涌现能力&#xff1f;…...

90元搭建渗透/攻防利器盒子!【硬件篇】

前言 以下内容请自行思考后进行实践。 使用场景 在某些情况下开软件进行IP代理很麻烦&#xff0c;并不能实现真正全局&#xff0c;而且还老容易忘记&#xff0c;那么为了在实景工作中&#xff0c;防止蓝队猴子封IP&#xff0c;此文正现。 正文 先说一下实验效果&#xff1…...

用vue2+elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选

单选注意点&#xff1a; touchmove.prevent: 在 touchmove 事件上添加 .prevent 修饰符&#xff0c;以阻止默认的滚动行为。 handleTouchStart: 记录触摸开始的 Y 坐标和当前的 translateY 值。 handleTouchMove: 计算触摸移动的距离&#xff0c;并更新 translateY 值。 han…...

『古籍自有答案』古风H5案例赏析

「古籍自有答案」&#xff0c;一部由新京报与字节跳动公益联合打造的古风H5&#xff0c;以诗意盎然的开篇引领用户穿梭于千年文脉。 part1. 创意定位 "人生有惑问先贤&#xff0c;先贤答案存古籍"&#xff0c;在这里&#xff0c;每一个灵魂的探问&#xff0c;都能在…...

Laravel模型事件完全指南:触发应用程序的动态行为

标题&#xff1a;Laravel模型事件完全指南&#xff1a;触发应用程序的动态行为 在Laravel框架中&#xff0c;模型事件提供了一种优雅的方式来处理Eloquent模型生命周期中的各种关键时刻。通过监听和响应这些事件&#xff0c;开发者可以自动化许多常见的任务&#xff0c;如日志…...

hot100 |八、二叉树

1-leetcode94. 二叉树的中序遍历 注意&#xff1a;√ 递归方法已经很熟练了&#xff0c;两种不同的递归方式迭代法需要注意&#xff0c;zrm就遇到了要求迭代实现&#xff0c;前序遍历和后续遍历其实不难&#xff0c;中序遍历用的少&#xff0c;注意看一看 // 1.递归方法1Lis…...

Matlab协方差矩阵分解法生成随机场

Matlab协方差矩阵分解法生成随机场 相关系数矩阵 % function outcohesion(x,y,mu,theta) % end % xyload(F:\Research-OUC\基于机器许学习模型的海底斜坡可靠度研究\基于comsol的斜坡稳定性分析\comsol网格操作\grid_operate-matlab.mphtxt); % xxy(:,1); % yxy(:,2); Xlinspac…...

android 在清单文件中配置receiver,系统是何时会注册此广播接收者的?

在 Android 中&#xff0c;通过清单文件&#xff08;AndroidManifest.xml&#xff09;配置的广播接收器&#xff08;BroadcastReceiver&#xff09;&#xff0c;系统会在特定的时机自动注册这些广播接收器。以下是详细的说明&#xff1a; 静态注册的广播接收器 静态注册的广播…...

嵌入式硬件电路常用设计软件

目录 1. Cadence Allegro 2. PADS 3. Altium Designer 4. Multisim 5. Protues 1. Cadence Allegro 功能&#xff1a; Cadence Allegro是Cadence公司推出的先进PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;设计布线工具&#xff0c;也是目前…...

c#的List<T>的SelectMany 和Select

在C#中&#xff0c;List<T>&#xff08;以及任何实现了IEnumerable<T>的集合&#xff09;的Select和SelectMany扩展方法都是LINQ&#xff08;Language Integrated Query&#xff09;的一部分&#xff0c;用于对集合中的元素进行查询和转换。 尽管它们的作用有些相…...

69.WEB渗透测试-信息收集- WAF、框架组件识别(9)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;68.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;8&#xff09; 有无waf存在&am…...

ASCII码对照表(Matplotlib颜色对照表)

文章目录 1、简介1.1 颜色代码 2、Matplotlib库简介2.1 简介2.2 安装2.3 后端2.4 入门例子 3、Matplotlib库颜色3.1 概述3.2 颜色图的分类3.3 颜色格式表示3.4 内置颜色映射3.5 xkcd 颜色映射3.6 颜色命名表 4、Colorcet库5、颜色对照表结语 1、简介 1.1 颜色代码 颜色代码是…...

Mysql-常用函数及其用法总结

1、字符串函数 测试用例如下&#xff1a; 1.1 CONCAT() 将多个字符串连接成一个字符串。 SELECT CONCAT(first_name, , last_name) AS full_name FROM users; -- 期望结果&#xff1a;John Doe, Jane Smith, Michael Johnson 1.2 SUBSTRING() 提取子字符串 SELECT SUBSTR…...

【c++刷题笔记-数组】day29:452. 用最少数量的箭引爆气球、 435. 无重叠区间 、 763.划分字母区间

452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;先按照左边界排序&#xff0c;当前的左边界大于前一个的右边界的时候&#xff0c;表示没有覆盖所以需要一根箭&#xff0c;反之则要更新为最小的右边界 重点&#xff1a;是区间覆盖问题…...

【数据结构】链表带环问题分析及顺序表链表对比分析

【C语言】链表带环问题分析及顺序表链表对比分析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【C语言】链表带环问题分析及顺序表链表对比分析前言一.顺序表和链表对比1.1顺序表和链表的区别1.2缓存利用率&#…...

快速解决找不到krpt.dll,无法继续执行代码问题

对于那些遇到计算机开机出现由于无法找到krpt.dll&#xff0c;进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件&#xff0c;如果它出现问题&#xff0c;可能会对一些特定的软件或游戏的运行产生影响。实际上&#xff0c;我们有多种解决该…...

C# List、LinkedList、Dictionary性能对比

数据结构性能对比 List、LinkedList、Dictionary 1. ArrayList &#xff08;List&#xff1a;前传&#xff09; ArrayList 是一个特殊数组&#xff0c; 通过添加和删除元素就可以动态改变数组的长度。 ArrayList集合相对于数组的优点&#xff1a; 支持…...

【Spring Cloud】微服务的简单搭建

文章目录 &#x1f343;前言&#x1f384;开发环境安装&#x1f333;服务拆分的原则&#x1f6a9;单一职责原则&#x1f6a9;服务自治&#x1f6a9;单向依赖 &#x1f340;搭建案例介绍&#x1f334;数据准备&#x1f38b;工程搭建&#x1f6a9;构建父子工程&#x1f388;创建父…...

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…...

Git管理源代码、git简介,工作区、暂存区和仓库区,git远程仓库github,创建远程仓库、配置SSH,克隆项目

学习目标 能够说出git的作用和管理源代码的特点能够如何创建git仓库并添加忽略文件能够使用add、commit、push、pull等命令实现源代码管理能够使用github远程仓库托管源代码能够说出代码冲突原因和解决办法能够说出 git 标签的作用能够使用使用git实现分支创建&#xff0c;合并…...

【机器学习】机器学习与时间序列分析的融合应用与性能优化新探索

文章目录 引言第一章&#xff1a;机器学习在时间序列分析中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 自回归模型1.2.2 移动平均模型1.2.3 长短期记忆网络1.2.4 卷积神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 A…...

执行力不足是因为选择模糊

选择模糊&#xff1a;执行力不足的根源 选择模糊是指在面对多个选项时&#xff0c;缺乏明确的目标和方向。这种模糊感会导致犹豫不决&#xff0c;进而影响我们的执行力。 选择模糊的表现&#xff1a; 目标不明确&#xff0c;不知道应该做什么。优先级混乱&#xff0c;不清楚…...

力扣 225题 用队列实现栈 记录

题目描述 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素…...