如何做一份干净的Git提交记录

12,556 阅读6分钟

背景

毕业工作有一些年头了,之前在写工作代码或者给开源项目贡献的时候,提交代码都不是很规范,甚至可以说十分的随意,想到什么就提交什么,根本没有管理提交记录的概念或者想法(当你身边的人都不怎么在意的时候,你也很难在意的)。工作了一段时间之后,对代码提交规范的要求高了不少,因为我发现,当我把这件事情做好的时候,会让工作变得顺畅一些。有一天解决倒腾git解决了一些问题,就想到把这些东西沉淀下来,分享出去。所以写下了这篇文章。倒也不是多么高大上的代码技巧或者炫技,只是分享之前遇到的一些git commit问题,和分享一些见解。

cases and thoughts

1. 处理业务开发代码和测试联调代码

想象一下这样一个场景:有一个需求开发完了,准备和其他同事联调这个需求。谨慎起见,联调期间希望可以观测到这个需求运行过程中的大部分细节。比如上下游的输入输出是什么样的,运行到某段代码他的表现应该是什么样的。如果没有测试到位,就上线了,一不小心造成了什么事故,问题可就大了。另外,如果在测试过程中遇到了肉眼看不出来的bug,这时候也需要打一些日志去分析。

这个时候问题就来了,调试日志代码一般情况下是不能上线的,毕竟一个系统在关键的地方打上日志方便线上排查bug就好,到处打日志估计服务器也很难顶得住。这个时候怎么办呢?我会通过下面的例子来演示下面解决的方法。

首先我们假设有一个仓库。叫做git-experiment.并且当前有一个提交,是一个名为Feature-1的需求的相关开发改动。通过查看git提交日志我们可以看到:

image-20230623172359302

下面让我们看看具体怎么解决这个问题。

1.1 直接在这个分支上写,merge进master之前去掉这些提交记录

第一个做法其实比较好理解,就直接在原来的分支上加嘛,测试完了把这些关于测试的提交记录去掉就好。下面这幅图模拟的情景是:

  1. 加上了打印log逻辑。
  2. 在测试中发现了问题,又添加了一个commit来修复这个bug。

image-20230623172557907

测试结束,这个时候我们看到上面这样一份提交记录,应该怎么办呢,用git revert?是不太行的喔,因为revert会生成一个新的提交记录。像下面这样子。

image-20230623175716868

这样子虽然代码没了,但是这份提交记录看起来就会很奇怪。很明显,在这个场景中,我们实际上只需要关于Feature-1代码改动和关于bug fix的代码改动。这个时候推荐用git rebase。比如在上面这个case中,可以运行:

git rebase -i HEAD~2

这时候我们将看到下面这个景象,这些你挑选好的commit会倒序排列在你面前让你操作。

image-20230623181437659

d代表要放弃这个commit,pick代表保留。确认好你的操作之后退出。可能会遇到代码冲突,解决冲突之后可以执行git rebase --continue。完事之后我们可以看到。

image-20230623181551019

Perfect,这就是我们想要的。但是,这个方法的缺点就是在原来的分支上引入了新的不确定性,并且在去除日志代码的时候,最好期待没有冲突出现,如果出现了冲突,一个不小心把业务需求的代码搞掉了,那就美滋滋了。这种做法相当于把所有的风险都集中在一个分支上面。

1.2 切换一个分支,在新分支上写测试相关的代码

这里介绍第二种方法。我们可以在原来的基础上切换出一个新的分支来,专门用来做测试相关的工作,原有的分支专注在业务开发和bug fix。

image-20230623184507882

然后给这个分支加上测试相关的日志打印代码。

image-20230623185128561

这时候可以看一下这个分支上面的提交日志。

image-20230623185158854

这时候我们就可以拿这个分支去部署,然后和别人联调测试了。如果在测试过程中发现了bug,需要修复怎么办?这个好办,在原来的分支上做bug fix,然后测试分支cherry-pick bug fix的commit就好了。让我们来看看。

image-20230623185610302

commit bug fix的代码后,切换到测试分支,cherry pick这个commit。

image-20230623190717668

有冲突解决冲突。弄完之后让我们来看看这个分支的log。

image-20230623190652166

这样你就可以继续用这个分支做bug fix之后的测试啦。这样做的好处就是,你的开发分支始终是安全且干净的。冲突都在测试分支解决。

2. 让每一个commit都有意义

相信大家都听过这样的一句话,"代码是写给人看的,其次它能在电脑上跑起来。"。无论是工作还是开源项目。如果你写的代码会给别人仔细的review,那么让别人知道你的代码代表什么,要做什么,就显得尤为关键。不要因为做这个需要时间就不去做,如果别人没看懂你的commit或者需要你修改一下commit信息,这些现在省下来的时间后面还是会还回去的。就比如上面这个例子的最终状态是这样的:

image-20230623181551019

实际上,我个人认为这两个commit应该合并成一个,其实看代码的人看到这个bug fix的commit还会好奇这个提交的上下文是什么,可能脑海里会涌现出这样一个问题:bug是什么?不要让别人想太多,如果他很困惑,他就会来问你。最好可以通过commit信息告诉他你做了什么。

说到这里你就会想了,我把所有代码都弄成一个commit,再给上比较好的commit信息是不是就好了。看情况吧,如果一个需求你写了好多代码,上千行这样子。这时候我认为应该拆分一下commit,比如这个时候你可以拆分成好几个小的commit,再分别给提供commit信息。看代码的人可以通过你的commit信息拆解你的需求,细分到每一个小需求去审视你的代码,这也节约了他人的时间。

总结

上面是在我在工作中遇到的一些关于代码提交的问题和想法, 在这里分享给到大家。希望对大家有所帮助。