Wie könnte ich git bisect verwenden, um das erste GUTE Commit zu finden?

90

Ich habe folgendes Problem:

  • Die Version bei masterfunktioniert gut
  • Die Version des letzten Tags vor master(sagen wir last) hat einen Fehler
  • Ein Kollege benötigt einen Patch für seine lastÜberarbeitung für diesen bestimmten Fehler

In Ordnung. Fragen wir unseren Freund git bisectnach der Revision, mit der der Fehler behoben wurde:

git bisect start
git bisect bad last
git bisect good master

Aber das wird nicht funktionieren:

Einige gute Drehzahlen sind keine Vorfahren der schlechten Drehzahl.
Git Bisect kann in diesem Fall nicht richtig funktionieren.
Vielleicht verwechseln Sie gute und schlechte Drehzahlen?

Irgendwelche Hinweise, um dies zu überwinden? Habe ich etwas in den Dokumenten verpasst?

eckes
quelle
1
Ich renne, git bisect run ...um die Halbierung zu automatisieren. Ich habe also keine Chance, nur die Wörter zu tauschen goodund bad(das war zu offensichtlich). Wie runfinde ich die erste gute Revision?
Daniel Böhmer
@ DanielBöhmer: Du musst Begriffe in deinem Skript austauschen , nicht wahr ?
eckes
Das von ausgeführte Skript git bisect rungibt gut oder schlecht als Exit-Code zurück, nicht als Zeichenfolge. Siehe meine Antwort, die ich gerade unten gepostet habe.
Daniel Böhmer
@ DanielBöhmer: Nun, in diesem Fall musst du den Rückkehrcode umkehren, nicht wahr?
eckes
Richtig, das ist in meiner Antwort beschrieben.
Daniel Böhmer

Antworten:

97

Ab Git 2.7 können Sie die Argumente --term-old und --term-new verwenden.

Zum Beispiel können Sie ein Commit zur Problembehebung folgendermaßen identifizieren:

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

Sagen Sie beim Testen git bisect fixedoder git bisect unfixednach Bedarf.

Alte Antwort für Versionen von Git vor 2.7

Anstatt sich vorübergehend zu trainieren, zu denken, dass schlecht gut und gut schlecht bedeutet, sollten Sie einige Aliase erstellen.

In ~/.gitconfigfügen Sie die folgende:

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

Sie können ein Commit zur Problembehebung folgendermaßen identifizieren:

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

Sagen Sie beim Testen git bisect-fixedoder git bisect-unfixednach Bedarf.

Michael Wolf
quelle
5
Abgesehen davon können Sie mit git keine Aliase für Unterbefehle erstellen. Daher die Striche. Wenn dies tatsächlich möglich ist (oder möglich ist), wird hoffentlich jemand die Antwort aktualisieren.
Michael Wolf
3
Selbst wenn Sie Aliase verwenden, wird die Ausgabe von git nicht angezeigt is the first bad commit, sodass immer noch foo gemeldet wird. Es scheint also, dass eine vorübergehende Schulung weiterhin erforderlich ist, nicht wahr?
ThomasW
2
Gutes Argument. (Hat Ihren Kommentar positiv bewertet.) Obwohl es hoffentlich zumindest ein bisschen weniger zusätzliche kognitive Belastung gibt, und als Programmierer haben wir bereits viel.
Michael Wolf
1
Ich empfehle die Verwendung von Aliasen 'vor' und 'nach'. Auf diese Weise haben Sie nicht den kognitiven Aufwand, die Inversion durchzuführen. "Wenn ich den Fehler sehe, sollte ich 'gut' schreiben." Stattdessen haben Sie nur den - wahrscheinlich geringeren - Aufwand, sich daran zu erinnern, dass Sie nach dem Auftreten / Verschwinden eines Fehlers suchen (dh sich daran zu erinnern, nach welcher Art von Änderung Sie suchen - "vor was?").
Jonas Kölker
1
@ JonasKölker, das ist eine tolle Idee. Ich habe die vorgeschlagenen Aliase in der Antwort sowie bisect-after = bisect badund bisect-before = bisect goodgemäß Ihrer Empfehlung verwendet. Jetzt kann ich beide Aliase verwenden. Wir werden sehen, welche ich nach ein paar Anwendungen am Ende mehr bevorzuge.
Gabriel Staples
47

