2015-01-20 5 views
23

Mehrere Male in der Vergangenheit hatten wir ein Problem, wo Entwickler (entweder explizit oder effektiv) eine git merge -s ours gemacht haben, wenn sie nicht haben sollten, wurden verloren und wir haben nur so viel später erkannt, wenn die Bereinigung ist viel komplexer und zeitaufwendiger. Tests sind nicht fehlgeschlagen, da die eigentlichen Commits, die die Tests hinzugefügt haben, automatisch mit dem Code, den sie getestet haben, rückgängig gemacht wurden.Wie kann ich eine Zusammenführung zusammenfassen, um fehlerhafte `git merge -s ours` zu erkennen?

Was ich möchte, ist tun zu finden oder ein Werkzeug zu schaffen, die eine Zusammenführung zusammenfasst, eine Ausgabe so etwas wie die folgenden mit einem normalen merge Herstellung:

Lines    Left(2b3c4d) Right(3c4d5e) 
Common with base 970   930 
Unique wrt base 20   50 
Unique wrt other 15   45 
Unique wrt merge 15   45 
Common with merge 995   985 

Aber in dem Fall, dass eine Zusammenführung falsch gemacht wurde , viele Änderungen Zurücksetzen aus, oder wo ein git merge -s ours durchgeführt wurde, könnte es in einem Bericht etwas ergeben wie:

Lines    Left(2b3c4d) Right(3c4d5e) 
Common with base 970   930 
Unique wrt base 20   50 
Unique wrt other 15   45 
Unique wrt merge 15    0 !! 
Common with merge 990   935 
Warning: 100% of changes from 3c4d5e are missing from merge commit! 

Wenn dieser Bericht ausgeführt wurden für jeden begehen, könnten wir Fahne (durch einen jenkins Job), wenn ein Zusammenführen war ein wenig auf der stinkenden Seite.

Bisher habe ich mit git diff --stat, git diff --name-status und git diff --summary gespielt, aber bisher gibt mir keiner ganz was ich will.

Das Beste, was ich bisher in etwa wie folgt für einen normalen merge würde tun können:

   base..left base..right left..merge right..merge 
       f67c4..a9eb4 f67c4..5b592 a9eb4..cb209 5b592..cb209 
a |     1 +   1 +   
b |  1 +         1 + 
base |  1 +   1 +   1 +   1 + 
changed  2   2   2   2 
insertions(+) 2   2   2   2 
deletions(-) 0   0   0   0 

und für eine ours merge:

   base..left base..right left..merge right..merge 
       f67c4..a9eb4 f67c4..5b592 a9eb4..95637 5b592..95637 
a |     1 +      1 - 
b |  1 +         1 + 
base |  1 +   1 +      2 +- 
changed  2   2   0   3 
insertions(+) 2   2   0   2 
deletions(-) 0   0   0   2 

Bitte beachte, dass ich nicht nur tun möchte eine -s ours merge erkennen, ich möchte auch die Situation abfangen, wo einige, aber nicht alle Änderungen in der resultierenden Zusammenführung sind. Dies ist ein allgemeinerer Fall, in dem fehlerhafte Zusammenführungen festgestellt werden, als nur eine bestimmte Ursache von verlorenen Änderungen zu überprüfen.

Dies scheint auch nur dann zu passieren, wenn es Konflikte in der Zusammenführung gibt, so dass jede Methode, die die Zusammenführung automatisch erneut ausführen muss, diese Konflikte ebenfalls automatisch auflösen muss.

Schließlich möchte ich in der Lage sein, diese Zusammenfassung Dienstprogramm auf einem schmutzigen Repo ausführen, ohne alle meine Änderungen zuerst zu verstauen, daher meine aktuellen Experimente mit git diff.

Irgendwelche Vorschläge, wie ich zu dieser Art von Informationen direkter kommen kann als ein Skript mit viel Parsing und Neuformatierung würde geschätzt werden.

Die nächsten bestehenden Fragen, die ich diese finden können, sind: Detect a merge made by '-s ours' (aber die einzige Antwort, es hilft nicht) und “git merge -s ours” and how to show difference (aber es gibt keine Antworten alles an).

+2

Eine einfache Möglichkeit, eine '-s unsere' Zusammenführung zu erkennen, besteht darin, ein Diff gegen beide Eltern des Zusammenführungs-Commits auszuführen. Wenn ein Unterschied ** leer ** ist und die Eltern anders sind, ist es ein sicheres Zeichen, dass "-s unser" (oder Äquivalent) durchgeführt wurde. Zum Beispiel können Sie '$ (git show --pretty =% P $ commit)' durchlaufen und warnen 'if! git diff -s --exit-code $ parent .. $ commit'. – user4815162342

+0

Der beste Weg, um zu sehen, was in einem Merge-IMO passiert ist, besteht darin, den Merge selbst zu wiederholen und dann das Ergebnis mit der tatsächlichen Merge zu vergleichen. So 'git Kasse ; Git mischen ; git diff ' –

+0

Danke @ user4815162342, das ist ziemlich viel, was ich oben mache, mit' git diff --stat' auf 'base..left',' base..right', 'left..merge' &' richtig ... merge. Außerdem möchte ich nicht annehmen, dass ein "-s unsers" fusioniert, ich möchte auch die Situation erfassen, in der einige, aber nicht alle Änderungen in der resultierenden Zusammenführung sind. Ich habe meine Frage aktualisiert, um beide klarer zu machen. –

Antwort

1

Ich hatte dieses genaue Problem, und am Ende schrieb ich ein Tool, um diese Arten von Zusammenführungen zu erkennen. Obwohl ich den eigentlichen Code nicht teilen kann (er gehört technisch meinem Arbeitgeber), ist der Algorithmus sehr einfach: Sei S1 die Menge aller Dateien, die sich zwischen dem Merge und dem zweiten Elternteil des Merges befinden. Sei S2 die Menge aller Dateien, die Änderungen zwischen der Zusammenführung und der Zusammenführungsbasis haben. Subtrahieren Sie S2 von S1, und Sie bleiben mit dem Satz von Dateien, die wahrscheinlich Änderungen aufgrund der Zusammenführung verloren haben.

Dies wird nicht nur verschmilzt mit -s ours gemacht ermitteln, wird sie auch verpfuschte detect geht, wo einig, aber nicht alle, die Veränderungen in den zweit Eltern es in die Zusammenführung gemacht.