Git
Chapters ▾ 2nd Edition

7.10 Git Алатки - Дебагирање со Git

Дебагирање со Git

Покрај тоа што е првенствено за контрола на верзијата, Git исто така обезбедува неколку команди кои ќе ви помогнат да ги дебагирате вашите проекти со изворен код. Бидејќи Git е дизајниран да се справи со секаков вид на содржина, овие алатки се прилично генерички, но тие често може да ви помогнат да ловите некоја грешка или виновник кога работите ќе тргнат наопаку.

Прибелешка на датотеката

Ако пронајдете грешка во вашиот код и сакате да знаете кога е воведен и зошто, прибелешката на датотеки е често вашата најдобра алатка. Тоа ви покажува што посветеноста беше последна за менување на секоја линија од која било датотека. Значи, ако видите дека методот во вашиот код е кабриолет, можете да ја коментирате датотеката со git blame за да одредите кој одмет е одговорен за воведувањето на таа линија.

Следниот пример го користи git blame за да утврди кој извршител и извршител е одговорен за линиите во највисокото Linux кернел` Makefile`, и понатаму ја користи опцијата -L за ограничување на излезот од коментарот на линиите 69 до 82 од таа датотека:

$ git blame -L 69,82 Makefile
b8b0618cf6fab (Cheng Renquan  2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line")
b8b0618cf6fab (Cheng Renquan  2009-05-26 16:03:07 +0800 70)   KBUILD_VERBOSE = $(V)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73)   KBUILD_VERBOSE = 0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75)
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1)
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 77)   quiet =
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 78)   Q =
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 79) else
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 80)   quiet=quiet_
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 81)   Q = @
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 82) endif

Забележете дека првото поле е делумна SHA-1 од извршената последна промена на таа линија. Следните две полиња се вредности што се извлечени од таа обврска - името на авторот и датумот на кој се запишува тој - така лесно можете да видите кој ја изменил таа линија и кога. Потоа доаѓа бројот на линијата и содржината на датотеката. Исто така, забележете ги линиите за "^ 1da177e4c3f4", каде префиксот ^ ги означува линиите кои беа внесени во почетната обврска на складиштето и оттогаш останаа непроменети. Ова е збунувачки, бидејќи сега сте виделе најмалку три различни начини на кои Git користи "^" за да го модифицира SHA-1 commit, но тоа е она што тоа значи овде.

Уште една кул работа за Git е тоа што не ги следи датотеките преименувани експлицитно. Таа ги снима сликите и потоа се обидува да дознае што е имплицитно преименувано, по факт. Една од интересните карактеристики на ова е тоа што можете да побарате од него да ги дознае сите видови движења на код. Ако го положите -C на` git blame`, Git ја анализира датотеката што ја коментирате и се обидува да дознае каде се отпечатени фрагменти од кодот во него, ако тие се копирани од друго место. На пример, велат дека рефакторирате датотека со име GITServerHandler.m во повеќе датотеки, од кои едната е` GITPackUpload.m`. Со обвинување на GITPackUpload.m со опцијата` -C`, можете да видите од каде потекнуваат делови од кодот:

$ git blame -C -L 141,153 GITPackUpload.m
f344f58d GITServerHandler.m (Scott 2009-01-04 141)
f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC
f344f58d GITServerHandler.m (Scott 2009-01-04 143) {
70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145)
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha;
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148)
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150)
56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) {
56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb
56ef2caf GITServerHandler.m (Scott 2009-01-05 153)

Ова е навистина корисно. Нормално, добивате како што оригиналот извршил извршување каде сте го препишале кодот, бидејќи тоа е прв пат да ги допрете тие редови во оваа датотека. Git ви го кажува оригиналното извршување каде што ги напишавте тие редови, дури и ако е во друга датотека.

Аннотирањето на датотека помага ако знаете од каде треба да започне проблемот. Ако не знаете што се крши, а од последната држава каде што знаете дека кодот функционира, имаше десетици или стотици обврски, најверојатно, ќе се свртите кон git bisect за помош. Командата bisect прави бинарно пребарување преку вашата историја на извршените врски, за да ви помогне да ги идентификувате што е можно побрзо, кои извршат внесат проблем.

Да речеме дека само го испуштивте пуштањето на вашиот код во производствена околина, добивате извештаи за бубачки за нешто што не се случувало во вашето развојно опкружување, и не можете да замислите зошто кодот го прави тоа. Вратете се на вашиот код, и излегува дека можете да го репродуцирате проблемот, но не можете да дознаете што се случува погрешно. Можете да го избришете кодот за да дознаете. Прво го стартувате git bisect start за да ги направат работите, а потоа користите` git bisect bad` за да му кажете на системот дека тековната посветеност на која сте вклучени е прекината. Потоа, мора да се каже дека бисect кога последна позната добра состојба беше, користејќи git bisect good <good_commit>:

$ git bisect start
$ git bisect bad
$ git bisect good v1.0
Bisecting: 6 revisions left to test after this
[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo

Git сфати дека околу 12 обврски дојдоа помеѓу обврските што ги обележавте како последна добра заложба (v1.0) и сегашната лоша верзија, и ја провери средната за вас. Во овој момент, можете да го извршите вашиот тест за да видите дали проблемот постои како резултат на ова извршување. Ако го стори тоа, тогаш тоа беше воведено пред овој среден залог; ако не, тогаш проблемот беше воведен некаде по средното извршување. Излезе дека нема проблем тука, и му кажувате на Git дека со внесување git bisect good и продолжете со вашето патување:

$ git bisect good
Bisecting: 3 revisions left to test after this
[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing

Сега сте на друга обврска, на половина пат помеѓу она што сте ја тестирале и вашата лоша заложба. Повторно го стартуваш тестот и откриј дека оваа обврска е скршена, така да му кажете на Git дека со git bisect bad:

$ git bisect bad
Bisecting: 1 revisions left to test after this
[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table

Оваа обврска е во ред, а сега Git ги има сите информации што му се потребни за да се утврди каде е воведено прашањето. Таа ви го кажува SHA-1 од првото лошо извршување и прикажува некои од информациите за извршување и кои датотеки биле модифицирани во тој запис, за да можете да дознаете што се случило што може да го претстави овој грешка:

$ git bisect good
b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
Author: PJ Hyett <pjhyett@example.com>
Date:   Tue Jan 27 14:48:32 2009 -0800

    secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config

Кога ќе завршите, треба да ја стартувате git bisect reset за да ја ресетирате вашата HEAD до каде сте биле пред да започнете, или ќе завршите во една чудна состојба:

$ git bisect reset

Ова е моќна алатка која може да ви помогне да проверите стотици обврски за воведени бубачки за неколку минути. Всушност, ако имате скрипта која ќе излезе од 0 ако проектот е добар или не-0 ако проектот е лош, можете целосно да го автоматизирате git bisect. Прво, повторно ќе го кажете обемот на бисектот со обезбедување на познати лоши и добри обврски. Можете да го направите ова со наведување на нив со командата bisect start ако сакате, со наведување на познатите лоши обврски прво и познатото добро изврши второ:

$ git bisect start HEAD v1.0
$ git bisect run test-error.sh

Со тоа автоматски се извршува test-error.sh на секоја избрана изјава додека Git не најде прва скршена обврска. Можете исто така да извршите нешто како направи или` направи тестови` или што и да имате што тече автоматски тестови за вас.