原创 | Git仓库的提交记录乱成一团,怎么办?
大家好,今天和大家聊聊git当中一个非常好用的功能——区间选择,它可以帮我们处理看起来非常复杂的提交记录。从而帮助我们很快找到我们需要的内容。
如果大家有参与过多人协同的项目开发,比如十几个人甚至更多的成员的时候,会发现一些分支的记录非常的混乱,比如master。因为其中包含了太多的提交信息,比如各种分支的merge记录,以及线上bugfix等。这个时候使用区间选择就非常有必要,它会帮助我们过滤掉不需要的提交记录,快速找到我们想要的结果。
区间选择
关于区间选择我们之前在介绍rebase的时候曾经提到过一次:
git rebase --onto master feature bugFix
当我们执行这条命令之后,git会将在bugFix分支当中但是不在feature分支里的内容rebase到master分支。这其实就是一种区间选择,我们把两个分支之间的差集选择了出来。当然这是在rebase当中的应用,那么我们能不能把这种形式应用在日志搜索上呢?
当然是可以的,最常用指明区间的语法是双点。它的用法是两个英文句号,它可以让git选出在一个分支但是不在另外一个分支当中的提交,比如:
git log master..experiment
这个语句的含义就是筛选出在experiment当中但是不在master当中的提交。我们来看一张图,会更加地直观:
我们执行上面的命令之后,得到的结果就是C和D这两个节点的提交记录。
如果我们想要反其道而行之,想要获得在master,但是不在experiment,也就是查看我们在开发experiment这个分支的过程当中master进行了哪些改动,我们可以将前后两个分支名交换顺序。
git log experiment..master
这样我们得到的结果是E、F两个节点。
另外一个使用场景是在我们进行push之前进行检查,查看我们究竟做了哪些改动,哪些commit会被更新到远端。这个时候我们比较的是当前节点以及远程push的分支之间的差别,我们可以这样:
git log origin/master..HEAD
对于这个功能Git进行了优化, 我们可以省去最后的HEAD,git会默认使用HEAD代替留空的情况。
三点及多点
除了上面使用的双点语法之外,git当中还提供了三点以及多点的语法,我们先来说说三点的语法。
三点
其实三点的功能本质上和双点是一样的,可以认为是在双点的基础上做了一点优化,让我们使用起来更加方便。在真实的使用场景当中,我们往往既需要知道我们正在开发的feature带来的提交,也需要知道master后来进行的改动。这样的话,我们会需要执行git log两次,所以git提供了三点的语法,将两次执行压缩成了一次,通过使用三点语法,我们可以只需要执行一次就可以获得的结果。
git log master...experiment
当我们执行这个命令之后,git会展示这两个分支各自独有的提交,以上图举例,它的执行结果应该是C、D、E、F这四个节点。
但是这有一个问题,我们光看其实是不知道这四个节点分别属于哪个分支的,我们可以加上参数,--left-right,它会用箭头表明这些提交分别被哪个分支独有。
git log --left-right master...experiment
< F
< E
> D
> C
多点
有的时候我们的提交情况可能会比较复杂,可能有多个分支糅杂在一起,你可能未必确定某一个改动的源头。这个时候我们可能需要一个复杂的表达式才能把我们想要查看的提交记录表达清楚。
比如说我们现在有A、B、C三个分支,我们想要查看在A或和B当中,但是不在C当中的提交。我们可以这样写:
git log A B ^C
git log A B --not C
上面的两条语句都是可以的,第一条我们用^表示了not的意思,第二条比较直观,我们直接加上前缀来表示。这就是多点的用法,它支持我们定义多个来源,这样一些复杂的情况就会非常方便。git默认多个来源之间是或的关系,这也是非常符合实际的。大家可以思考一下这个问题。
多点同样也兼容双点的情况,双点操作有一个问题是我们经常会搞混比较的主体,这个时候我们完全可以使用多点的语法来代替。
git log A ^B
git log A --not B
掌握了多点和双点之后,我们就可以应付各种复杂场景下的log排查了,再加上之前介绍过的git show等功能,对于提升我们搜索git log的速度非常有帮助。这么几个命令掌握下来,使用起来的气质就不一样,会给你一种自己已经是技术大牛的感觉。
今天的文章就到这里,希望大家都能有这种感觉。如果还喜欢本文的话,请来个三连支持吧!(点赞、关注、转发)
- END -
- python contextlib 上下文管理器
- Django扩展自定义manage命令
- Elasticsearch分片、副本与路由(shard replica routing)
- EsRejectedExecutionException排错与线程池类型
- python重试(指数退避算法)
- 动手为王 | Oracle 数据库跨版本升级迁移实践
- 日志归档与数据挖掘
- Redis实现分布式锁
- Mybatis分页插件PageHelper的配置和使用方法
- 另类保存微信公众平台历史消息的方法 - 星标消息
- CentOS环境下Docker私有仓库搭建
- spark三种连接join
- 用firebug给firefox添加信任链接
- Elasticsearch索引别名、Filtered索引别名、Template
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【拓展】745- Windows Server 升级 HTTPS 实战
- 【Web技术】746- VSCode 插件开发入门教程
- Python实现ARMA模型
- SpringMVC笔记
- JAVA入门学习五
- ECMAScript 6新特性简介
- Python 多维数据可视化
- 探究Compound治理及构建治理界面
- python之unittest框架实现接口测试的一个简单实例
- linux提权-Suid和Guid配置错误
- Git快速学习
- Spring笔记
- ARL灯塔最新版本2.1,现在它来了,快来看看盒子带来了什么有趣的更新
- 渗透测试常规操作记录(下)
- IntelliJ IDEA 2020.2激活破解教程