Bagaimana saya bisa menggunakan git bisect untuk menemukan komit GOOD pertama?

94

Saya memiliki masalah berikut:

  • versi di masterberfungsi dengan baik
  • versi dari tag terakhir sebelum master(katakanlah last) memiliki bug
  • seorang kolega membutuhkan patch untuk lastrevisinya untuk bug tertentu itu

Baik. Mari tanyakan teman kita git bisecttentang revisi yang memperbaiki bug:

git bisect start
git bisect bad last
git bisect good master

Tapi itu tidak akan berhasil:

Beberapa revs baik bukanlah nenek moyang dari revs buruk.
git bisect tidak dapat berfungsi dengan baik dalam kasus ini.
Mungkin Anda salah mengira revs baik dan buruk?

Ada petunjuk untuk mengatasi ini? Apakah saya melewatkan sesuatu di dokumen?

eckes
sumber
1
Saya menjalankan git bisect run ...untuk mengotomatiskan membagi dua. Jadi saya tidak punya kesempatan hanya untuk menukar kata-kata gooddan bad(itu terlalu jelas). Bagaimana cara menggunakan rununtuk menemukan revisi bagus pertama?
Daniel Böhmer
@ DanielBöhmer: Anda harus menukar istilah di dalam skrip yang sedang dijalankan, bukan?
eckes
Skrip yang dijalankan oleh git bisect runmengembalikan baik atau buruk sebagai kode keluar, bukan sebagai string. Lihat jawaban saya yang baru saja saya posting di bawah ini.
Daniel Böhmer
@ DanielBöhmer: baik, dalam hal ini Anda harus membalikkan kode pengembalian, bukan?
eckes
Benar, itulah yang dijelaskan dalam jawaban saya.
Daniel Böhmer

Jawaban:

100

Mulai git 2.7, Anda dapat menggunakan argumen --term-old dan --term-new.

Misalnya, Anda dapat mengidentifikasi komit perbaikan masalah sebagai berikut:

git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed master
git bisect unfixed $some-old-sha1

Saat Anda menguji, katakan git bisect fixedatau git bisect unfixedsesuai kebutuhan.

Jawaban lama, untuk versi git sebelum 2.7

Daripada melatih diri Anda untuk sementara waktu untuk berpikir bahwa buruk berarti baik dan baik berarti buruk, mengapa tidak membuat beberapa alias?

Dalam ~/.gitconfigmenambahkan berikut:

[alias]
        bisect-fixed = bisect bad
        bisect-unfixed = bisect good

Anda dapat mulai mengidentifikasi komit perbaikan masalah sebagai berikut:

$ git bisect start
$ git bisect-fixed master
$ git bisect-unfixed $some-old-sha1

Saat Anda menguji, katakan git bisect-fixedatau git bisect-unfixedsesuai kebutuhan.

Michael Wolf
sumber
5
Sebagai tambahan, git tidak mengizinkan Anda membuat alias dari sub perintah. Karenanya tanda hubung. Jika memang (atau dibuat) mungkin, semoga ada yang mengupdate jawabannya.
Michael Wolf
3
Bahkan jika Anda menggunakan alias, keluaran dari git tidak akan, jadi masih akan melaporkan foo is the first bad commit, jadi sepertinya pelatihan sementara masih diperlukan, bukan?
ThomasW
2
Poin yang adil. (Beri suara positif pada komentar Anda.) Meskipun demikian mudah-mudahan beban kognitif tambahan untuk ditangani setidaknya sedikit lebih sedikit, dan sebagai programmer, kami sudah memiliki banyak.
Michael Wolf
1
Saya merekomendasikan menggunakan alias 'sebelum' dan 'setelah'. Dengan cara itu Anda tidak memiliki overhead kognitif untuk melakukan inversi "ketika saya melihat bug, saya harus menulis 'bagus'"; alih-alih Anda hanya memiliki — kemungkinan lebih kecil — overhead mengingat bahwa Anda sedang mencari kemunculan / hilangnya bug (yaitu mengingat jenis perubahan apa yang Anda cari— "sebelum apa?").
Jonas Kölker
1
@ JonasKölker, itu ide yang bagus. Saya menggunakan alias yang disarankan dalam jawaban, serta bisect-after = bisect baddan bisect-before = bisect good, sesuai rekomendasi Anda. Sekarang saya bisa menggunakan salah satu dari alias. Kita akan melihat mana yang akhirnya lebih saya sukai setelah beberapa penggunaan.
Gabriel Staples
47

