【git使用】了解三种git commit合并的使用场景(rebase、merge、cherry-pick)

参考

  • 【Git学习笔记】逃不掉的merge和rebase-腾讯云开发者社区-腾讯云
  • git merge 和 git rebase - 知乎
  • git cherry-pick 教程 - 阮一峰的网络日志

简单理解各种合并的方法

  • 线性合并,使用 rebase —— feature 分支开发,提交前拉取 master 最新改动进行合并
  • 保留合并历史,使用 merge,会产生一个新的 commit —— master 分支合并 feature
  • 挑选别的分支某几个 commit 进行合并,使用 cherry-pick

git rebase 使用场景 —— 线性合并

  • 本地 feature 分支开发完成后,想要给远端 master 提交一个合并的 PR,此时发现远端 master 分支已经提交了很多 feature,就是本地 master 分支落后远端 master 分支多个 commit
# 1. 备份,将当前分支 feature 推到远端
git push origin feature# 2. 切换到本地 master 分支,并拉取远端最新 master
git checkout master
git pull origin master# 3. 切换到自己 feature 分支,采用 rebase 合并,不像 merge 会产生新分支
git checkout feature
git rebase master  # 直接执行 esc :q 就行
# 若有冲突就进行解决,之后再执行 git rebase --continue
# 合并完成后,git log 会发现本地 feature 分支已合并了远端 master 分支新增的 commit,
# 本地 feature 开发提交的 commit 会在远端 master 新增 commit 之后,不会产生新的 commit,是线形的# 4. 推送到远端,覆盖
git push origin feature --force# 5. 提交 pr 到远程仓库的 master 分支# 注意
# git rebase ,想要合并到哪个分支,就先切换到那个分支,然后执行 git rebase {另一个分支名}
# 如,有两个分支 A  和 B,A 想要 B 分支的新增 commit
git checkout A
git rebase B
# git log 查看历史就是   A和B 共同的 commit --> B-commit --> A-commit(HEAD)
        +---------------+       +---------------+
------->| master branch |------>| new commit-A  |+---------------+       +---------------+|                                |                                v                                +---------------+       +---------------+
------->|featrue branch |------>|   commit-B    |+---------------+       +---------------+# git pull origin master        
# git checkout feature
# git rebase master
# 通过 git log --graph 即可看到合并历史信息,如下是个线形的,但没有清楚记录从哪个分支合并的(merge 可以记录)+---------------+       +---------------+       +---------------+
------->|featrue branch |------>| new commit-A  |------>|   commit-B    |+---------------+       +---------------+       +---------------+

git rebase 使用场景 —— 保留合并历史

  • 假设 A,B 两个人,都是基于当前 master 分支进行开发,开发不同的功能,但是可能会对相同文件进行改动(也可能不会)
  • A 首先完成,提交 pr 到 master 分支,master 分支维护者进行合并,这时候没有冲突,直接合并,但会产生一个新的 merge commit(该 commit 无文件更改,就是个说明)
  • 这时候 B 也完成了,提交 pr 到 master 分支,master 分支维护者进行合并,这时候可能会有冲突,解决后,也会产生一个新的 merge commit(该 commit 可能文件更改,解决冲突)
  • 可以看到下面
# git checkout master 
# git merge A  (合并 A 分支到 master 分支)
# 生成一个 merge commit A
# git merge B  (合并 B 分支到 master 分支)
# 生成一个 merge commit B
# 可以看到下面记录了 合并的历史信息 ,通过 git log --graph 即可看到合并历史信息+---------------+       +---------------+                                       |   A branch    |------>|   commit-A    |--------+                              +---------------+       +---------------+        |                              ^                                        |                              |                                        v                              +---------------+                        +---------------+     +---------------+
------->| master branch |----------------------->|merge-commit-A |---->|merge-commit-B |+---------------+                        +---------------+     +---------------+|                                                              ^        v                                                              |        +---------------+            +---------------+                         |        |   B branch    |----------->|   commit-B    |-------------------------+        +---------------+            +---------------+                                  

