Git

Урок за Git Bisect

Урок за Git Bisect
Коментирането на вашите ангажименти е съществена част от поддържането на проследим код. Помага ви да проследявате проблеми. Намирането на грешка обаче само въз основа на коментари е досадна задача. Може да отнеме много време, за да се сортира цялата история и да се разбере кой ангажимент е виновникът.

Командата git bisect предоставя начин за ускоряване на процеса на откриване на грешки. Позволява ви да определите проблема по-бързо. С git bisect можете да дефинирате набор от ангажименти, за които подозирате, че имат проблемния код и след това да използвате двоични методи за елиминиране, за да намерите началото на проблема. Намирането на грешки става по-бързо и лесно.

Нека създадем пример и стартираме няколко тестови случая, за да видим как работи.

Примерна настройка

В нашия пример ще създадем тест.txt файл и добавете нов ред към файла с всеки фиксиране. След 16 фиксации крайното състояние на файла ще изглежда така:

Ето моя добър код 1
Ето моя добър код 2
Ето моя добър код 3
Ето моя добър код 4
Ето моя добър код 5
Ето моя добър код 6
Ето моя добър код 7
Ето моя добър код 8
Ето моят лош код 1 <-- BUG INTRODUCED HERE
Ето моят лош код 2
Ето моят лош код 3
Ето моят лош код 4
Ето моят лош код 5
Ето моят лош код 6
Ето моят лош код 7
Ето моят лош код 8
Ето моят лош код 9

В горния пример грешката е влязла в кода след 8 фиксации. Продължихме да разработваме кода дори след въвеждането на грешката.

Можете да създадете папка, наречена my_bisect_test, и да използвате следните команди от папката, за да създадете примерната ситуация:

git init
echo "Ето моя добър код 1"> тест.текст
git add -A && git commit -m "Моят ангажимент 1"
echo "Ето моя добър код 2" >> тест.текст
git add -A && git commit -m "Моят ангажимент 2 (v1.0.0) "
echo "Ето моя добър код 3" >> тест.текст
git add -A && git commit -m "Моят ангажимент 3"
echo "Ето моя добър код 4" >> тест.текст
git add -A && git commit -m "Моят ангажимент 4"
echo "Ето моя добър код 5" >> тест.текст
git add -A && git commit -m "Моят ангажимент 5 (v1.0.1) "
echo "Ето моя добър код 6" >> тест.текст
git add -A && git commit -m "Моят ангажимент 6"
echo "Ето моя добър код 7" >> тест.текст
git add -A && git commit -m "Моят ангажимент 7 (v1.0.2) "
echo "Ето моя добър код 8" >> тест.текст
git add -A && git commit -m "Моят ангажимент 8"
echo "Ето моя лош код 1"> тест.текст
git add -A && git commit -m "Моят ангажимент 9"
echo "Ето моя лош код 2" >> тест.текст
git add -A && git commit -m "Моят ангажимент 10"
echo "Ето моя лош код 3" >> тест.текст
git add -A && git commit -m "Моят ангажимент 11"
echo "Ето моя лош код 4" >> тест.текст
git add -A && git commit -m "Моят ангажимент 12 (v1.0.3) "
echo "Ето моя лош код 5" >> тест.текст
git add -A && git commit -m "Моят ангажимент 13"
echo "Ето моя лош код 6" >> тест.текст
git add -A && git commit -m "Моят ангажимент 14"
echo "Ето моя лош код 7" >> тест.текст
git add -A && git commit -m "Моят ангажимент 15 (v1.0.4) "
echo "Ето моя лош код 8" >> тест.текст
git add -A && git commit -m "Моят ангажимент 16"

Проверка на историята

Ако погледнете историята на ангажиментите, ще видите следното:

