每一行代码都有一块被隐藏了的文档信息。
下面的代码片段不管是谁写的,其第4行因为某些原因要访问一个DOM结点的clientLeft属性,但却对结果不作任何处理。这十分的莫名其妙,你能告诉我他们为什么要这样做吗?以后改变或移除这个调用安全吗?
// ...if (duration > 0) this.bind(endEvent, wrappedCallback) this.get(0).clientLeft this.css(cssValues) 即使曾有人像我一样给你贴过该段代码,你可能还是不知道谁写的这行代码,他们的用意是什么,有必要继续保留这行吗?无论如何,大部分在你致力于一个项目时,你一般会通过版本控制系统访问它的历史。 项目的历史是其最有价值的记录
当我们观察下面这行命令输出的提交信息时,一切谜底都揭开了:
$ git show $(git blame example.js -L 4,4 | awk '{print $1}') Fix animate() for elements just added to DOM
Activating CSS transitions for an element just added to the DOM won’t work in either Webkit or Mozilla. To work around this, we used to defer setting CSS properties with setTimeout (see 272513b).
This solved the problem for Webkit, but not for latest versions of Firefox. Mozilla seems to need at least 15ms timeout, and even this value varies.
A better solution for both engines is to trigger “layout”. This is done here by reading clientLeft from an element. There are other properties and methods that trigger layout; see gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit
正如结果所示,这一行—更确切地说,是引进这一行所做的改动—大量记载了有关于为什么它是必要的,为什么先前的方法(指的是通过提交SHA)不奏效,哪些浏览器受到影响以及进一步阅读的链接这些信息。
上面的结果也显示,这行莫名其妙的代码的作者就是我,实际上我有方法将这行代码本身写的更好:通过在函数中用意图明显的名字如triggerLayout()封装magic属性的访问,或者至少通过添加触发动画这样一个简短的解释作为代码注释。不管什么原因,我那天就是没能让这段特殊的代码赋有表达力。这样的代码发生了,就不总是完美的。
即使这段代码更具表达力,或者它已经包含了数行代码注释,项目的历史都能提供更加丰富的信息:
1. 谁添加的这行代码;
2. 他们什么时候添加的这行代码;
3. 哪部分是accompanying test(如果有的话);
4. 完整的提交信息可以是整部小说(但其中的代码注释应该保持简洁)。
代码质量仍然十分重要。但是在琢磨如何进一步提高你的编码水平时,你应该考虑完成更好的提交信息。你不仅仅应该请求你自己,还应该请求整个团队甚至所有的贡献者做到这一点。一个软件的故事与其最新的检出一样重要。 对项目历史有效的深层次探索 git blame
我已经在上面的命令中证明了如何使用git blame。当你不能够访问本地git库时,你也可以打开GitHub上任何文件的“Blame”视图。
一个非常有效的探索文件历史的方法是使用Vim和Fugitive:
1. 在缓冲区里使用:Gblame打开blame视图;
2. 如果你需要进一步探索,在blame面板那行按下Shift-P在那次提交的parent上重新blame;
3. 按下o打开一个拆分面板显示出blame面板当前选中的提交信息。
4. 在提交分区使用:Gbrowse打开GitHub web接口的commit;
5. 按下gq关闭blame面板返回到主缓冲区。
避免不相关改动间的推导:坚持基于行的编码风格,允许你添加,编辑或删除列表中的值而不用改动相邻行。一些例子:var one = "foo" , two = "bar" , three = "baz" // Comma-first style allows us to add or remove a // new variable without touching other lines # Ruby: result = make_http_request( :method => 'POST', :url => api_url, :body => '...', // Ruby allows us to leave a trailing comma, making it ) // possible to add/remove params while not touching others 你为什么要使用这样的编码风格?好吧,总得想想将要git blame这个的人们。在JavaScript的例子里,如果你要添加一个值“baz”然后提交,当有人blame添加“bar”的行时你不想你的名字呈现把,因为这两个变量可能不相关。
奖励脚本
既然你已经读到这里,我将奖励你一个额外的脚本。我称之为git-overwritten,它能够显示出指定分支处所改动或删除的行其原始作者的blame信息:
$ git overwritten feature origin/master 28 2014-02-04 1fb2633 Mislav Marohni?: Add Makefile for building and testing 1 2014-01-13 b2d896a Jingwen Owen Ou: Add -t to mktemp in script/make 17 2014-01-07 385ccee Jingwen Owen Ou: Add script/make for homebrew build 当打开每个GitHub Flow的pullrequests时,这是非常有用的;你要是想要你的pull request被同伴审查,但是你可能不太确定该ping谁,使用git-overwritten你可以获得你刚刚改动代码行的原始作者名字,所以你就会知道当打开一个pull request时@-mention谁了。 声明:本文编译自Mislav Marohnić,已投稿给伯乐在线。