git bisect run
membagi dua otomatis
Jika Anda memiliki ./test
skrip otomatis yang memiliki status keluar 0 jika pengujian OK, Anda dapat secara otomatis menemukan bug dengan bisect run
:
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
Tentu saja ini mengandaikan bahwa jika script tes ./test
dilacak git, bahwa itu tidak hilang pada beberapa komit sebelumnya selama pembagian dua.
Saya telah menemukan bahwa sangat sering Anda bisa lolos hanya dengan menyalin skrip in-tree keluar dari pohon, dan mungkin bermain dengan PATH
variabel-like, dan menjalankannya dari sana.
Tentu saja, jika infrastruktur pengujian test
bergantung pada komit yang lebih lama, maka tidak ada solusi, dan Anda harus melakukan hal-hal secara manual, memutuskan bagaimana menguji komit satu per satu.
Namun saya telah menemukan bahwa menggunakan otomasi ini sering berhasil, dan dapat menjadi penghemat waktu yang sangat besar untuk tes yang lebih lambat di tumpukan tugas Anda, di mana Anda dapat membiarkannya berjalan dalam semalam, dan mungkin bug Anda diidentifikasi pada pagi berikutnya, ada baiknya mencoba.
Lebih banyak tips
Tetap pada komit pertama yang gagal setelah membagi dua alih-alih kembali ke master
:
git bisect reset HEAD
start
+ awal bad
dan good
sekali jalan:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
sama dengan:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
Lihat apa yang telah diuji sejauh ini (secara manual good
dan bad
atau run
):
git bisect log
Output sampel:
git bisect log
git bisect start
# bad: [00b9fcdbe7e7d2579f212b51342f4d605e53253d] 9
git bisect bad 00b9fcdbe7e7d2579f212b51342f4d605e53253d
# good: [db7ec3d602db2d994fe981c0da55b7b85ca62566] 0
git bisect good db7ec3d602db2d994fe981c0da55b7b85ca62566
# good: [2461cd8ce8d3d1367ddb036c8f715c7b896397a5] 4
git bisect good 2461cd8ce8d3d1367ddb036c8f715c7b896397a5
# good: [8fbab5a3b44fd469a2da3830dac5c4c1358a87a0] 6
git bisect good 8fbab5a3b44fd469a2da3830dac5c4c1358a87a0
# bad: [dd2c05e71c246f9bcbd2fbe81deabf826c54be23] 8
git bisect bad dd2c05e71c246f9bcbd2fbe81deabf826c54be23
# bad: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05] 7
git bisect bad c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05
# first bad commit: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c0
Tunjukkan referensi yang baik dan buruk pada log git untuk mendapatkan gagasan waktu yang lebih baik:
git log --decorate --pretty=fuller --simplify-by-decoration master
Ini hanya menunjukkan komit dengan referensi yang sesuai, yang mengurangi kebisingan kebisingan, tetapi tidak menyertakan ref tipe autogenerated:
refs/bisect/good*
refs/bisect/bad*
yang memberi tahu kami mana yang ditandai sebagai baik atau buruk.
Pertimbangkan repo tes ini jika Anda ingin bermain-main dengan perintah.
Kegagalan cepat, kesuksesan lambat
Terkadang:
- kegagalan terjadi dengan cepat, misalnya salah satu tes pertama rusak
- keberhasilan butuh waktu, misalnya tes yang gagal lulus, dan semua tes lain yang tidak kita ikuti
Untuk kasus-kasus tersebut, misalkan anggap kegagalan selalu terjadi dalam 5 detik, dan jika kita malas membuat tes lebih spesifik seperti yang seharusnya, kita dapat menggunakan timeout
seperti pada:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
Ini berfungsi sejak timeout
keluar 124
sementara kegagalan test-command
keluar 1
.
Status keluar ajaib
git bisect run
agak pilih-pilih tentang status keluar:
apa pun di atas 127 membuat pembelahan dua gagal dengan sesuatu seperti:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
Secara khusus, huruf C assert(0)
mengarah ke a SIGABRT
dan keluar dengan status 134, sangat menjengkelkan.
125 ajaib dan membuat lari dilewati git bisect skip
.
Maksud dari ini adalah untuk membantu melewati bangunan yang rusak karena alasan yang tidak terkait.
Lihat man git-bisect
detailnya.
Jadi, Anda mungkin ingin menggunakan sesuatu seperti:
#!/usr/bin/env bash
set -eu
./build
status=0
./actual-test-command || status=$?
if [ "$status" -eq 125 ] || [ "$status" -gt 127 ]; then
status=1
fi
exit "$status"
Diuji pada git 2.16.1.