三行代码让你的git记录保持整洁

前言
笔者最近在主导一个项目的架构迁移工作,由于迁移项目的历史包袱较重,人员合作较多,在迁移过程中免不了进行多分支、多次commit的情况,时间一长,git的提交记录便混乱不堪,随便截一个图形化的git提交历史给大家感受一下。

各种分支疯狂打架宛如后宫争宠的妃子们,之所以会出现这种情况,主要还是因为滥用git merge命令并且不考虑后续的理解成本导致的。如今在大厂工作的程序员们,频繁接受变更的需求,一旦一开始考虑不周到,就一定会出现了大量无意义的commit log,加上“敏捷”理念的推广,产品的快速迭代上线变成了核心指标,这些无意义的commit log便被“下次再处理”,久而久之就混乱不堪了。
而我们在看一些开源仓库时,会发现他们的commit记录十分整洁,其实这并不是社区的程序员能力更强,而是因为他们没有KPI大棒的鞭笞,在提交代码前会花时间整理自己的commit log。而这就是本文的主角了——“Git Rebase”。
git rebase和git merge
git rebase,中文翻译为“变基”,通常用于分支合并。既然提到了分支合并,那就一定离不开git merge这个命令。
相信每个新手程序员刚进入职场的时候,都会听到“xxx你把这个分支merge一下”这样的话。那么问题来了,假如你有6个程序员一起工作, 你就会有6个程序员的分支, 如果你使用merge, 你的代码历史树就会有六个branch跟这个主的branch交织在一起。

上图是 git merge 操作的流程示意图,Merge命令会保留所有commit的历史时间。每个人对代码的提交是各式各样的。尽管这些时间对于程序本身并没有任何意义。但是merge的命令初衷就是为了保留这些时间不被修改。于是也就形成了以merge时间为基准的网状历史结构。每个分支上都会继续保留各自的代码记录,主分支上只保留merge的历史记录。子分支随时都有可能被删除。子分子删除以后,你能够看到的记录也就是,merge某branch到某branch上了。这个历史记录描述基本上是没有意义的。
而 git rebase 中文翻译为“变基”,变得这个基指的是基准。如何理解这个基准呢?我们看一下下图。

我们可以看到经过变基后的feature分支的基准分支发生了变化,变成了最新的master。这就是所谓的“变基”。
通过上面的两张图可以很明显的发现,这两种合并分支的方式最大的区别在于,merge后的分支,会保留两个分支的操作记录,这在git commit log 树中会以交叉的形式保存。而rebase后的分支会基于最新的master分支,从而不会形成分叉,自始至终都是一条干净的直线。
关于
git rebase和git merge的详细用法不在本文的介绍范围内,详情可以参考互联网上的其他资料。
在变基过程中,我们通常需要进行commit的修改,而这也为我们整理git记录提供了一个可选方案。
保持最近的几条记录整洁
假设我们有一个仓库,我在这个仓库里执行了4次提交,通过 git reflog 命令查看提交记录如下。

如果我们想将Commit-3、Commit-2和Commit-1的提交合并成一次提交(假设某次提交至改了一些pom文件),我们可以直接执行下面的命令
git rebase -i HEAD~3-i 指的是 --interactive ,HEAD~3 指的是最近三次commit。
当然我们也可以直接指定最新的一个想保留的 Commit的ID,在上面的例子中就是Commit-0的ID,因此我们也可以写成
git rebase -i d2b9b78执行该命令后,我们会进入到这么如下一个界面:

这个界面是一个Vim界面,我们可以在这个界面中查看、编辑变更记录。有关Vim的操作,可以看我之前写的文章和录制的视频👉《和Vim的初次见面》
在看前三行之前,我们先来看一下第5行的命令加深一下我们对git rebase的认识。

翻译过来就是,将d2b9b78..0e65e22这几个分支变基到d2b9b78这个分支,也就是将Commit-3/2/1/0这几次变更合并到Commit-0上。
回到前面三行,这三行表示的是我们需要操作的三个 Commit,每行最前面的是对该 Commit 操作的 Command。而每个命令指的是什么,命令行里都已经详细的告诉我们了。

pick:使用该commitsquash:使用该 Commit,但会被合并到前一个 Commit 当中fixup:就像squash那样,但会抛弃这个 Commit 的 Commit message
因此我们可以直接改成下面这样