git cherry-pick 使用场景 —— 挑选 commit 进行合并

  • 上面 merge 和 rebase,都是将所有新增的 commit 进行合并
  • 那么若只想挑选几个 commit 进行合并呢? —— cherry-pick 应运而生
  • 若 A 分支新增了几个 commit,如 commit-a1、commit-a2、commit-a3、commit-a4
# 现 master 分支只想要 commit-a2
git checkout master
git cherry-pick commit-a2
git cherry-pick --continue# 现 master 分支想要 a2到a4 的commit
git checkout master
# 范围符号是两个点  ..
# 注意! 首个commit一定要有 ^ 符号,否则不包含 首个 commit
# 如 commit-a2..commit-a4  表示合并 commit-a3 、 commit-a4 到 master 分支
git cherry-pick commit-a2^..commit-a4
git cherry-pick --continue

rebase 和 merge 的基本原则

  • 【Git学习笔记】逃不掉的merge和rebase-腾讯云开发者社区-腾讯云

  • git merge 和 git rebase - 知乎

  • 下游分支更新上游分支内容的时候使用 rebase;

  • 上游分支合并下游分支内容的时候使用 merge;

在 dev 上开发了一段时间后要把 master 分支提交的新内容更新到 dev 分支,此时切换到 dev 分支,使用 git rebase master,等 dev 分支开发完成了之后,要合并到上游分支 master 上的时候,切换到 master 分支,使用 git merge dev。

因为自己一直用的都是merge,以前完全没听过还有rebase这个命令

后来被问了,一脸懵逼,所以研究了一下,才发现rebase好像也有点东西

git merge

先构造一下环境

git init# mater初始化提交
touch master.txt
git add .
git commit -m "init master"# master第一次提交
# master.txt第一行加个1
git add .
git commit -m "commit 1"# 拉取feature分支
git branch feature# master第二次提交
# master.txt第二行加个2
git add .
git commit -m "commit 2"# master第三次提交
# master.txt第三行加个3
git add .
git commit -m "commit 3"# 到feature分支,进行提一次冲突提交
# master.txt第二行加个feature change1
git switch feature
git add .
git commit -m "confict1"# 进行提一次冲突提交
# master.txt第三行加个feature change2
git add .
git commit -m "confict2"

好了这个时候准备工作就完成了

现在master要merge feature分支的更新

git switch master
git merge feature# 解决完冲突后git add .
git commit -m "merged feature"

这是 git merge的流程

我们可以来看下此时的log:

git log --graph --pretty=oneline

master上的日志分支出现了feature分支的提交

也就是说,merge的流程是,将分支的改动合并到当前分支后,再形成一个新的commit

这只是一条分支,一旦分支多了,merge多了,可以想象master的提交记录将会是多么可怕…

这个时候,如果单纯只是为了保持master分支的纯净,使其的日志以一条线性的方式存在,看起来就会比较清晰。

git rebase

顾名思义 —— 变基

我的理解就是将当前所在的分支作为目标分支的新基线

还是先来跑一下,新找个目录:

git init# mater初始化提交
touch master.txt
git add .
git commit -m "init master"# master第一次提交
# master.txt第一行加个1
git add .
git commit -m "commit 1"# 拉取feature分支
git branch feature# master第二次提交
# master.txt第二行加个2
git add .
git commit -m "commit 2"# master第三次提交
# master.txt第三行加个3
git add .
git commit -m "commit 3"# 到feature分支,进行提一次冲突提交
# master.txt第二行加个feature change1
git switch feature
git add .
git commit -m "confict1"# 进行提一次冲突提交
# master.txt第三行加个feature change2
git add .
git commit -m "confict2"

这个时候,用一下rebase:

# 切回master分支
git switch master# 使用rebase
git rebase -i feature# 解决冲突

这样rebase之后,我们用相同的方式来看下master的日志:

你看,就是完全线性的了