Saya hanya akan "menipu" git dan menukar makna baik <=> buruk.

Dengan kata lain, anggap "buruk" sebagai sesuatu yang tidak menunjukkan masalah jadi ini bukan versi yang "baik" untuk mendasarkan tambalan Anda.

Baik dan buruk adalah konsep yang cukup subjektif, bukan? :)

git bisect start
git bisect good last
git bisect bad master
inger
sumber
2
Nah, jika dipikir-pikir tidak ada arti umum apa itu baik atau buruk (bahkan mungkin tidak dalam agama) .. itu hanya tergantung pada tujuan Anda. Dengan cara ini tidak benar-benar curang - tapi mungkin Git's Sin (untuk tetap pada topik religius: D berarti mengambil istilah yang diperdebatkan daripada "tujuan" / "asal" yang lebih netral .. Tapi ya, filosofi bisa menjadi pikiran- boggling ;-)
inger
Ini pasti pertama kalinya saya mendengar bahwa bug bisa menjadi "baik".
MarcH
1
Itulah yang saya lakukan sebelum saya menemukan pertanyaan ini. Saya tidak akan melakukannya lagi. Ingat, hanya dibutuhkan satu jawaban yang salah sebelum seluruh pembagian menjadi serba salah. Jangan memelintir pikiran Anda.
proski
21

Jika Anda menggunakan git bisect runseperti yang telah saya lakukan dengan proveperintah Perl (yang menjalankan tes otomatis) Anda tidak memiliki kesempatan hanya untuk menukar gooddan bad. Keberhasilan pengujian akan dilaporkan sebagai kode keluar.

Saya telah menemukan sintaks Bash yang valid untuk meniadakan kode keluar dari program yang dijalankan oleh git bisect run:

git bisect start
git bisect bad HEAD                 # last revision known to PASS the tests
git bisect good $LAST_FAIL_REVISION # last revision known to FAIL the tests
git bisect run bash -c "! prove"

Ini memberi saya revisi pertama untuk lulus tes yang dijalankan prove.

Daniel Böhmer
sumber
1
Saya setuju, saya lebih suka tidak mengubah kasus pengujian saya, jadi ini sempurna.
seanlinsley
8

Git sekarang memungkinkan Anda menggunakan olddan newtanpa mendefinisikannya terlebih dahulu. Anda harus memanggil git bisect starttanpa komit sebagai argumen lebih lanjut, lalu memulai pembagian dua dengan benar dengan menelepon

git bisect old <rev>
git bisect new <rev>

https://git-scm.com/docs/git-bisect#_alternate_terms

Ini pada dasarnya adalah apa yang @MarcH sarankan untuk diterapkan.

GKFX
sumber
1
Ini adalah jawaban yang paling relevan (untuk git modern). Dan perintah start harus (sesuai dengan tautan yang Anda bagikan):git bisect start --term-new fixed --term-old broken
Sam Protsenko
Benar. Kapan opsi ini diperkenalkan? Saya ingin memperbarui jawaban saya.
Michael Wolf
@MichaelWolf Mereka muncul di versi 2.7.0 .
GKFX
6

Git alias adalah ide yang baik, namun hal fixeddan unfixedmemiliki masalah yang sama dari gooddan bad: Anda tidak dapat memiliki mereka kompatibel dengan baik regresi dan progresi. Sangat mudah untuk menemukan kata-kata yang bekerja dengan cara apa pun: cukup ambil dari terminologi pencarian biner asli yang bersifat netral tanpa prasangka tentang apa yang baik atau buruk. Contohnya:

git config --global alias.bisect-high 'bisect bad'
git config --global alias.bisect-low  'bisect good'

Dengan istilah netral seperti ini, Anda selalu dapat mengetik: git bisect-high(atau git bisect-upper, atau git-bisect max, ... pilihan Anda!) Apakah Anda sedang mencari regresi atau perbaikan .

Sayang sekali para pengembang git bisect tidak bisa begitu saja menggunakan kembali istilah yang ada. Secara umum, antarmuka pengguna bukanlah urusan git: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/

Maret
sumber
Dari: git.github.io/rev_news/2015/07/08/edition-5 "Beberapa seri tambalan sedang dipoles untuk memungkinkan git dua menggunakan sembarang pasangan istilah, bukan baik dan buruk, ..."
MarcH