Ich würde nur git "betrügen" und Bedeutungen von gut <=> schlecht tauschen.

Mit anderen Worten, betrachten Sie "schlecht" als etwas, das das Problem nicht aufweist, sodass dies nicht die "gute" Version ist, auf der Ihr Patch basiert.

Gut und Böse sind sowieso ziemlich subjektive Konzepte, oder? :) :)

git bisect start
git bisect good last
git bisect bad master
Inger
quelle
2
Nun, wenn Sie darüber nachdenken, gibt es keine allgemeine Bedeutung, was gut oder schlecht ist (wahrscheinlich nicht einmal in der Religion). Es hängt nur von Ihren Zwecken ab. Auf diese Weise betrügt es nicht wirklich - aber vielleicht Git's Sin (um beim religiösen Thema zu bleiben: D bedeutet, einen so umstrittenen Begriff aufzugreifen und nicht ein neutraleres "Ziel" / "Ursprung". Aber ja, Philosophie kann Verstand sein - boggling ;-)
inger
Dies muss das allererste Mal sein, dass ich höre, dass Fehler "gut" sein können.
MarcH
1
Das habe ich getan, bevor ich diese Frage gefunden habe. Ich werde es nicht mehr tun. Denken Sie daran, es dauert nur eine falsche Antwort, bis die gesamte Halbierung schief geht. Verdrehen Sie nicht Ihren Verstand.
Proski
20

Wenn Sie verwenden , git bisect runwie ich mit Perl zu tun proveBefehl (die automatischen Tests läuft) haben Sie keine Chance nur zu tauschen goodund bad. Der Erfolg der Tests wird als Exit-Code gemeldet.

Ich habe eine gültige Bash-Syntax gefunden, um den Exit-Code des Programms zu negieren, das ausgeführt wird von 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"

Dies gab mir die erste Überarbeitung, die die durchgeführten Tests bestand prove.

Daniel Böhmer
quelle
Ich stimme zu, ich möchte meinen Testfall lieber nicht ändern, damit dies perfekt ist.
Seanlinsley
8

Git jetzt können Sie verwenden , oldund newohne sie vorher zu definieren. Sie müssen git bisect startohne Commits als weitere Argumente aufrufen und dann die Halbierung ordnungsgemäß durch Aufrufen starten

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

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

Dies ist im Wesentlichen das, was @MarcH vorgeschlagen hat, implementiert zu werden.

GKFX
quelle
1
Dies ist die relevanteste Antwort (für moderne Git). Und der git bisect start --term-new fixed --term-old broken
Startbefehl
Wahr. Wann wurden diese Optionen eingeführt? Ich möchte meine Antwort aktualisieren.
Michael Wolf
@ MichaelWolf Sie erschienen in Version 2.7.0 .
GKFX
6

Git - Aliase sind eine gute Idee, aber die Bedingungen fixedund unfixedhaben das gleiche Problem als goodund bad: Sie können sie mit nicht haben vereinbar beiden Regressionen und Progressionen. Es ist einfach, Wörter zu finden, die in beide Richtungen funktionieren: Nehmen Sie sie einfach aus der ursprünglichen binären Suchterminologie auf, die von Natur aus neutral ist, ohne Vorurteile darüber, was gut oder schlecht ist. Zum Beispiel:

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

Mit solchen neutralen Begriffen können Sie immer Folgendes eingeben: git bisect-high(oder git bisect-upper, oder git-bisect max, ... Ihre Wahl!), Ob Sie nach einer Regression oder einem Fix suchen .

Schade, dass die Entwickler von git bisect keinen der vorhandenen Begriffe einfach wiederverwenden konnten. Die Benutzeroberfläche ist im Allgemeinen kein Problem von git: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/

März
quelle
Von: git.github.io/rev_news/2015/07/08/edition-5 "Einige Patch-Serien werden poliert, damit git bisect ein beliebiges Begriffspaar anstelle von gut und schlecht verwenden kann, ..."
MarcH