这里使用fixup,而不是squash的主要原因是squash会让你再输入一遍commit的log,图省事的话,可以无脑选择fixup模式。
然后执行:wq退出vim编辑器,我们可以看到控制台已经输出Successful了。

这个时候我们再来看下log 记录,执行git log --oneline
于是最近三次的提交记录就被合并成一条提交记录了。
保持中间某些记录整洁
那如果不是最后的几个commit合并,而是中间连续的几个Commit记录,可以用上述方法整理合并吗?答案是可以的,只不过需要注意一下。
我们重新创建一个新的仓库

如果这次我们想将"third commit"和"second commit"合并为一个提交,其实和上面的方式一样,我们只需执行git rebase -i HEAD~3,然后将中间的提交改成fixup/squash模式即可,如下图所示:

之所以是HEAD~3,是因为我们要做的变更是基于first commit做的,因此我们也可以写成
git rebase -i a1f3929
我们来看下更改完的commit log,如下图所示:

是不是就干掉了third commit了。
三行代码让git提交记录保持整洁
上面我们都是在本地的git仓库中进行的commit记录整理,但是在实际的开发过程中,我们基本上都是写完就直接push到远程仓库了,那应该如何让远程的开发分支也保持记录的整洁呢?
第一种做法是在push代码前就做在本地整理好自己的代码,但是这种做法并不适用于那种本地无法部署,需要部署到远程环境才能调试的场景。
这时我们只需要执行git push -f命令,将自己的修改同步到远程分支即可。
-f是force强制的意思,之所以要强制推送是因为本地分支的变更和远程分支出现了分歧,需要用本地的变更覆盖远程的。
而远程分支更新后,如果其他人也在这条分支上更改的话,还需要执行一个git pull命令来同步远程分支。
这里我们来总结下让git提交记录保持整洁的三行代码。
git rebase -i xxx
git push -f
git pull❗️❗️❗️Tips:由于rebase和push -f是有些危险的操作,因此只建议在自己的分支上执行哦。
相关文章:
三行代码让你的git记录保持整洁
前言笔者最近在主导一个项目的架构迁移工作,由于迁移项目的历史包袱较重,人员合作较多,在迁移过程中免不了进行多分支、多次commit的情况,时间一长,git的提交记录便混乱不堪,随便截一个图形化的git提交历史…...
阿里巴巴内网 Java 面试 2000 题解析(2023 最新版)
前言 这份面试清单是今年 1 月份之后开始收集的,一方面是给公司招聘用,另一方面是想用它来挖掘在 Java 技术栈中,还有一些知识点是我还在探索的,我想找到这些技术盲点,然后修复它,以此来提高自己的技术水平…...
网络应用之静态Web服务器
静态Web服务器-返回固定页面数据学习目标能够写出组装固定页面数据的响应报文1. 开发自己的静态Web服务器实现步骤:编写一个TCP服务端程序获取浏览器发送的http请求报文数据读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。HTTP响应报文数据发送完…...
IndexDB 浏览器服务器
IndexDB 浏览器服务器 文章部分内容引用: https://www.ruanyifeng.com/blog/2018/07/indexeddb.html https://juejin.cn/post/7026900352968425486#heading-15 基本概念 数据库:IDBDatabase 对象对象仓库:IDBObjectStore 对象索引࿱…...
追梦之旅【数据结构篇】——详解C语言实现链队列
详解C语言实现链队列~😎前言🙌整体实现内容分析💞预备小知识🙌1.链队列头文件编写🙌2.链队列功能文件(Queue.c )编写:🙌1)初始化函数实现2)销毁函…...
SpringMVC - 13 - SpringMVC执行流程
文章目录1、SpringMVC常用组件2、DispatcherServlet初始化过程a>初始化WebApplicationContextb>创建WebApplicationContextc>DispatcherServlet初始化策略3、DispatcherServlet调用组件处理请求a>processRequest()b>doService()c>doDispatch()d>processDi…...
6091: 斐波那契数列
描述一个斐波那契序列,F(0) 0, F(1) 1, F(n) F(n-1) F(n-2) (n>2),根据n的值,计算斐波那契数F(n)。输入输入数据的第一行为测试用例的个数t,接下来为t行,每行为一个整数n(2≤n≤40)。输出…...
任何人均可上手的数据库与API搭建平台
编写API可能对于很多后端开发人员来说,并不是什么难事儿,但如果您主要从事前端功能,那么可能还是有一些门槛。 那么有没有工具可以帮助我们降低编写API的学习门槛和复杂度呢? 今天就来给大家推荐一个不错的开源工具:…...
Ubuntu(虚拟机)的Anaconda 及使用
安装Anaconda 使用firefox打开Ananconda网址Anaconda | The Worlds Most Popular Data Science Platform 下载后有.sh文件: Anaconda3-2022.10-Linux-x86_64.sh 进入所在目录打开终端并输入 $ bash Anaconda3-2022.10-Linux-x86_64.sh 然后开始安装。 对于给…...
Git ---- IDEA集成 GitHub
Git ---- IDEA集成 GitHub1. 设置 GitHub 账号2. 分享工程到 GitHub3. push 推送本地库到远程库4. pull 拉取远程库到本地库5. clone 克隆远程库到本地1. 设置 GitHub 账号 新版的 IDEA 选择之后会自动登录,就不需要设置 token 了。 如果是老版的 IDEA 的话&…...
opencv提取结构化文本总结
扫描文件表格识别 1.识别结构 situation1 有明确表格结构 1.纠正表格偏移角度(获取最大轮廓,计算最小的矩形,变换坐标截取矩形) 获取面积最大轮廓 _, contours, HIERARCHY cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2…...
JVM知识体系学习八:OOM的案例(承接上篇博文,可以作为面试中的案例)
文章目录前言一、概述二、案例二三、案例:方法区内存溢出1、代码:LambdaGC.java2、元空间内存溢出日志3、分析4、疑问*****四、案例:直接内存溢出问题(少见)(尽量不说)五、案例:栈内存溢出问题1…...
Redis的持久化方式
Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式,两种持久化方式可以单独使用其中一种,也可以将这两种方式结合使用。 •RDB:根据指定的规则“定时”将内存中的数据存储在硬…...
【unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity游戏制作 ⭐mango的冒险场景二——镜头和法球特效跟随⭐ 文章目录⭐mango的冒险场景二——镜…...
handwrite-1
-------------------- 实现防抖函数(debounce) 防抖函数原理:把触发非常频繁的事件合并成一次去执行 在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算…...
【一天一门编程语言】Pascal 语言程序设计极简教程
Pascal 语言程序设计极简教程 用 markdown 格式输出答案。 不少于3000字。细分到2级目录。 文章目录 Pascal 语言程序设计极简教程一、Pascal简介1.1 Pascal历史1.2 Pascal的特点1.3 Pascal的应用二、Pascal语言程序设计2.1 Pascal编程环境2.2 Pascal的基本语法2.3 Pascal程序…...
【基础篇0】Linux下ANACONDA与TF-LITE环境配置
0 写在前面:一些摸索与总结 对于Linux系统,我发现不管是电脑x86的Ubuntu还是树莓派arm的raspberry系统,在系统安装完毕后,总是自带一个特定版本的python. 例如我的ubuntu22.04自带的python版本是3.10,而高版本的py…...
TCP协议原理二
文章目录四、滑动窗口二、流量窗口三、拥塞控制四、滑动窗口 前面我们学习了 确认应答,超时重传,连接管理,这些机制都为我们TCP的可靠性提供了保证,当然在保证TCP的可靠性的同时,传输效率也受到了一定的影响ÿ…...
电子科技大学网络协议(TCP/IP作业答案)--网工(五次作业汇总)
目录 作业1:OSI/RM、TCP/IP编址和底层网络技术 作业2:IP地址规划与路由选择 作业3:ARP、IP、ICMP 作业4:UDP、Routing Protocol 作业五 作业1:OSI/RM、TCP/IP编址和底层网络技术 物理地址属于OSI/RM的哪一层&…...
Kubernetes集群声明式文件YAML
一、YAML介绍 YAML 的意思是:仍是一种标记语言,但为了强调这种语言以数据做为中心,而不是以标记语言为重点。是一个可读性高,用来表达数据序列的格式。 二、基本语法 1.低版本缩进时不允许使用Tab键,只允许使用空格…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