rebase的过程实际就是以当git 前最新的master的版本,再"拉"出一条分支作为当前最新的分支上,原先该分支上的改动就变成现在分支上的新的commit 了

单从master的提交记录来看,rebase之后的日志记录是线性的,肯定是舒适很多

那么问题来了:那不是都用rebase就好了吗,用啥merge操作呢?

使用场景是纯个人看法:

1、个人开发分支管理使用rebase

比如我们现在在feature分支上开发我们新功能,master正常迭代

feature开发到一半,master迭代的很多了,再不更新你的feature就会导致和master的偏移越来越大

这个时候获取最新的master代码,merge的话刚刚看了,别的分支的commit记录乱的一批全混到你的分支来了

重新拉一条分支,本地的改动备份还原又不方便

看来看去,rebase算是最好的选择了,可以线性化个人分支的commit

版本追溯起来更清晰,roll back 也更方便

2、master(公共分支)使用merge

这个我觉得应该没毛病,公共分支上的commit历史还是不能去篡改的,所以老老实实git merge --no-ff 好了

git cherry-pick

  • git cherry-pick 教程 - 阮一峰的网络日志

一、基本用法

git cherry-pick命令的作用,就是将指定的提交(commit)应用于其他分支。

$ git cherry-pick <commitHash>

上面命令就会将指定的提交commitHash,应用于当前分支。这会在当前分支产生一个新的提交,当然它们的哈希值会不一样。

举例来说,代码仓库有masterfeature两个分支。

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

现在将提交f应用到master分支。

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

上面的操作完成以后,代码库就变成了下面的样子。

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

从上面可以看到,master分支的末尾增加了一个提交f

git cherry-pick命令的参数,不一定是提交的哈希值,分支名也是可以的,表示转移该分支的最新提交。

$ git cherry-pick feature

上面代码表示将feature分支的最近一次提交,转移到当前分支。

二、转移多个提交

Cherry pick 支持一次转移多个提交。

$ git cherry-pick <HashA> <HashB>

上面的命令将 A 和 B 两个提交应用到当前分支。这会在当前分支生成两个对应的新提交。

如果想要转移一系列的连续提交,可以使用下面的简便语法。

$ git cherry-pick A..B 

上面的命令可以转移从 A 到 B 的所有提交。它们必须按照正确的顺序放置:提交 A 必须早于提交 B,否则命令将失败,但不会报错。

注意,使用上面的命令,提交 A 将不会包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的语法。

$ git cherry-pick A^..B 

三、配置项

git cherry-pick命令的常用配置项如下。

(1)-e--edit

打开外部编辑器,编辑提交信息。

(2)-n--no-commit

只更新工作区和暂存区,不产生新的提交。

(3)-x

在提交信息的末尾追加一行(cherry picked from commit ...),方便以后查到这个提交是如何产生的。

(4)-s--signoff

在提交信息的末尾追加一行操作者的签名,表示是谁进行了这个操作。

(5)-m parent-number--mainline parent-number

如果原始提交是一个合并节点,来自于两个分支的合并,那么 Cherry pick 默认将失败,因为它不知道应该采用哪个分支的代码变动。

-m配置项告诉 Git,应该采用哪个分支的变动。它的参数parent-number是一个从1开始的整数,代表原始提交的父分支编号。

$ git cherry-pick -m 1 <commitHash>

上面命令表示,Cherry pick 采用提交commitHash来自编号1的父分支的变动。

一般来说,1号父分支是接受变动的分支(the branch being merged into),2号父分支是作为变动来源的分支(the branch being merged from)。

四、代码冲突

如果操作过程中发生代码冲突,Cherry pick 会停下来,让用户决定如何继续操作。

(1)--continue

用户解决代码冲突后,第一步将修改的文件重新加入暂存区(git add .),第二步使用下面的命令,让 Cherry pick 过程继续执行。

$ git cherry-pick --continue

(2)--abort

发生代码冲突后,放弃合并,回到操作前的样子。

(3)--quit

发生代码冲突后,退出 Cherry pick,但是不回到操作前的样子。