$ git log
ангажиране 3023b63eb42c7fadc93c2dd18b532a44a0a6888a
Автор: Zak H
Дата: неделя 31 декември 23:07:27 2017 -0800
Моят ангажимент 17
ангажиране 10ef0286d6459cd5dea5038a54edf36fc9bfe4c3
Автор: Zak H
Дата: неделя 31 декември 23:07:25 2017 -0800
Моят ангажимент 16
ангажиране 598d4c4acaeb14cda0552b6a92aa975c436d337a
Автор: Zak H
Дата: неделя 31 декември 23:07:23 2017 -0800
Моят ангажимент 15 (v1.0.4)
ангажиране b9678b75ac93d532eed22ec2c6617e5a9d70fe7b
Автор: Zak H
Дата: неделя 31 декември 23:07:21 2017 -0800
Моят ангажимент 14
ангажиране eb3f2f7b0ebedb732ecb5f18bee786cd3cbbb521
Автор: Zak H
Дата: Нед Дек 31 23:07:19 2017 -0800
Моят ангажимент 13
ангажиране 3cb475a4693b704793946a878007b40a1ff67cd1
Автор: Zak H
Дата: неделя 31 декември 23:07:17 2017 -0800
Моят ангажимент 12 (v1.0.3)
ангажиране 0419a38d898e28c4db69064478ecab7736700310
Автор: Zak H
Дата: неделя 31 декември 23:07:15 2017 -0800
Моят ангажимент 11
ангажиране 15bc59201ac1f16aeaa233eb485e81fad48fe35f
Автор: Zak H
Дата: неделя 31 декември 23:07:13 2017 -0800
Моят ангажимент 10
ангажиране a33e366ad9f6004a61a468b48b36e0c0c802a815
Автор: Zak H
Дата: неделя 31 декември 23:07:11 2017 -0800
Моят ангажимент 9
ангажиране ead472d61f516067983d7e29d548fc856d6e6868
Автор: Zak H
Дата: неделя 31 декември 23:07:09 2017 -0800
Моят ангажимент 8
ангажиране 8995d427668768af88266f1e78213506586b0157
Автор: Zak H
Дата: неделя 31 декември 23:07:07 2017 -0800
Моят ангажимент 7 (v1.0.2)
ангажиране be3b341559752e733c6392a16d6e87b5af52e701
Автор: Zak H
Дата: неделя 31 декември 23:07:05 2017 -0800
Моят ангажимент 6
ангажиране c54b58ba8f73fb464222f30c90aa72f60b99bda9
Автор: Zak H
Дата: неделя 31 декември 23:07:03 2017 -0800
Моят ангажимент 5 (v1.0.1)
ангажиране 264267111643ef5014e92e23fd2f306a10e93a64
Автор: Zak H
Дата: неделя 31 декември 23:07:01 2017 -0800
Моят ангажимент 4
ангажиране cfd7127cd35f3c1a55eb7c6608ecab75be30b208
Автор: Zak H
Дата: неделя 31 декември 23:06:59 2017 -0800
Моят ангажимент 3
ангажиране 3f90793b631ddce7be509c36b0244606a2c0e8ad
Автор: Zak H
Дата: неделя 31 декември 23:06:57 2017 -0800
Моят ангажимент 2 (v1.0.0)
ангажиране cc163adb8a3f7b7b52411db2b3d8bab9b7fb191e
Автор: Zak H
Дата: неделя 31 декември 23:06:55 2017 -0800
Моят ангажимент 1

Дори само с няколко ангажименти можете да видите, че е трудно да се определи фиксацията, която е стартирала грешката.


Намиране на грешката

Нека използваме git log -online, за да видим по-изчистена версия на историята на фиксиране.

$ git log --oneline
3023b63 Моят ангажимент 17
10ef028 Моят ангажимент 16
598d4c4 Моят ангажимент 15 (v1.0.4)
b9678b7 Моят ангажимент 14
eb3f2f7 Моят ангажимент 13
3cb475a Моят ангажимент 12 (v1.0.3)
0419a38 Моят ангажимент 11
15bc592 Моят ангажимент 10
a33e366 Моят ангажимент 9
ead472d Моят ангажимент 8
8995d42 Моят ангажимент 7 (v1.0.2)
be3b341 Моят ангажимент 6
c54b58b Моят ангажимент 5 (v1.0.1)
2642671 Моят ангажимент 4
cfd7127 Моят ангажимент 3
3f90793 Моят ангажимент 2 (v1.0.0)
cc163ad Моят ангажимент 1

Искаме да намерим ситуацията, при която редът „Ето моят лош код 1 <- BUG INTRODUCED HERE” entered the picture.

Ситуация 1

Да предположим, че помним, че нашият код беше добър до v1.0.2 и искаме да проверим от този момент до последния ангажимент. Първо стартираме командата bisect:

$ git bisect start

Предоставяме добрата и лошата граница (без хеш означава най-новия код):

$ git bisect good 8995d42
$ git bisect лошо

Изход:

Разделяне: Остават 4 ревизии за тестване след това (приблизително 2 стъпки)
[3cb475a4693b704793946a878007b40a1ff67cd1] Моят ангажимент 12 (v1.0.3)

