猿猿有责,维持整洁的 Git 提交记录,三个锦囊送给你
背景
大家都有学习如何规范简洁的编写代码,但却很少学习如何规范简洁的提交代码。现在大家基本上都用 Git 作为源码管理的工具,Git 提供了极大的灵活性,我们按照各种 workflow 来提交/合并 code,这种灵活性把控不好,也会带来很多问题
最常见的问题就是乱成一团的 git log history,那真的是老太太的裹脚布, 又臭又长, 个人极其不喜欢这种 log

造成这个问题的根本原因就是随意提交代码。
代码都提交了,那还有什么办法拯救吗?三个锦囊,就可以完美解决了
善用 git commit --amend
这个命令的帮助文档是这样描述的:
--amend amend previous commit
也就是说,它可以帮助我们修改最后一次提交
既可以修改我们提交的 message,又可以修改我们提交的文件,最后还会替换最后一个 commit-id
我们可能会在某次提交的时候遗漏了某个文件,当我们再次提交就可能会多处一个无用的 commit-id,大家都这样做,git log 慢慢就会乱的无法追踪完整功能了
假设我们有这样一段 log 信息
* 98a75af (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2
* 119f86e feat: [JIRA123] add feature 1.1
* 5dd0ad3 feat: [JIRA123] add feature 1
* c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit
假设我们要修改最后一个 log message,就可以使用下面命令:
git commit --amend -m "feat: [JIRA123] add feature 1.2 and 1.3"
我们再来看一下 log 信息, 可以发现,我们用新的 commit-id 5e354d1 替换了旧的 commit-id 98a75af, 修改了 message,并没有增加节点
* 5e354d1 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2 and 1.3
* 119f86e feat: [JIRA123] add feature 1.1
* 5dd0ad3 feat: [JIRA123] add feature 1
* c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit
现在我们的 repo 中文件是这样的:
.
├── README.md
└── feat1.txt
0 directories, 2 files
假设我们提交 feature 1.3 的时候,忘记了一个配置文件 config.yaml, 不想修改 log,不想添加新的 commit-id,那下面的这个命令就非常好用了
echo "feature 1.3 config info" > config.yaml
git add .
git commit --amend --no-edit
git commit --amend --no-edit 就是灵魂所在了,来看一下当前的 repo 文件:
.
├── README.md
├── config.yaml
└── feat1.txt
0 directories, 3 files
再来看一下 git log
* 247572e (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2 and 1.3
* 119f86e feat: [JIRA123] add feature 1.1
* 5dd0ad3 feat: [JIRA123] add feature 1
* c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit
知道这个技巧,就可以确保我们的每次提交都包含有效的信息了。一张图描述这个过程就是这个样子了:

有了 --no-edit 的 buff 加成,威力更大一些
善用 git rebase -i
可以看着,上面的 log 都是在开发 feature1,我们在把 feature 分支 merge 到 main 分支之前,还是应该继续合并 log commit 节点的,这就用到了
git rebase -i HEAD~n
其中 n 代表最后几个提交,上面我们针对 feature 1 有三个提交,所以就可以使用:
git rebase -i HEAD~3
运行后,会显示一个 vim 编辑器,内容如下:
1 pick 5dd0ad3 feat: [JIRA123] add feature 1
2 pick 119f86e feat: [JIRA123] add feature 1.1
3 pick 247572e feat: [JIRA123] add feature 1.2 and 1.3
4
5 # Rebase c69f53d..247572e onto c69f53d (3 commands)
6 #
7 # Commands:
8 # p, pick <commit> = use commit
9 # r, reword <commit> = use commit, but edit the commit message
10 # e, edit <commit> = use commit, but stop for amending
11 # s, squash <commit> = use commit, but meld into previous commit
12 # f, fixup <commit> = like "squash", but discard this commit's log message
13 # x, exec <command> = run command (the rest of the line) using shell
14 # d, drop <commit> = remove commit
15 # l, label <label> = label current HEAD with a name
16 # t, reset <label> = reset HEAD to a label
17 # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
18 # . create a merge commit using the original merge commit's
19 # . message (or the oneline, if no original merge commit was
20 # . specified). Use -c <commit> to reword the commit message.
21 #
22 # These lines can be re-ordered; they are executed from top to bottom.
23 #
24 # If you remove a line here THAT COMMIT WILL BE LOST.
25 #
26 # However, if you remove everything, the rebase will be aborted.
27 #
28 #
29 # Note that empty commits are commented out
合并 commit-id 最常用的是 squash 和 fixup, 前者包含 commit message,后者不包含,这里使用 fixup, 然后 :wq 退出
1 pick 5dd0ad3 feat: [JIRA123] add feature 1
2 fixup 119f86e feat: [JIRA123] add feature 1.1
3 fixup 247572e feat: [JIRA123] add feature 1.2 and 1.3
我们再来看一下 log, 这就非常清晰了
* 41cd711 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1
* c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit
善用 rebase
上面的 feature1 已经完整的开发完了,main 分支也有了其他人的更新,在将 feature merge 回 main 分支之前,以防代码有冲突,需要先将 main 分支的内容合并到 feature 中,如果用 merge 命令,就会多处一个 merge 节点,log history 中也会出现拐点,并不是线性的,所以这里我们可以在 feature 分支上使用 rebase 命令
git pull origin main --rebase

pull 命令的背后是自动帮我们做 merge 的,但是这里以 rebase 的形式,再来看一下 log
* d40daa6 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1
* 446f463 (origin/main, origin/HEAD) Create main.properties
* c69f53d (origin/feature/JIRA123-amend-test, main) Initial commit
我们的 feature1 功能 on top of main 的提交节点,还是保持线性,接下来就可以 push 代码,然后提 PR,将你的 feature merge 到 main 分支了
简单描述 merge 和 rebase 的区别就是这样的:


我这里使用 git pull origin main --rebase 省略了切换 main 并拉取最新内容再切回来的过程,一步到位,背后的原理都是上图展示的这样
使用 rebase 是要遵守一个黄金法则的,这个之前有说过,就不再是赘述了
总结
有了这三个锦囊,相信大家的 git log 都无比的清晰,如果你还不知道,完全可以用起来,如果你的组内成员不知道,你完全可以推广起来,这样的 repo 看起来才更健康
接下来会介绍一个多分支切换互不影响的锦囊
个人博客:https://dayarch.top
加我微信好友, 进群娱乐学习交流,备注「进群」
欢迎持续关注公众号:「日拱一兵」
- 前沿 Java 技术干货分享
- 高效工具汇总 | 回复「工具」
- 面试问题分析与解答
- 技术资料领取 | 回复「资料」
以读侦探小说思维轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......

猿猿有责,维持整洁的 Git 提交记录,三个锦囊送给你的更多相关文章
- [译] 怎样(以及为什么要)保持你的 Git 提交记录的整洁
最近在掘金翻译了一篇文章,主要讲的是 Git 提交记录的维护,确实很有用,感兴趣的同学可以去看一下.链接如下: [译] 怎样(以及为什么要)保持你的 Git 提交记录的整洁 截图:
- 如何搜索 git 提交记录
如何搜索 git 提交记录 git log -p --all -G '可通过正则搜索' --pretty=format:'%ci' # 可跨分支搜索 # -S '通过文本搜索' git branch ...
- 怎样快速找到某一行代码的git提交记录
利用notepad++提高问题分析效率,以及快速找到某一行代码的git提交记录 1. 全目录搜索/替换 Notepad++是一款强大的文本编辑工具,当知道大概的关键词但不知道在哪个日志时可以使用not ...
- git使用记录三:查看日志
git使用记录三: git log git log 的帮助文档 git log --help 查看最后面的两个日志记录 命令如下: git log -n number 比如: git log -n 2 ...
- 恢复到版本并销毁之后的git提交记录
git reset --hard HEAD~1(或者你想要的版本号) git push --force # 千万注意:此操作无法恢复
- 自动刷github提交记录
前言 进入自己github主页会看到自己的提交记录,如果某天没有提交记录,那天的小方框就显示灰色.强迫症的我,每次进来看着就感觉不爽, 想着自己每天记得提交点东西,争取像阮一峰大神一样,每天都有提交记 ...
- git使用记录二: 给文件重命名的简单方法
git使用记录三: 给文件重命名的简单方法 git mv file_name_old file_name_new mv: 文件命名 file_name_old : 文件当前的名字 file_name_ ...
- 老鸟都应该注意的git 提交规范
不知道大家有没有看过自己项目的git 提交信息-----我看过好多次 ,不忍直视 然后提醒一起的小伙伴 :大家规范点 信息要详细, 过段时间再看下 ,还是一样. 相信很多猿都有这样的感受,对于垃圾的 ...
- git提交到远程仓库
Git概述 什么是Git? 刚开始对这个东西也感到挺迷茫,并且问了好多已经学习android一段时间的同学也是一头雾水,直到了解并使用之后,才体会到Git的好处以及重要意义. Git:是目前世界上最先 ...
随机推荐
- iOS自动化之WDA(WebDriverAgent)安装
1.WDA介绍 WebDriverAgent 在 iOS 端实现了一个 WebDriver server ,借助这个 server 我们可以远程控制 iOS 设备.你可以启动.杀死应用,点击.滚动视图 ...
- NX9.0和NX10.0做自定义操作可以用的函数
NX9.0:LIBUFUNX.DLL int UF_OPER_ask_check_geom(void *,int *,unsigned int * *) int UF_OPER_ask_first_o ...
- SpringBoot 整合 Thymeleaf & 如何使用后台模板快速搭建项目
如果你和我一样,是一名 Java 道路上的编程男孩,其实我不太建议你花时间学 Thymeleaf,当然他的思想还是值得借鉴的.但是他的本质在我看来就是 Jsp 技术的翻版(Jsp 现在用的真的很少很少 ...
- 2020BUAA软工提问回顾和个人总结作业
2020BUAA软工提问回顾和个人总结作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾和个人总结作业 我在 ...
- BUAA2020软工作业(三)——个人项目
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 进一步提高自己的编码能力,工程能力 这个作业在哪个具体方面帮助 ...
- zuul的各种配置
我们知道我们前台要展示数据给用户看,这中间可能涉及到从后端的多个微服务进行获取数据.比如获取用户信息需要用到用户微服务.获取商品信息需要获取商品微服务.创建订单需要调用订单微服务,而各个微服务可能分布 ...
- MOSFET管驱动电路的设计
https://wenku.baidu.com/view/ae727da5caaedd3382c4d3b9.html?mark_pay_doc=2&mark_rec_page=1&ma ...
- Java并发:ReadWriteLock 读写锁
读写锁在同一时刻可以允许多个线程访问,但是在写线程访问,所有的读线程和其他写线程均被阻塞. 读写锁不像 ReentrantLock 那些排它锁只允许在同一时刻只允许一个线程进行访问,读写锁可以允许多个 ...
- objcopy使用
objcopy - copy and translate object files:用于二进制文件的拷贝和翻译(转化) objcopy的man文件如下所示: objcopy [-F bfdname|- ...
- mongoDB 的一般使用
理解 mongodb 也是nosql 的一种.他的数据存储类型是一种和json格式比较像的数据类型,可以看作就是json. mongodb 里的数据库都是一个单独的库.一般需要用的库都会设置自己的us ...