五、转移到另一个代码库

Cherry pick 也支持转移另一个代码库的提交,方法是先将该库加为远程仓库。

$ git remote add target git://gitUrl

上面命令添加了一个远程仓库target

然后,将远程代码抓取到本地。

$ git fetch target

上面命令将远程代码仓库抓取到本地。

接着,检查一下要从远程仓库转移的提交,获取它的哈希值。

$ git log target/master

最后,使用git cherry-pick命令转移提交。

$ git cherry-pick <commitHash>

(完)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识HTTP协议

Web服务器可以接收浏览器的请求&#xff0c;并将服务器中的web项目资源响应给浏览器&#xff0c;浏览器与服务器之间进行网络通信遵循HTTP协议。 一、什么是HTTP协议 超文本传输协议&#xff08;HTTP&#xff0c;HyperText Transfer Protocol&#xff09;(浏览器---->web服务…

微信小程序:flex常用布局

在我们平时微信小程序开发过程中为了页面能达到设计小伙伴的预期&#xff0c;追求还原度&#xff0c;那我们肯定会使用很多常用的布局方式&#xff0c;那我们今天就介绍一下微信小程序中常用的一些flex布局 1、常用flex布局 /** 水平垂直居中 **/ .flex-center {display: fle…

vue3+vant4 移动端软键盘弹出 收起导致项目样式布局错乱解决方案,亲测有效!!

问题描述 最近在做vue3 H5的移动端项目 我用的是vue3vant4&#xff0c;然后在使用过程中发现 小米14手机在点击密码输入框软键盘弹出 时会导致项目布局整体向上移动 导致页面布局错乱。 原因分析&#xff1a; 在移动端软键盘弹出收起时&#xff0c;导致项目样式布局错乱的原因…

基于STM32的ESP8266 WiFi模块数据采集与显示

基于STM32的ESP8266 WiFi模块数据采集与显示是一种常见的嵌入式系统应用&#xff0c;通常用于远程数据监测和控制。在这种应用中&#xff0c;STM32作为主控制器负责采集周围环境的数据&#xff0c;通过ESP8266 WiFi模块将数据发送到远程服务器&#xff0c;并在远程服务器上进行…

03-微服务-Ribbon负载均衡

Ribbon负载均衡 1.1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件&#xff0c;来实现负载均衡功能的。 那么我们发出的请求明明是http://userservice/user/1&#xff0c;怎么变成了http://localhost:8081的呢&#xff1f; 1.2.源码跟踪 为什么我们只输入…

小梅哥Xilinx FPGA学习笔记20——无源蜂鸣器驱动设计与验证(音乐发生器设计)

目录 一&#xff1a;章节导读 二&#xff1a;无源蜂鸣器驱动原理 三&#xff1a;PWM 发生器模块设计 3.1 PWM 发生器模块框图 3.2 PWM 发生器模块接口功能描述 3.3 PWM波生成设计文件代码 3.4 测试仿真文件 3.5 测试仿真结果 3.6 板级调试与验证之顶层文件设计 四&am…

Python:界面开发,wx入门篇

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/3Yb_YAKiMte_f5HanetXiA 本文大概 3617 个字&#xff0c;阅读需花 10 分钟 内容不多&#xff0c;但也花了一些精力 如要交流&#xff0c;欢迎评…

@Scheduled定时任务现状与改进

项目场景&#xff1a; 定时任务现状&#xff1a;每个项目都会有一些配置信息&#xff0c;这些信息我们是都放在一个配置服务中&#xff0c;这个服务会定时从配置表中加载所有配置存入本地JVM内存&#xff0c;以供调用方获取&#xff08;调用方集成了配置服务的SDK&#xff0c;…

elasticsearch的查询方式和数据库事务隔离级别的思考

项目中用到了 elasticsearch&#xff0c;发现有几种查询方式不太一样&#xff0c;思考了一下&#xff0c;总结如下 普通分页 等同于关系数据库的分页查询&#xff0c;例如 mysql 的 limit&#xff0c;如下 sql select * from test limit 100000,10 这种查询方式有一个问题&a…

