原文: http://www.ruanyifeng.com/blog/2018/12/git-bisect.html
git bisect
是一个很有用的命令,用来查找哪一次代码提交引入了错误。
它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓”两分法”,就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。
本文通过一个实例,解释如何使用这个命令。下面是一个代码库,请将它克隆到本地。
$ git clone git@github.com:bradleyboy/bisectercise.git
$ cd bisectercise
这个库是一个网页index.html
,在浏览器打开这个网页。
$ open index.html
网页上是一个计数器,有两个按钮。点击+
号按钮,可以看到计数器没有递增,反而递减,这说明代码有问题。
现在,就要来查找,到底哪一次代码提交,引入了错误。首先,检查一下代码提交历史。
$ git log —pretty=oneline
可以看到,这个库一共有101次提交。最早的第一次提交的哈希是4d83cf
。
git bisect start
命令启动查错,它的格式如下。
$ git bisect start [终点] [起点]
上面代码中,”终点”是最近的提交,”起点”是更久以前的提交。它们之间的这段历史,就是差错的范围。
这个例子中,我们选择全部的代码历史。起点是第一次提交4d83cf
,终点是最近一次的HEAD
。当然,指定其他范围也可以。
$ git bisect start HEAD 4d83cf
执行上面的命令以后,代码库就会切换到这段范围正当中的那一次提交,本例是第51次提交。
现在刷新浏览器,点击+
按钮,发现可以正常递增。使用git bisect good
命令,标识本次提交(第51次)没有问题。
$ git bisect good
既然第51次提交没有问题,就意味着错误是在代码历史的后半段引入的。执行上面的命令,Git 就自动切换到后半段的中点(第76次提交)。
现在刷新浏览器,点击+
按钮,发现不能正常递增。使用git bisect bad
命令,标识本次提交(第76)有问题。
$ git bisect bad
执行上面的命令以后,Git 就自动切换到第51次到第76次的中点(第63次提交)。
接下来,不断重复这个过程,直到成功找到出问题的那一次提交为止。这时,Git 会给出如下的提示。
b47892 is the first bad commit
既然找到那个有问题的提交,就可以检查代码,确定具体是什么错误。
然后,使用git bisect reset
命令,退出查错,回到最近一次的代码提交。
$ git bisect reset
现在就可以开始修复错误了。
(完)
PS: 懒了就炖了附实操日志
administrator MINGW64 ~/Desktop/git
$ git clone https://github.com/bradleyboy/bisectercise.git
Cloning into 'bisectercise'...
remote: Enumerating objects: 304, done.
remote: Counting objects: 100% (304/304), done.
remote: Compressing objects: 100% (206/206), done.
remote: Total 304 (delta 97), reused 304 (delta 97), pack-reused 0
Receiving objects: 100% (304/304), 29.88 KiB | 164.00 KiB/s, done.
Resolving deltas: 100% (97/97), done.
administrator MINGW64 ~/Desktop/git
$ cd bisectercise/
administrator MINGW64 ~/Desktop/git/bisectercise (master)
$ git log --pretty=oneline
483ed94b63fe3dd4acd10073e0be30a8af36ac2c (HEAD -> master, origin/master, origin/HEAD) readme
7808b0941eab1e47dbafb123704ac7e289a59143 commit 100
4551242eb13dc392d21338128c775fa3557d0d4e commit 99
37b86f1b64ad8cdb609d3720483603cfd474d65e commit 98
3ae6b73a590539d4273bdd0683b01188796db6cd commit 97
7c48b6faf5e3acf0869be9ecfd09fba2eeb69275 commit 96
8facd277e8f87ee2de30e4c1b12c65a6c27ad943 commit 95
f73367c1e011ca3345dbc823065e9ba962442068 commit 94
0f4ce30c8f4e77c459b7785a667e3ab8343f7ee4 commit 93
4ea0bfa7a1973fdf4cd1176b7efed94d73a391a1 commit 92
907f98a4654541c44fbe65125e86e24eebe2b0d9 commit 91
c6635603597396fb0df2cf97bdcb27f277e60f98 commit 90
834ec389bdfe67312c8004382a76036251b7cc73 commit 89
885c043cd6b548150f145256a3f366c863e2ac9d commit 88
f9f4f7a67c5c97dc8eb927310d8fd48f2e3ae592 commit 87
8df8f95ceadb8abdf0eb47ef4b7c0a8c08a03ca6 commit 86
70d40011375d9265e75fdc95c1553ef68e2b539b commit 85
ff398a0a62d31f9fe0c114d21e6d925a74a2dc0d commit 84
63e61f64e0069f17f554b83f7888f80d0544fd36 commit 83
97bf43affd78401a943b7af89afe9c0438fb319a commit 82
7a4679cc7115d456bd5d900874595cdf2e54988a commit 81
c5f0fd743e27ed11ae89a6a4c94f4947b5ea974c commit 80
c6ba7429dbad520067b6bf0b2450ef1a541b4e7a commit 79
75afe37a77429121befc8676823c9439f1d7b2ad commit 78
27c58746f430da1374410eab456c559c14599090 commit 77
cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0 commit 76
dd6b85e2604c0b2db5218ed080596cfca485e242 commit 75
6580e5074ad69418a417b72f5d3b8bbf2120c6a7 commit 74
5a2b0a88cc65571a4c40e8e8b22c8dce344421d9 commit 73
8d47c8046b861ede7026922da260f81a97d44650 commit 72
23f8650bf3644bd3c1704754a6d58d7062b2b00a commit 71
6de289d48cdea034077840937216e848703014c5 commit 70
54d2dc29e0f23d08c42a2ef16cf20f1145cbe076 commit 69
60fd6b78c9726e7987a5d6d8800f05f5e73bbfa1 commit 68
af5c9eae2c06350ecb751733ce0e42ad5b284c5e commit 67
68f066184e9c835a0270b904805c608c0b29aa6b commit 66
21306f0075a6fcd255f0d6cefa9f1cf0e1c8eddd commit 65
b47892adec22ee3b0330aff37cbc5e695dfb99d6 commit 64
4437723ed1ac9a1022311ebb78d3688848a4c9b0 commit 63
050059f41862f228871666e928f66663279ff915 commit 62
a4c2943a7ac2f2b8b70a5086afc6ed1a56b90298 commit 61
369e7566190a56882a76d05274d13b2ae60612f0 commit 60
9765d89c3f7ce7692510a2ad8df51ac07bcd5f44 commit 59
98acf91bfbf47a63ca5be01043b4e728bbee35ed commit 58
ef048eb110abb2a7bf10a0539e5ac079f580633a commit 57
55025d545bb345448c30682a27b9018e8edc9d44 commit 56
b7800c3849e17b0b80e736e98d7ab7ca25a04204 commit 55
c5ff70e4f1e2de3cc1866544344c829d636b6d89 commit 54
f135eb98b8ab9c73e259f9b89c674c890d35a0ed commit 53
96c49431eec7982ba36d07573d939db842ef3198 commit 52
b5a131d5eed449db864a36ccc4c367ab28b402ff commit 51
6ac79e6285f46aa93bc1d7b75b8d3e5e733f0e38 commit 50
cbfaa8504e6fb14d01b0668ab3ef03dd4677fbb4 commit 49
2c10e5a2efc522b3497e5df359fd4eafdaa0ffaa commit 48
f0d4566c1941650351ab40c5e21a34fa2ffeeb2d commit 47
bbb705c1b58c5148a525688e175935b3539dfe6a commit 46
31289094f959c29d0d9e89d8f180acbbf1fe9fb8 commit 45
5a56ce1b00f17b2cf3e41b4a53b3e51436a8689d commit 44
7f9762397972d5a116c81083c389480332f3ead9 commit 43
3fb52388b0651c55b4d08360c9e752ecc0ef0a7d commit 42
aa75608369c9641ab5a2b3f237345777a6b3600f commit 41
b64d33fbe5daed64164547ec1d31994b9f6b40dd commit 40
2ae08d55d364a56e9e7be16006fcf2f37199555f commit 39
82b63fba165ffdd304c2c155a286d5b37b2b2384 commit 38
a442f71570fb589479547c06fc0339fcfb23cb42 commit 37
45950578d70acad16ba839dbcc702c48ddf87958 commit 36
001ff307e6c438f66f819fe6b7a5be0f1ef2a155 commit 35
b6fc4fa82dc202b6f139b118ec0798ef9a57ae84 commit 34
2146743760a98b1891595b11271679b4ca3346e4 commit 33
f1b390e7ffcb61c62a1e087976088cae5d8692f2 commit 32
30385fdf7e335b1c670974283d93e64328c43c65 commit 31
1c6d445dd989b13596ca7c8d08fde2b3c45e2f11 commit 30
a53675c350cbbcef4110f8dfddb4493c6286601e commit 29
cd9cd8cbd7d9a70425a2bb127b7ee7597f71dffb commit 28
eafe7183b10ebc4bfbfdfd7d986a00f2910605fa commit 27
d9db1bdbc7ec59d6876b048ee94641d4060f649d commit 26
4c5eb07072d39727d5b6dd91fcb043d409b769bf commit 25
0d2678b576572bfec934dc1c8bcfc36eaefb934e commit 24
9a501378bb8cd18d7e3043135a6fccb8b7087b36 commit 23
e16b2b7af22897300466ba3fb6c8eb12b17e187f commit 22
9635abbc40ab599483fb34bf99228499159e9888 commit 21
6700d53ad66fdcbee781ce585f9107b143e11ae4 commit 20
a00393802ed35a018392f1cbbf741770ea7a77cb commit 19
ae6ea16243a77479eafd814ad65a013e30575f85 commit 18
c49b939c4b0e5af5cf76f14b4c374b89d91eb3df commit 17
217148e9f9ca6166fd7b1382034569bac834007a commit 16
3d71e25762ae0fe7c081ee3b10d7a608b64a18c8 commit 15
ba170a6f8bfa1c45e85a931c54af7d9bb79a20a8 commit 14
8ddef7a93017e577442fad25081d6c6a164bb409 commit 13
d7ca9f996b4ad8406bfe78b218c31acc1d9cec1c commit 12
42c6c24f87657eb5b898346aaa14d1233f1b083a commit 11
e4b93d031c9615276528b99d121e6086e76e9f58 commit 10
b39e3fce273bacb3529f5de0618d532431c8329d commit 9
09e5d4b9d2612dba3d4f15de457a2663cb88ed8c commit 8
a5a170f273e13727dc814992be6e88bd93668273 commit 7
5b64d98370f42a84504c9f2ecbc992007990072d commit 6
f853c75da28a80e1831d6f0c7d0ffc98f8a6d577 commit 5
a149b5b932d6fd51125c734808ee9bcdd111f1cc commit 4
989792f504e54f73a4b9415d14a8a17e29ea914b commit 3
295191adc3aa97f7448c55aff6343ec5ec7196f0 commit 2
4d83cfcbaef648345571d77db867b6f9e4146ba7 commit 1
administrator MINGW64 ~/Desktop/git/bisectercise (master)
$ git bisect start HEAD 4d83cfcbaef648345571d77db867b6f9e4146ba7
Bisecting: 49 revisions left to test after this (roughly 6 steps)
[b5a131d5eed449db864a36ccc4c367ab28b402ff] commit 51
administrator MINGW64 ~/Desktop/git/bisectercise ((b5a131d...)|BISECTING)
$ git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[cd592ce62d90de8bfd7df8ae47648aaee3bf9cc0] commit 76
administrator MINGW64 ~/Desktop/git/bisectercise ((cd592ce...)|BISECTING)
$ git bisect bad
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[4437723ed1ac9a1022311ebb78d3688848a4c9b0] commit 63
administrator MINGW64 ~/Desktop/git/bisectercise ((4437723...)|BISECTING)
$ git bisect good
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[54d2dc29e0f23d08c42a2ef16cf20f1145cbe076] commit 69
administrator MINGW64 ~/Desktop/git/bisectercise ((54d2dc2...)|BISECTING)
$ git bisect bad
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[68f066184e9c835a0270b904805c608c0b29aa6b] commit 66
administrator MINGW64 ~/Desktop/git/bisectercise ((68f0661...)|BISECTING)
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 1 step)
[21306f0075a6fcd255f0d6cefa9f1cf0e1c8eddd] commit 65
administrator MINGW64 ~/Desktop/git/bisectercise ((21306f0...)|BISECTING)
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[b47892adec22ee3b0330aff37cbc5e695dfb99d6] commit 64
administrator MINGW64 ~/Desktop/git/bisectercise ((b47892a...)|BISECTING)
$ git bisect bad
b47892adec22ee3b0330aff37cbc5e695dfb99d6 is the first bad commit
commit b47892adec22ee3b0330aff37cbc5e695dfb99d6
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:36 2018 -0500
commit 64
:100644 100644 b10625ed4a08e037bd78fa82f8642f86425e794f 43a01abbda2fb4df745fac338636a9d78dab769e M index.html
administrator MINGW64 ~/Desktop/git/bisectercise ((b47892a...)|BISECTING)
$ git show b47892adec22ee3b0330aff37cbc5e695dfb99d6
commit b47892adec22ee3b0330aff37cbc5e695dfb99d6 (HEAD, refs/bisect/bad)
Author: Brad Daily <bdaily@rsglab.com>
Date: Sat Dec 22 13:41:36 2018 -0500
commit 64
diff --git a/index.html b/index.html
index b10625e..43a01ab 100644
--- a/index.html
+++ b/index.html
@@ -67,12 +67,12 @@
<div id="number">0</div>
<div class="actions">
- <button data-action="dec">-</button>
- <button data-action="inc">+</button>
+ <button data-action="dc">-</button>
+ <button data-action="ic">+</button>
</div>
</main>
- <footer>Version: 63</footer>
+ <footer>Version: 64</footer>
<script>
(() => {
administrator MINGW64 ~/Desktop/git/bisectercise ((b47892a...)|BISECTING)
$ git bisect reset
Previous HEAD position was b47892a commit 64
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
administrator MINGW64 ~/Desktop/git/bisectercise (master)
$
从上面的代码可以看到,错误的地方就是:dec
改成了dc
,inc
改成了ic
导致的错误
Unable to negotiate with 106.52.160.162 port 22: no matching host key type found. Their offer: ssh-rsa fatal: Could not read from remote repository.
使用git hooks(post-receive)实现简单的远程自动部署
linux下,设置git免密码操作
**git cherry-pick**可以选择某一个分支中的一个或几个commit(s)来进行操作。例如,假设我们有个稳定版本的分支,叫v2.0,另外还有个开发版本的分支v3.0,我们不能直接把两个分支合并,这样会导致稳定版本混乱,但是又想增加一个v3.0中的功能到v2.0中,这里就可以使用cherry-pick了,其实也就是对已经存在的commit 进行再次提交.
在使用Git的过程中,有时候会因为一些误操作,比如reset、rebase、merge等。特别是在Commit之后又执行了`git reset --hard HEAD`强制回滚本地记录以及文件到服务器版本,导致本地做的修改全部恢复到Git当前分支的服务器版本,同时自己的Commmit记录也消失了。碰到这种情况,不要慌,我们在Git上做的任何操作都只是在原来之前的操作上做修改,并且会被记录下来保存,也就是说无论你做了什么,对于Git来说都可以进行回滚操作。
它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓&quot;两分法&quot;,就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。
当在git操作log,如`git log`后,然后非正常退出,即使用`CTRL+C`退出,这个时候git输入命令就不会显示了,只有光标,这时怎么办?
.gitignore文件配置不生效
git修改当前项目用户
Git修改最近一次已经提交了的commit及push
git常用命令,git查看某个文件的修改记录,分支备注
通过设置git-diff driver,结合.gitattributes文件,使git diff命令忽略某些目录。例如我们只希望看到比较src目录,不希望看到比较dist目录
学习这本书的目的是让你了解版本控制,并且尽可能快速简单的掌握 Git。但是和另外一些关于介绍版本控制的图书不一样,阅读这本书并不需要你有很专业的 IT 或者电脑背景知识,它也面向那些编程的初学者,软件构架师,或者是项目经理。在技术方面你也不需要有很多专业知识,我们会以循序渐进的方式帮助你来理解版本控制和掌握 Git。
git如何打包增量文件?
github push时免密码