Was ist der beste Weg, um einen Git-Merge rückgängig zu machen, der Dateien aus dem Repo löscht?

13

Stellen Sie sich also Folgendes vor (und dass wir alle SourceTree verwenden):

  1. Wir arbeiten alle an der Entstehung / Entwicklung.
  2. Ich mache eine Woche Urlaub.
  3. Mein Kollege hat in den letzten Tagen vor Ort gearbeitet, ohne Herkunft / Entwicklung wieder in seiner lokalen Entwicklungsabteilung zusammenzuführen.
  4. Er versucht einen Push zu machen, bekommt die Anweisung, dass er zuerst verschmelzen muss und macht dann einen Pull.
  5. Er bekommt einen Konflikt und stoppt das automatische Festschreiben nach dem Zusammenführen.
  6. Unter der Annahme, dass Git wie SVN ist, verwirft mein Kollege die "neuen" Dateien in seiner Arbeitskopie und schreibt dann die Zusammenführung fest.
  7. Zu dieser Überarbeitung kommt noch eine Woche Entwicklungsarbeit.
  8. Ich komme aus den Ferien zurück und stelle fest, dass einige Tage meiner Arbeit fehlen.

Wir sind alle sehr neu in Git (dies ist unser erstes Projekt, das es verwendet), aber was ich getan habe, um es zu beheben, war:

  1. Benennen Sie "develop" in "develop_old" um.
  2. Füge develop_old zu einem neuen Zweig "develop_new" zusammen.
  3. Setzen Sie den Zweig "develop_new" auf den letzten Commit vor der fehlerhaften Zusammenführung zurück.
  4. Cherry wählt jedes Commit seitdem einzeln aus und löst Konflikte von Hand.
  5. Drücken Sie "Develop_old" und "Develop_New" bis zum Ursprung.

Jetzt ist develop_new, so hoffe ich, eine "gute" Kopie aller unserer Änderungen, die in den folgenden Wochen erneut durchgeführt wurden. Ich gehe auch davon aus, dass "Reverse Commit" bei einer Zusammenführung seltsame Dinge bewirken wird, zumal die Arbeit der nächsten Wochen darauf basiert - und da diese Zusammenführung eine Menge Dinge enthält, die wir wollen, zusammen mit Dingen, die wir nicht tun. ' t.

Ich hoffe, dass dies nie wieder vorkommt, aber wenn es doch wieder vorkommt, würde ich gerne eine einfachere / bessere Möglichkeit zur Fehlerbehebung finden. Gibt es eine bessere Möglichkeit, eine "schlechte" Zusammenführung rückgängig zu machen, wenn im Repo aufgrund dieser Zusammenführung viel Arbeit geleistet wurde?

George
quelle
1
Könnten Sie einen Screenshot des Git-Baums (entsprechend angepasst) oder die Ausgabe Ihres Lieblingsformats git logmit entsprechenden Anmerkungen zu den Ereignissen bei den verschiedenen Commits veröffentlichen? (Ich würde redigieren / kommentieren git log --graph --pretty=oneline --abbrev-commitund von dort aus gehen)
1
Es ist zu spät für Sie, aber Unit-Tests hätten das erkannt.
Nalply
1
@nalply: Nicht, wenn die fehlerhafte Zusammenführung auch die Komponententests gelöscht hat.
Aaronaught
Wow, das ist wirklich heimtückisches Pech.
Nalply

Antworten:

6

Wenn ich richtig verstanden habe, ist dies Ihre Situation:

    ,-c--c--c--c--M--a--a--X ← develop
o--o--y--y--y--y-´

Nach einigem gemeinsamen Werdegang (o) haben Sie sich verpflichtet und Ihre Arbeit vorangetrieben (y). Ihr Mitarbeiter (c) hat an seinem lokalen Repository gearbeitet und eine fehlerhafte Zusammenführung durchgeführt (M). Danach könnte es einige zusätzliche Commits (a) über M geben.

git reset --hard develop M^2
git branch coworker M^1

Jetzt sieht Ihr Diagramm genau so aus wie vor der schlechten Zusammenführung:

    ,-c--c--c--c ← coworker
o--o--y--y--y--y ← develop

Führe einen guten Merge durch (G):