系列十一、(一)Sentinel简介

一、Sentinel简介 1.1、官网 【英文文档】 https://github.com/alibaba/Sentinel/wiki【中文文档】 https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5 1.2、概述 1.3、功能

网络路由跟踪工具

随着企业网络需求的增长&#xff0c;组织发现监控和管理其网络基础设施变得越来越困难。网络管理员正在转向其他工具和资源&#xff0c;这些工具和资源可以使他们的工作更轻松一些&#xff0c;尤其是在故障排除方面。 目前&#xff0c;网络管理员主要使用简单、免费提供的实用…

在win10上cuda12+tensorrt8.6+vs2019环境下编译paddle2.6生成python包与c++推理库

paddle infer官方目前没有发布基于cuda12的c库&#xff0c;为此参考https://www.paddlepaddle.org.cn/inference/user_guides/source_compile.html实现cuda12的编译安装&#xff0c;不料博主才边缘好自己的paddle2.6&#xff0c;paddle官方已经发布了cuda12.0的paddle2.6框架。…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)Buffer的创建和销毁、扩容、写入数据

TcpConnection:封装的就是建立连接之后得到的用于通信的文件描述符&#xff0c;然后基于这个文件描述符&#xff0c;在发送数据的时候&#xff0c;需要把数据先写入到一块内存里边&#xff0c;然后再把这块内存里边的数据发送给客户端&#xff0c;除了发送数据&#xff0c;剩下…

基于综合特征的细菌噬菌体宿主预测工具iPHoP (Integrated Phage HOst Prediction)的介绍以及使用方法详细流程

介绍 iPHoP&#xff08;Integrated Phage HOst Prediction&#xff09;是一种基于综合特征的细菌噬菌体宿主预测方法。它是通过整合基因组序列、蛋白质序列和宿主基因组信息来预测细菌噬菌体的宿主范围。 iPHoP的预测过程分为三个步骤&#xff1a;特征提取、特征选择和宿主预…

【Spring实战】21 Spring Data REST 常用功能详细介绍

文章目录 1. 资源导出&#xff08;Resource Exporting&#xff09;2. 查询方法&#xff08;Query Methods&#xff09;3. 分页和排序&#xff08;Pagination and Sorting&#xff09;4. 关联关系&#xff08;Associations&#xff09;5. 事件&#xff08;Events&#xff09;6. …

“华为杯”杭州电子科技大学2023新生编程大赛---树

题目链接 Problem Description 给定一棵包含 n 个节点的带边权的树&#xff0c;树是一个无环的无向联通图。定义 xordist(u,v) 为节点 u 到 v 的简单路径上所有边权值的异或和。 有 q 次询问&#xff0c;每次给出 l r x&#xff0c;求 ∑rilxordist(i,x) 的值。 Input 测试…

JVM之内存模型带参数

Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里)&#xff1a; java ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize256M ‐XX:MaxMetaspaceSize256M ‐jar xxxxxx.jar-Xss&#xff1a;每个线程的栈大小 -Xms&#xff1a;设置…

关于“Python”的核心知识点整理大全61

目录 注意 20.1.4 使用 jumbotron 设置主页的样式 index.html 20.1.5 设置登录页面的样式 login.html 20.1.6 设置 new_topic 页面的样式 new_topic.html 20.1.7 设置 topics 页面的样式 topics.html 元素&#xff0c;让它们在页面上显得大些&#xff08;见2&#xf…

imgaug库指南(三):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

prometheus与zabbix监控的对比介绍

一、普米与zabbix基本介绍 1、prometheus介绍 Prometheus的基本原理是Prometheus Server通过HTTP周期性抓取被监控组件的监控数据&#xff0c;任意组件只要提供对应的HTTP接口并且符合Prometheus定义的数据格式&#xff0c;就可以接入Prometheus监控。 工作流程大致分为收集数…