Idiota

Tutorial Git Bisect

Tutorial Git Bisect
Commentare i tuoi commit è una parte essenziale del mantenimento del codice tracciabile. Ti aiuta a tenere traccia dei problemi. Tuttavia, trovare un bug basato solo sui commenti è un compito noioso. Può volerci molto tempo per riordinare tutta la cronologia e capire quale commit è il colpevole.

Il comando git bisect fornisce un modo per accelerare il processo di rilevamento dei bug. Ti consente di individuare il problema più velocemente. Con git bisect, puoi definire un intervallo di commit che sospetti abbiano il codice problematico e quindi utilizzare metodi di eliminazione binaria per trovare l'inizio del problema. Trovare i bug diventa più facile e veloce.

Facciamo un esempio ed eseguiamo alcuni casi di test per vedere come funziona.

Esempio di configurazione

Nel nostro esempio, creeremo un test.txt e aggiungi una nuova riga al file con ogni commit. Dopo 16 commit, lo stato finale del file sarà simile a questo:

Ecco il mio buon codice 1
Ecco il mio buon codice 2
Ecco il mio buon codice 3
Ecco il mio buon codice 4
Ecco il mio buon codice 5
Ecco il mio buon codice 6
Ecco il mio buon codice 7
Ecco il mio buon codice 8
Ecco il mio codice errato 1 <-- BUG INTRODUCED HERE
Ecco il mio codice errato 2
Ecco il mio cattivo codice 3
Ecco il mio cattivo codice 4
Ecco il mio cattivo codice 5
Ecco il mio codice errato 6
Ecco il mio codice errato 7
Ecco il mio codice errato 8
Ecco il mio codice errato 9

Nell'esempio sopra, il bug è entrato nel codice dopo 8 commit. Abbiamo continuato a sviluppare il codice anche dopo aver introdotto il bug.

Puoi creare una cartella chiamata my_bisect_test e utilizzare i seguenti comandi dall'interno della cartella per creare la situazione di esempio:

git init
echo "Ecco il mio buon codice 1" > test.TXT
git add -A && git commit -m "Il mio commit 1"
echo "Ecco il mio buon codice 2" >> test.TXT
git add -A && git commit -m "Il mio commit 2 (v1.0.0)"
echo "Ecco il mio buon codice 3" >> test.TXT
git add -A && git commit -m "Il mio commit 3"
echo "Ecco il mio buon codice 4" >> test.TXT
git add -A && git commit -m "Il mio commit 4"
echo "Ecco il mio buon codice 5" >> test.TXT
git add -A && git commit -m "Il mio commit 5 (v1.0.1)"
echo "Ecco il mio buon codice 6" >> test.TXT
git add -A && git commit -m "Il mio commit 6"
echo "Ecco il mio buon codice 7" >> test.TXT
git add -A && git commit -m "Il mio commit 7 (v1.0.2)"
echo "Ecco il mio buon codice 8" >> test.TXT
git add -A && git commit -m "Il mio commit 8"
echo "Ecco il mio codice errato 1" > test.TXT
git add -A && git commit -m "Il mio commit 9"
echo "Ecco il mio codice errato 2" >> test.TXT
git add -A && git commit -m "Il mio commit 10"
echo "Ecco il mio codice errato 3" >> test.TXT
git add -A && git commit -m "Il mio commit 11"
echo "Ecco il mio codice errato 4" >> test.TXT
git add -A && git commit -m "Il mio commit 12 (v1.0.3)"
echo "Ecco il mio codice errato 5" >> test.TXT
git add -A && git commit -m "Il mio commit 13"
echo "Ecco il mio codice errato 6" >> test.TXT
git add -A && git commit -m "Il mio commit 14"
echo "Ecco il mio codice errato 7" >> test.TXT
git add -A && git commit -m "Il mio commit 15 (v1.0.4)"
echo "Ecco il mio codice errato 8" >> test.TXT
git add -A && git commit -m "Il mio commit 16"

Controllo della cronologia

Se guardi la cronologia dei commit, vedrai quanto segue:

$ git log
commit 3023b63eb42c7fadc93c2dd18b532a44a0a6888a
Autore: Zak H
Data: domenica 31 dicembre 23:07:27 2017 -0800
Il mio impegno 17
commit 10ef0286d6459cd5dea5038a54edf36fc9bfe4c3
Autore: Zak H
Data: domenica 31 dicembre 23:07:25 2017 -0800
Il mio impegno 16
commit 598d4c4acaeb14cda0552b6a92aa975c436d337a
Autore: Zak H
Data: domenica 31 dicembre 23:07:23 2017 -0800
Il mio commit 15 (v1.0.4)
commit b9678b75ac93d532eed22ec2c6617e5a9d70fe7b
Autore: Zak H
Data: domenica 31 dicembre 23:07:21 2017 -0800
Il mio impegno 14
commit eb3f2f7b0ebedb732ecb5f18bee786cd3cbbb521
Autore: Zak H
Data: domenica 31 dicembre 23:07:19 2017 -0800
Il mio impegno 13
commit 3cb475a4693b704793946a878007b40a1ff67cd1
Autore: Zak H
Data: domenica 31 dicembre 23:07:17 2017 -0800
Il mio commit 12 (v1.0.3)
commit 0419a38d898e28c4db69064478ecab7736700310
Autore: Zak H
Data: domenica 31 dicembre 23:07:15 2017 -0800
Il mio impegno 11
commit 15bc59201ac1f16aeaa233eb485e81fad48fe35f
Autore: Zak H
Data: domenica 31 dicembre 23:07:13 2017 -0800
Il mio impegno 10
commit a33e366ad9f6004a61a468b48b36e0c0c802a815
Autore: Zak H
Data: domenica 31 dicembre 23:07:11 2017 -0800
Il mio impegno 9
commit ead472d61f516067983d7e29d548fc856d6e6868
Autore: Zak H
Data: domenica 31 dicembre 23:07:09 2017 -0800
Il mio impegno 8
commit 8995d427668768af88266f1e78213506586b0157
Autore: Zak H
Data: domenica 31 dicembre 23:07:07 2017 -0800
Il mio commit 7 (v1.0.2)
commit be3b341559752e733c6392a16d6e87b5af52e701
Autore: Zak H
Data: domenica 31 dicembre 23:07:05 2017 -0800
Il mio impegno 6
commit c54b58ba8f73fb464222f30c90aa72f60b99bda9
Autore: Zak H
Data: domenica 31 dicembre 23:07:03 2017 -0800
Il mio commit 5 (v1.0.1)
commit 264267111643ef5014e92e23fd2f306a10e93a64
Autore: Zak H
Data: domenica 31 dicembre 23:07:01 2017 -0800
Il mio impegno 4
commit cfd7127cd35f3c1a55eb7c6608ecab75be30b208
Autore: Zak H
Data: domenica 31 dicembre 23:06:59 2017 -0800
Il mio impegno 3
commit 3f90793b631ddce7be509c36b0244606a2c0e8ad
Autore: Zak H
Data: domenica 31 dicembre 23:06:57 2017 -0800
Il mio commit 2 (v1.0.0)
commit cc163adb8a3f7b7b52411db2b3d8bab9b7fb191e
Autore: Zak H
Data: domenica 31 dicembre 23:06:55 2017 -0800
Il mio impegno 1

Anche con solo una manciata di commit, puoi vedere che è difficile individuare il commit che ha avviato il bug.


Trovare il bug

Usiamo git log -online per vedere una versione più pulita della cronologia dei commit commit.

$ git log --oneline
3023b63 Il mio commit 17
10ef028 Il mio commit 16
598d4c4 Il mio commit 15 (v1.0.4)
b9678b7 Il mio commit 14
eb3f2f7 Il mio commit 13
3cb475a Il mio commit 12 (v1.0.3)
0419a38 Il mio commit 11
15bc592 Il mio commit 10
a33e366 Il mio commit 9
ead472d Il mio commit 8
8995d42 Il mio commit 7 (v1.0.2)
be3b341 Il mio commit 6
c54b58b Il mio commit 5 (v1.0.1)
2642671 Il mio impegno 4
cfd7127 Il mio commit 3
3f90793 Il mio commit 2 (v1.0.0)
cc163ad Il mio commit 1

Vogliamo trovare la situazione in cui la riga "Ecco il mio cattivo codice 1 <- BUG INTRODUCED HERE” entered the picture.

Situazione 1

Supponiamo di ricordare che il nostro codice era valido fino alla v1.0.2 e vogliamo controllare da quel momento fino all'ultimo commit. Per prima cosa avviamo il comando bisect:

$ git bisect start

Forniamo il confine buono e il confine cattivo (nessun hash significa il codice più recente):

$ git bisect buono 8995d42
$ git bisect male

Produzione:

Bisezione: 4 revisioni rimaste da testare dopo (circa 2 passaggi)
[3cb475a4693b704793946a878007b40a1ff67cd1] Il mio commit 12 (v1.0.3)

Il comando bisect ha trovato il punto medio nel nostro intervallo definito e ha spostato automaticamente il codice per eseguire il commit 12. Possiamo testare il nostro codice ora. Nel nostro caso, emetteremo il contenuto di test.TXT:

$ prova del gatto.TXT

Produzione:

Ecco il mio buon codice 1
Ecco il mio buon codice 2
Ecco il mio buon codice 3
Ecco il mio buon codice 4
Ecco il mio buon codice 5
Ecco il mio buon codice 6
Ecco il mio buon codice 7
Ecco il mio buon codice 8
Ecco il mio codice errato 1 <-- BUG INTRODUCED HERE
Ecco il mio codice errato 2
Ecco il mio cattivo codice 3
Ecco il mio cattivo codice 4

Vediamo che lo stato di prova.txt è nello stato post-bug. Quindi è in cattivo stato. Quindi facciamo sapere al comando bisect:

$ git bisect male

Produzione:

Bisezione: 2 revisioni rimaste da testare dopo (circa 1 passaggio)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Il mio commit 9

Sposta il nostro codice in commit 9. Proviamo di nuovo:

$ prova del gatto.TXT

Produzione:

Ecco il mio buon codice 1
Ecco il mio buon codice 2
Ecco il mio buon codice 3
Ecco il mio buon codice 4
Ecco il mio buon codice 5
Ecco il mio buon codice 6
Ecco il mio buon codice 7
Ecco il mio buon codice 8
Ecco il mio codice errato 1 <-- BUG INTRODUCED HERE

Vediamo che abbiamo trovato il punto di partenza del bug. Il commit "a33e366 My commit 9" è il colpevole.

Infine, abbiamo riportato tutto alla normalità:

$ git bisect reset

Produzione:

La precedente posizione HEAD era a33e366... ​​Il mio commit 9
Passato al ramo 'master'

Situazione 2

Nello stesso esempio, proviamo una situazione in cui un altro sviluppatore inizia con la premessa che il bug è stato introdotto tra v1.0.0 e v1.0.3. Possiamo ricominciare il processo:

$ git bisect start
$ git bisect buono 3f90793
$ git bisect male 3cb475a

Produzione:

Bisezione: 4 revisioni rimaste da testare dopo (circa 2 passaggi)
[8995d427668768af88266f1e78213506586b0157] Il mio commit 7 (v1.0.2)

Bisect ha spostato il nostro codice in commit 7 o v1.0.2. Eseguiamo il nostro test:

$ prova del gatto.TXT

Produzione:

Ecco il mio buon codice 1
Ecco il mio buon codice 2
Ecco il mio buon codice 3
Ecco il mio buon codice 4
Ecco il mio buon codice 5
Ecco il mio buon codice 6
Ecco il mio buon codice 7

Non vediamo alcun codice errato. Quindi, fai sapere a git bisect:

$ git bisect buono

Produzione:

Bisezione: 2 revisioni rimaste da testare dopo (circa 1 passaggio)
[a33e366ad9f6004a61a468b48b36e0c0c802a815] Il mio commit 9

Ci ha spinto a impegnarci 9. Proviamo di nuovo:

$ prova del gatto.TXT

Produzione:

Ecco il mio buon codice 1
Ecco il mio buon codice 2
Ecco il mio buon codice 3
Ecco il mio buon codice 4
Ecco il mio buon codice 5
Ecco il mio buon codice 6
Ecco il mio buon codice 7
Ecco il mio buon codice 8
Ecco il mio codice errato 1 <-- BUG INTRODUCED HERE

Abbiamo nuovamente trovato il commit che ha introdotto il bug. Era il commit "a33e366 Il mio commit 9". Anche se abbiamo iniziato con la diversa gamma di sospetti, abbiamo trovato lo stesso bug in pochi passaggi.

Resettiamo:

$ git bisect reset

Produzione:

La precedente posizione HEAD era a33e366... ​​Il mio commit 9
Passato al ramo 'master'

Conclusione

Come puoi vedere dall'esempio, git bisect ci consente di individuare un problema più velocemente. È un ottimo strumento per migliorare la tua produttività. Invece di esaminare l'intera cronologia dei commit, puoi adottare un approccio più sistematico al debug.

Ulteriori studi:

https://git-scm.com/docs/git-bisect
https://git-scm.com/book/en/v2/Git-Tools-Debug-con-Git

Le 5 migliori carte di acquisizione del gioco
Abbiamo tutti visto e amato i giochi in streaming su YouTube. PewDiePie, Jakesepticye e Markiplier sono solo alcuni dei migliori giocatori che hanno g...
Come sviluppare un gioco su Linux
Un decennio fa, non molti utenti Linux avrebbero previsto che il loro sistema operativo preferito un giorno sarebbe diventato una piattaforma di gioco...
Porte open source di motori di gioco commerciali
Ricreazioni del motore di gioco gratuite, open source e multipiattaforma possono essere utilizzate per riprodurre titoli di giochi vecchi e abbastanza...