Командата bisect намери средната точка в дефинирания от нас диапазон и автоматично премести кода, за да фиксира 12. Можем да тестваме нашия код сега. В нашия случай ще изведем съдържанието на теста.текст:

$ тест за котка.текст

Изход:

Ето моя добър код 1
Ето моя добър код 2
Ето моя добър код 3
Ето моя добър код 4
Ето моя добър код 5
Ето моя добър код 6
Ето моя добър код 7
Ето моя добър код 8
Ето моят лош код 1 <-- BUG INTRODUCED HERE
Ето моят лош код 2
Ето моят лош код 3
Ето моят лош код 4

Виждаме, че състоянието на теста.txt е в състояние след грешка. Така че е в лошо състояние. Така че даваме на командата bisect да знае:

$ git bisect лошо

Изход:

Разделяне: Остават 2 ревизии за тестване след това (приблизително 1 стъпка)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Моят ангажимент 9

Той премества нашия код, за да фиксира 9. Тестваме отново:

$ тест за котка.текст

Изход:

Ето моя добър код 1
Ето моя добър код 2
Ето моя добър код 3
Ето моя добър код 4
Ето моя добър код 5
Ето моя добър код 6
Ето моя добър код 7
Ето моя добър код 8
Ето моят лош код 1 <-- BUG INTRODUCED HERE

Виждаме, че сме намерили началната точка на грешката. Ангажиментът „a33e366 My commit 9“ е виновникът.

И накрая, върнахме всичко към нормалното чрез:

$ git bisect нулиране

Изход:

Предишната позиция на HEAD беше a33e366 ... Моят ангажимент 9
Превключено към клон „master“

Ситуация 2

В същия пример нека опитаме ситуация, при която друг разработчик започва с предпоставката, че грешката е била въведена между v1.0.0 и v1.0.3. Можем да започнем процеса отново:

$ git bisect start
$ git bisect good 3f90793
$ git bisect bad 3cb475a

Изход:

Разделяне: Остават 4 ревизии за тестване след това (приблизително 2 стъпки)
[8995d427668768af88266f1e78213506586b0157] Моят ангажимент 7 (v1.0.2)

Bisect премести нашия код, за да фиксира 7 или v1.0.2. Нека да стартираме нашия тест:

$ тест за котка.текст

Изход:

Ето моя добър код 1
Ето моя добър код 2
Ето моя добър код 3
Ето моя добър код 4
Ето моя добър код 5
Ето моя добър код 6
Ето моя добър код 7

Не виждаме лош код. Така че, нека git bisect знае:

$ git bisect добре

Изход:

Разделяне: Остават 2 ревизии за тестване след това (приблизително 1 стъпка)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Моят ангажимент 9

Подтикна ни да се ангажираме 9. Тестваме отново:

$ тест за котка.текст

Изход:

Ето моя добър код 1
Ето моя добър код 2
Ето моя добър код 3
Ето моя добър код 4
Ето моя добър код 5
Ето моя добър код 6
Ето моя добър код 7
Ето моя добър код 8
Ето моят лош код 1 <-- BUG INTRODUCED HERE

Отново намерихме фиксацията, която въведе грешката. Това беше ангажиментът „a33e366 My commit 9“. Въпреки че започнахме с различния диапазон на подозрения, открихме същата грешка в няколко стъпки.

Нека рестартираме:

$ git bisect нулиране

Изход:

Предишната позиция на HEAD беше a33e366 ... Моят ангажимент 9
Превключено към клон „master“

Заключение

Както можете да видите от примера, git bisect ни позволява да определим по-бързо проблем. Това е чудесен инструмент за повишаване на вашата производителност. Вместо да преглеждате цялата история на коммитите, можете да предприемете по-систематичен подход към отстраняване на грешки.

Допълнително проучване:

https: // git-scm.com / docs / git-bisect
https: // git-scm.com / book / en / v2 / Git-Tools-Debugging-with-Git

OpenTTD срещу Simutrans
Създаването на собствена транспортна симулация може да бъде забавно, релаксиращо и изключително примамливо. Ето защо трябва да сте сигурни, че изпробв...
Урок за OpenTTD
OpenTTD е една от най-популярните бизнес симулационни игри там. В тази игра трябва да създадете прекрасен транспортен бизнес. Въпреки това, ще започне...
SuperTuxKart за Linux
SuperTuxKart е страхотно заглавие, създадено да ви предостави безплатно изживяването на Mario Kart във вашата Linux система. Играта е доста предизвика...