Git bisect è un comando che permette di cercare la commit che ha introdotto un bug attraverso l’uso di un algoritmo di ricerca binaria.
Supponendo di avere una lunga serie di commit, la nostra esigenza è quella di trovare quella che ha causato il bug. Ciò che quindi verrebbe spontaneo fare è ricercare il problema commit dopo commit.
Andare di commit in commit è sostanzialmente una ricerca lineare, la quale potrebbe richiedere più o meno tempo in base al numero di commit da ispezionare.
Cos’è la ricerca lineare
La ricerca lineare è un tipo di algoritmo di ricerca che prevede lo scorrere di una serie di elementi nell’ordine in cui sono collocati.
Supponendo di avere un mazzo di carte e di cercare l’asso di fiori scorreremo tutto il mazzo alla ricerca di suddetta carta.
In termini di time complexity la ricerca lineare ha un best case di O(1) e un worst case O(n). Dove n aumenta in base al numero di elementi.
Supponendo che il mazzo di carte sia da 40, nel peggiore dei casi l’asso di fiori è al 40esimo posto e nel miglior caso è la prima carta del mazzo.
Cos’è la ricerca binaria
La ricerca binaria (o dicotomica) è un tipo di algoritmo di ricerca che si applica su liste ordinate.
La ricerca binaria confronta l’elemento centrale della lista con quello che stiamo cercando, se l’elemento è minore rispetto al valore ricercato, l’elemento diventa il nuovo limite e verrà preso il nuovo elemento centrale e confrontato. Viceversa se il numero è maggiore.
Per scriverla meglio possiamo dire che avendo una serie di elementi ordinari, prendiamo l’elemento mediano, lo confrontiamo con ciò che stiamo cercando, in base all’esito del confronto verrà presa in considerazione per la nuova estrazione e confronto la parte sinistra se il confronto da esito maggiore, la parte destra se il confronto da esito minore. Se uguale ovviamente termina. Così via fintanto che abbiamo elementi da estrarre e confrontare.
In termini di time complexity la ricerca binaria è O(log n) nel worst case e O(1) nel best case. Possiamo considerarlo un algoritmo efficiente, se applicato a liste con numerosi elementi e solo se ordinati.
Come usare il comando git bisect
Bisect quindi performa una ricerca binaria, il che significa che ha bisogno di due estremi per iniziare. L’estremo cattivo e l’estremo buono.
L’estremo cattivo = la commit che non funziona a causa del bug L’estremo buono = la commit dove sappiamo che tutto funziona correttamente
Prima ancora però bisogna far partire il processo con il comando:
1$ git bisect start
Per selezionare gli estremi dobbiamo usare i due sub-comandi bad e good in questo modo:
1$ git bisect bad <hash>
2$ git bisect good <hash>
Al posto dell’hash possiamo usare anche HEAD
, soprattutto nel caso di bad, perché è quasi sempre l’ultima commit.
Con queste due informazioni Git può iniziare il processo.
Sarà compito di chi sta eseguendo il bisect controllare che tutto funzioni o se il bug è ancora presente. Terminati i test possiamo comunicare a Git se la commit che stiamo ispezionando è bad o good con i comandi:
1$ git bisect bad
2$ git bisect good
In base alla risposta procederà con la parte di sinistra o destra della serie di commit finché non avrà finito le commit da analizzare.
Se la ricerca non produce risultati, AKA non troviamo nessun bug. La commit segnalata come bad all’inizio dell’intero processo sarà giudicata colpevole.
Git ci farà vedere il log e il diff della commit. A questo punto possiamo terminare il processo con il comando:
1$ git bisect reset
Il quale ci mostrerà l’hash della commit dove ci trovavamo.
Ma bisogna fare tutto a mano?
La risposta è no.
Git bisect ha un sub-comando run che ci permette di eseguire dei test in maniera automatizzata. Tutto procederà in automatico.
Se il codice restituisce 0 il test è superato, se invece è tra 1 e 127 nel caso contrario ad eccezione del 125 che skipperà la commit.
I codici da 128 a 255 invece permettono di interrompere l’esecuzione nel caso git bisect ci stia impiegando troppo tempo. Per vedere all’opera un bisect automatizzato potete dare un’occhiata a questo repo dimostrativa.
Conclusioni
Se siamo amanti dello squash o della commit che comprende modifiche multiple in ogni punto dell’applicazione e senza apparente logica di raggruppamento il bisect non sarà un comando molto utile.
Torna quindi la solita raccomandazione del fare commit frequenti, così da rendere anche la fase di ricerca dei bug più veloce e meno snervante.
Caricamento...
Diventiamo amici di penna? ✒️
Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.
Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!