老早就听说过用 Git 的 bisect, 二分查找问题 commit, 只是一直都没机会实践运用. (项目都跑的太正常了, 手动斜眼)
其实, 只是绝大部分时候总可以通过各种 Log 来追踪到问题所在. 今个儿遇到了个实在没法看日志的问题.
团队的成员提交了各自提交了各种代码并合并到了 master 分支, 正准备发测试环境, 发现部署的时候 precompile 崩掉了, 一看报错日志. 一脸懵逼了…
这只说了某个等号附近有语法错误, 具体在哪一个文件哪一行也没个说法, 只给出了这一大坨, 加起来单是当天新增的 commit 少说二三十个, 总不能一个个去 reset 看哪儿改的 JavaScript 引起吧 = . =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
ExecJS::ProgramError: SyntaxError: Unexpected token operator «=», expected punc «,» (line: 58005, col: 69, pos: 2186981)
Error
at new JS_Parse_Error (<eval>:3623:11948)
at js_error (<eval>:3623:12167)
at croak (<eval>:3623:22038)
at token_error (<eval>:3623:22175)
at expect_token (<eval>:3623:22411)
at expect (<eval>:3623:22562)
at ctor.argnames (<eval>:3623:27486)
at function_ (<eval>:3623:27550)
at expr_atom (<eval>:3623:31068)
at maybe_unary (<eval>:3624:1752)
at expr_ops (<eval>:3624:2523)
at maybe_conditional (<eval>:3624:2615)
at maybe_assign (<eval>:3624:3058)
new JS_Parse_Error ((execjs):3623:11948)
js_error ((execjs):3623:12167)
croak ((execjs):3623:22038)
token_error ((execjs):3623:22175)
expect_token ((execjs):3623:22411)
expect ((execjs):3623:22562)
ctor.argnames ((execjs):3623:27486)
function_ ((execjs):3623:27550)
expr_atom ((execjs):3623:31068)
maybe_unary ((execjs):3624:1752)
expr_ops ((execjs):3624:2523)
maybe_conditional ((execjs):3624:2615)
maybe_assign ((execjs):3624:3058)
|
还好可以在本地用
1
|
RAILS_ENV=staging rake assets:precompile
|
还原 precompile 的错误,
想起 git bisect, 看样子可以用上了.
1
2
3
4
|
git bisect start
git bisect good be835ca5ce4755ea106701587c308d6add8d4f7
# be835ca5ce4755ea106701587c308d6add8d4f7 是该分支上确定不会出现这个 bug 的 commit,
# 其实, 只是随意在昨天的 commit 里面捞一条出来而已
|
标记好了以后跑一次
1
|
RAILS_ENV=staging rake assets:precompile
|
发现还是编译不过, 于是
1
2
3
4
5
6
7
|
# 标记为 bad
git bisect bad
Bisecting: 36 revisions left to master after this (roughly 5 steps)
[76dbb96bc3b5bfb1465f81081aeebb9a34e6f92b]
➜ Cherry git:(76dbb96)
|
76dbb96 这个 commit 正好是 先前设定的 be835ca5ce4755ea106701587c308d6add8d4f7 跟当前最新 commit 的中间节点.
git 此时已经 checkout 到 76dbb96
说明问题出在最新 commit 到 76dbb96 commit 之间.
刚刚已经标记好了 bad, 再继续跑
1
|
RAILS_ENV=staging rake assets:precompile
|
发现没有问题, 能编译过, 所以,
1
2
3
4
5
|
git bisect good
Bisecting: 18 revisions left to master after this (roughly 4 steps)
[cdc07fc05a85465797086dc0f9fe5c663b7ffcf6]
➜ Cherry git:(cdc07fc)
|
再一次 checkout
标记为 good 以后可以看到, 问题出在从 cdc07fc 到当前最新的代码之间某个 commit. 继续重复上述的步骤, 其实 git 有给提示最多还要 4 次就可以找出问题 commit 在哪了.
实际可能更少. 更快就找到了问题所在的 commit 了.
最后, 发现是 Javascript 方法默认值这里出的问题 = . =
1
2
3
4
5
6
7
8
9
10
|
(function(){
window.DrawCarState = {
single_car_state: function(car_id, begin_at, end_at, draw_target = '', format = 'html'){
$.ajax({
...
})
}
}
}).call(this);
|
定位好问题分支以后可以通过
恢复到 bisect 前的状态