|
|
# `git bisect` Demo Repository
|
|
|
|
|
|
`git bisect` ist ein sehr nuetzliches Werkzeug um Regressionen zu finden, d.h. Fehler die in einer Codebasis im Laufe der Zeit eingefuehrt wurden. Hierbei hat man typischerweise eine alte Revision die fehlerfrei ist und eine neue Revision, die fehlerhaft ist.
|
|
|
|
|
|
## Beispielanwendung: Hello World
|
|
|
|
|
|
Das vorliegende "Hello World" ist ein triviales Beispiel um `git bisect` vorzufuehren.
|
|
|
|
|
|
## Vorbereitung
|
|
|
|
|
|
Zunaechst sollte das Repository ausgecheckt werden:
|
|
|
|
|
|
```console
|
|
|
$ git clone https://gitlab.cs.fau.de/i4/git-bisect-demo.git
|
|
|
Cloning into 'git-bisect-demo'...
|
|
|
remote: Counting objects: 41, done.
|
|
|
remote: Compressing objects: 100% (39/39), done.
|
|
|
remote: Total 41 (delta 23), reused 0 (delta 0)
|
|
|
Unpacking objects: 100% (41/41), done.
|
|
|
$ cd git-bisect-demo
|
|
|
```
|
|
|
|
|
|
Die Anwendung wird mittels `make` compiliert und kann dann ausgefuehrt und getestet werden:
|
|
|
```console
|
|
|
$ make
|
|
|
cc hello.c -o hello
|
|
|
$ ./hello
|
|
|
Howdy World!!!!
|
|
|
Sehr geehrte Damen und Herren Erdenbuerger, seien Sie hiermit herzlich gegruesst!
|
|
|
(c)2013 ACME
|
|
|
```
|
|
|
|
|
|
Eine Testsuite im Unterverzeichnis `t` kann mittels `make test` oder `prove` zur Ausfuehrung gebracht werden:
|
|
|
```console
|
|
|
$ make test
|
|
|
prove
|
|
|
t/00-hello-tests.t .. 1/5
|
|
|
# Failed test 'command stdout somehow greets everybody'
|
|
|
# at t/00-hello-tests.t line 16.
|
|
|
# Looks like you failed 1 test of 5.
|
|
|
t/00-hello-tests.t .. Dubious, test returned 1 (wstat 256, 0x100)
|
|
|
Failed 1/5 subtests
|
|
|
|
|
|
Test Summary Report
|
|
|
-------------------
|
|
|
t/00-hello-tests.t (Wstat: 256 Tests: 5 Failed: 1)
|
|
|
Failed test: 3
|
|
|
Non-zero exit status: 1
|
|
|
Files=1, Tests=5, 0 wallclock secs ( 0.05 usr 0.01 sys + 0.13 cusr 0.01 csys = 0.20 CPU)
|
|
|
Result: FAIL
|
|
|
Makefile:6: recipe for target 'test' failed
|
|
|
make: *** [test] Error 1
|
|
|
```
|
|
|
|
|
|
Hierbei faellt auf, dass die Tests fehlschlagen. Der Test prueft per regulaerem Ausdruck die Ausgabe von `./hello`:
|
|
|
```perl
|
|
|
ok($stdout =~ /(Hello|Hallo|Hi) (world|Welt|all|Alle)/i, "command stdout somehow greets everybody");
|
|
|
```
|
|
|
Die Ausgabe "Howdy World!" wird von diesem Ausdruck nicht erfasst, weswegen der Test fehlschlaegt.
|
|
|
|
|
|
Die aelteste Revision d208bcb6d450d365ebd707a582dbab182c6d0f40 hingegen weist diesen Fehler nicht auf.
|
|
|
```console
|
|
|
$ git checkout d208bc
|
|
|
Note: checking out 'd208bc'.
|
|
|
|
|
|
You are in 'detached HEAD' state. You can look around, make experimental
|
|
|
<...>
|
|
|
HEAD is now at d208bcb... initial version of hello world
|
|
|
$ make test
|
|
|
cc hello.c -o hello
|
|
|
prove
|
|
|
t/00-hello-tests.t .. ok
|
|
|
All tests successful.
|
|
|
Files=1, Tests=4, 0 wallclock secs ( 0.07 usr 0.01 sys + 0.15 cusr 0.01 csys = 0.24 CPU)
|
|
|
Result: PASS
|
|
|
```
|
|
|
|
|
|
## halbautomatisches `git bisect`
|
|
|
Zur halbautomatischen Suche der Revision, die den Fehler eingefuehrt hat kann man nun `git bisect` wie folgt beginnen:
|
|
|
```console
|
|
|
$ git checkout master
|
|
|
Previous HEAD position was d208bcb... initial version of hello world
|
|
|
Switched to branch 'master'
|
|
|
Your branch is up to date with 'origin/master'.
|
|
|
$ git bisect start
|
|
|
$ git bisect bad
|
|
|
$ git bisect good d208bcb
|
|
|
Bisecting: 5 revisions left to test after this (roughly 3 steps)
|
|
|
[2c463b9e8cc0b73fcacd82b99f51acfea2ea085c] germans are somewhat more formal...
|
|
|
```
|
|
|
Hiermit wurden nun die neueste Revision HEAD als kaputt und die aelteste d208bcb als funktionierend markiert. Im letzten Schritt hat `git bisect` automatisch eine ungefaehr in der Mitte befindliche Revision ausgecheckt, die nun getestet werden kann:
|
|
|
```console
|
|
|
$ make test
|
|
|
cc hello.c -o hello
|
|
|
prove
|
|
|
t/00-hello-tests.t .. ok
|
|
|
All tests successful.
|
|
|
Files=1, Tests=4, 0 wallclock secs ( 0.06 usr 0.00 sys + 0.22 cusr 0.02 csys = 0.30 CPU)
|
|
|
Result: PASS
|
|
|
```
|
|
|
Die Testsuite befindet diese Revision fuer gut, weswegen man hier nun diese als gut markiert. `git bisect` checkt automatisch die naechste zu testende Revision aus:
|
|
|
```console
|
|
|
$ git bisect good
|
|
|
Bisecting: 2 revisions left to test after this (roughly 2 steps)
|
|
|
[b2a30db52966bf32b0928dc05eb67879390ff589] the new Texan owner of our company requested this
|
|
|
```
|
|
|
|
|
|
Waere der Test fehlgeschlagen haette man dies per `git bisect bad` angezeigt. Waere die Revision untestbar, was auch vorkommen kann wenn beispielsweise das Compilieren fehlschlaegt, so zeigt man diese per `git bisect skip` an. Das Testen und Markieren wiederholt man bis keine Schritte und Revisionen mehr uebrig sind und ein Ergebnis feststeht:
|
|
|
|
|
|
```console
|
|
|
<...>
|
|
|
$ git bisect good
|
|
|
b2a30db52966bf32b0928dc05eb67879390ff589 is the first bad commit
|
|
|
commit b2a30db52966bf32b0928dc05eb67879390ff589
|
|
|
Author: Alexander Wuerstlein <arw@arw.name>
|
|
|
Date: Tue Jun 11 14:44:17 2013 +0200
|
|
|
|
|
|
the new Texan owner of our company requested this
|
|
|
|
|
|
:100644 100644 304528e494897bcc19d300d50c615882f8a4e20e 45ec4a19e69189070a83fd80266b4b71a839ed5b M hello.c
|
|
|
```
|
|
|
|
|
|
Mittels `git bisect log` oder `git bisect visualize` kann man sich den Verlauf oder die Uebergangsstelle ansehen. `git bisect reset` bringt die Arbeitskopie wieder in den Ursprungszustand.
|
|
|
|
|
|
## vollautomatisches git bisect
|
|
|
|
|
|
Die obigen iterativen Schritte, welche die Software wiederholt compilieren, testen und das Ergebnis an `git bisect` weiterleiten eignen sich sehr gut zur Automatisierung, wenn die Entscheidung ob der Test erfolgreich war vollautomatisch getroffen werden kann. Dann verkuerzt sich obige Beschreibung auf die Verwendung eines geeigneten Skriptes, hier [bisect.sh](bisect.sh):
|
|
|
```console
|
|
|
$ git bisect start
|
|
|
$ git bisect bad
|
|
|
$ git bisect good d208bcb
|
|
|
Bisecting: 5 revisions left to test after this (roughly 3 steps)
|
|
|
[2c463b9e8cc0b73fcacd82b99f51acfea2ea085c] germans are somewhat more formal...
|
|
|
$ git bisect run ./bisect.sh
|
|
|
<...>
|
|
|
[b6d36749a325e6a75a1ee83cf45a322f7eee7431] add missing header to make it compile
|
|
|
running ./bisect.sh
|
|
|
cc hello.c -o hello
|
|
|
prove
|
|
|
t/00-hello-tests.t .. ok
|
|
|
All tests successful.
|
|
|
Files=1, Tests=4, 0 wallclock secs ( 0.05 usr 0.00 sys + 0.15 cusr 0.00 csys = 0.20 CPU)
|
|
|
Result: PASS
|
|
|
./bisect.sh: version is good
|
|
|
b2a30db52966bf32b0928dc05eb67879390ff589 is the first bad commit
|
|
|
commit b2a30db52966bf32b0928dc05eb67879390ff589
|
|
|
Author: Alexander Wuerstlein <arw@arw.name>
|
|
|
Date: Tue Jun 11 14:44:17 2013 +0200
|
|
|
|
|
|
the new Texan owner of our company requested this
|
|
|
|
|
|
:100644 100644 304528e494897bcc19d300d50c615882f8a4e20e 45ec4a19e69189070a83fd80266b4b71a839ed5b M hello.c
|
|
|
bisect run success
|
|
|
```
|
|
|
|
|
|
## Voraussetzungen
|
|
|
|
|
|
- perl
|
|
|
- gcc
|
|
|
- make
|
|
|
- libtest-more-perl |
|
|
\ No newline at end of file |