git checkout develop
git merge coworker

Ergebend:

    ,-c--c--c--c-、
o--o--y--y--y--y--G ← develop

Jetzt verpflanzen Sie die zusätzlichen Commits:

git reset --hard X
git rebase --onto G M develop

Dies ergibt das Endergebnis:

    ,-c--c--c--c-、
o--o--y--y--y--y--G--a--a--X ← develop

Beachten Sie, dass dies zu mehr Zusammenführungskonflikten führen kann. Außerdem haben Sie gerade die Historie geändert, dh alle Ihre Mitarbeiter sollten auf die neue Historie klonen / zurücksetzen / zurücksetzen.

PS: natürlich solltest du G, Mund Xin deinen befehlen durch die entsprechende commit id ersetzen .

michas
quelle
In der Frage scheint es ziemlich offensichtlich zu sein, dass all diese Commits bereits in ein gemeinsames Repository verschoben wurden, daher halte ich ein Umbasieren nicht für eine gute Wahl. Es ist sicherer, alle kürzlich durchgeführten Commits zurückzusetzen und dann die wiederhergestellten, nicht in Konflikt stehenden Commits zusätzlich zur ordnungsgemäßen Zusammenführung auszuwählen.
Aaronaught
Das war der Teil mit dem Klon / Reset / Rebase. - Wenn es nur wenige Entwickler gibt, kann es eine gültige Option sein, sie aufzufordern, ihre Repositorys zu aktualisieren.
Michas
1

Es ist gut, dass Sie darüber nachdenken, wie Sie das Repository reparieren können. Wenn Ihr Kollege jedoch nur neue Dateien gelöscht und nicht viele Aktualisierungen überschrieben hat, ist es viel einfacher, die gelöschten Dateien einfach wiederherzustellen.

Ich würde wahrscheinlich anfangen, indem ich versuche, die ursprünglichen Commits, in denen Sie den Code hinzugefügt haben, der jetzt verschwunden ist, (auf den aktuellen Kopf) auszuwählen. Wenn dies aus irgendeinem Grund nicht funktioniert, checken Sie einfach die alte Revision mit den von Ihnen hinzugefügten Dateien aus und fügen Sie sie in einem neuen Commit erneut hinzu.

Was Sie beschreiben, ist eine Teilmenge eines bekannten Git-Anti-Patterns, an dessen Namen ich mich für mein ganzes Leben nicht erinnern kann. Das Wesentliche ist jedoch, dass Sie während eines Git-Merges "manuelle" Bearbeitungen vornehmen (dh Bearbeitungen vornehmen) Das Lösen von Zusammenführungskonflikten ist keine Selbstverständlichkeit, führt jedoch zu Änderungen, die nichts damit zu tun haben. Dies wird als äußerst schlechte Vorgehensweise angesehen, da sie im Wesentlichen durch die Zusammenführung selbst maskiert werden und in Codeüberprüfungen oder Debugging-Sitzungen leicht übersehen werden.

Erklären Sie Ihrem Kollegen also auf jeden Fall, dass dies ein epischer Fehlschlag war, aber erwägen Sie, auf ein Pflaster zu klopfen, bevor Sie sich auf eine größere Operation vorbereiten.

Aaronaught
quelle
Ich stimme zu, wenn ganze Dateien verschwunden sind, können Sie Folgendes tun, wenn Sie sich nicht um die Historie in den alten Dateien kümmern: 1.Erstellen Sie einen neuen Zweig aus dem derzeit fehlerhaften Zweig. 2.Schalten Sie zurück zum fehlerhaften Zweig und erstellen Sie einen neuen Zweig, der Ihr Rettungszweig ist. 4. Kopieren Sie die gelöschten Dateien irgendwo außerhalb von Git. 5. Wechseln Sie in den anderen neuen Zweig. 6. Kopieren Sie die neuen Versionen der gelöschten Dateien in den neuen Zweig und übernehmen Sie das Commit. Es gibt einen komplizierteren Weg, um Geschichte zu retten, der ein berühmter Beitrag von Linus T. ist
Elin
1
Tatsächlich zeigt dies, wie Sie den Checkout verwenden können. Jasonrudolph.com/blog/2009/02/25/… Das ist viel schöner.
Elin