Wie kann man den Effekt einer Verschmelzung auf polarisierte Zweige umkehren, ohne an Qualen zu sterben?
Dieses Problem plagt mich seit Monaten und ich habe endlich aufgegeben.
Sie haben 1 Repository mit 2 benannten Zweigen. A und B.
Änderungen an A treten zwangsläufig bei B auf.
Änderungen, die direkt auf B auftreten, dürfen NIEMALS auf A erfolgen.
In einer solchen Konfiguration führt das Zusammenführen von "B" mit "A" zu einem schwerwiegenden Problem im Repository, da alle Änderungen an B in A so angezeigt werden, als wären sie in A vorgenommen worden.
Der einzige "normale" Weg, um sich von dieser Situation zu erholen, scheint darin zu bestehen, die Zusammenführung "zurückzuziehen", dh:
hg up -r A
hg backout -r BadMergeRev --parent BadMergerevBeforeOnA
Das sieht alles gut und gut aus, bis Sie sich entscheiden, später in die richtige Richtung zu verschmelzen, und am Ende alle möglichen bösen Dinge passieren und Code, der in einem bestimmten Zweig B gelöscht / auskommentiert wurde, plötzlich nicht mehr gelöscht oder nicht mehr kommentiert wird.
Bisher gab es keine praktikable Lösung für dieses Problem, außer "Lassen Sie es sein Ding machen und dann alle Probleme von Hand beheben", und das ist, um ehrlich zu sein, ein bisschen fubar.
Hier ist ein Bild, das das Problem verdeutlicht:
[Originalbild verloren]
Die Dateien C & E (oder Änderungen C & E) dürfen nur in Zweig b und nicht in Zweig a angezeigt werden. Revision A9 hier (Zweig a, Revno 9) ist der Beginn des Problems.
Die Revisionen A10 und A11 sind die Phasen "Backout Merge" und "Merge the Backout".
Und Revision B12 ist quecksilberhaltig und löscht fälschlicherweise wiederholt eine Änderung, die nicht gelöscht werden sollte.
Dieses Dilemma hat viel Frust und blauen Rauch verursacht und ich möchte dem ein Ende setzen.
Hinweis
Es kann die offensichtliche Antwort zu versuchen , die umgekehrte merge Verbot auftritt, entweder mit Haken oder mit Politik, ich habe die Fähigkeit hat dieses bis mucken ist ziemlich hoch und die Chance, es passiert so wahrscheinlich , dass auch mit Gegenmaßnahmen, Sie müssen noch Nehmen Sie an, dass dies unweigerlich passieren wird , damit Sie es lösen können, wenn dies der Fall ist.
Ausarbeiten
Im Modell habe ich separate Dateien verwendet. Dadurch klingt das Problem einfach. Diese stellen lediglich willkürliche Änderungen dar, die eine separate Zeile sein können.
Um die Verletzung zusätzlich zu beleidigen, gab es in Zweig A wesentliche Änderungen, die das ständige Problem hinterlassen. "Machen Sie die Änderungen in Zweig A zu einem Konflikt mit den Änderungen in Zweig B, die gerade aufgetaucht sind (und zurückgesetzt wurden), was wie eine Änderung aussieht stattdessen auf Zweig A "
Über Tricks zum Umschreiben der Geschichte:
Das Problem bei all diesen rückwirkenden Lösungen ist wie folgt:
- Wir haben 9000 Commits.
- Das frische Klonen dauert somit eine halbe Stunde
- Wenn es irgendwo nur einen fehlerhaften Klon des Repositorys gibt, ist es wahrscheinlich, dass er wieder mit dem ursprünglichen Repository in Kontakt kommt und ihn erneut aufschlägt.
- Jeder hat dieses Repository bereits geklont, und jetzt sind mehrere Tage mit laufenden Commits vergangen.
- Ein solcher Klon ist zufällig eine Live-Site, also "diesen löschen und von vorne anfangen" = "big nono"
(Ich gebe zu, viele der oben genannten sind etwas dumm, aber sie liegen außerhalb meiner Kontrolle).
Die einzigen Lösungen, die realisierbar sind, sind diejenigen, die davon ausgehen, dass Menschen alles falsch machen können und werden und dass es einen Weg gibt, diese Ungerechtigkeit rückgängig zu machen.
Antworten:
Ich glaube, ich habe eine Lösung gefunden, die die fehlerhafte Zusammenführung dauerhaft behebt und bei der Sie keine Unterschiede manuell überprüfen müssen. Der Trick besteht darin, in die Geschichte zurückzugehen und Commits parallel zur fehlerhaften Zusammenführung zu generieren.
Wir haben also ein Repository mit separaten Zweigen pro gepflegter Version eines einzelnen Produkts. Wie die in der Frage gestellte Situation müssen alle Änderungen, die an einem Zweig einer früheren Version vorgenommen wurden (dh die Bugfixes für diese Version), schließlich mit den Zweigen der späteren Versionen zusammengeführt werden.
Wenn also etwas in BRANCH_V8 eingecheckt ist, muss es mit BRANCH_V9 zusammengeführt werden.
Jetzt macht einer der Entwickler folgenden Fehler: Er führt alle Änderungen von BRANCH_V9 in BRANCH_V8 zusammen (dh eine Zusammenführung in die falsche Richtung). Darüber hinaus führt er nach dieser schlechten Zusammenführung einige zusätzliche Commits durch, bevor er seinen Fehler bemerkt.
Die Situation ist also wie im folgenden grafischen Protokoll dargestellt.
Wir können diesen Fehler wie folgt beheben:
hg update 11
$EDITOR some/file.txt
(dies ist erforderlich, da Mercurial keine leeren Commits zulässt.)hg commit -m "generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9"
Die Situation sieht nun wie folgt aus:
Führen Sie den neu generierten Kopf mit der Revision zusammen, in der die fehlerhafte Zusammenführung stattgefunden hat, und werfen Sie alle Änderungen weg, bevor Sie sie festschreiben. Führen Sie die beiden Köpfe nicht einfach zusammen, da Sie dann das wichtige Commit verlieren, das auch nach dem Zusammenführen stattgefunden hat!
hg merge 12
(Konflikte ignorieren)hg revert -a --no-backup -r 14
hg commit -m "throwing away wrong merge from BRANCH_V9"
Übernehmen Sie die Änderungen: Die Situation sieht jetzt so aus:Dh. Es gibt zwei Köpfe in BRANCH_V8: einen, der die Korrektur der fehlerhaften Zusammenführung enthält, und den anderen, der das übrig gebliebene wichtige Commit für BRANCH_V8 enthält, das unmittelbar nach der Zusammenführung stattgefunden hat.
hg merge
hg commit -m "merged two heads used to revert from bad merge"
Die Situation am Ende von BRANCH_V8 ist jetzt korrigiert und sieht folgendermaßen aus:
Jetzt ist die Situation auf BRANCH_V8 korrekt. Das einzige verbleibende Problem ist, dass die nächste Zusammenführung von BRANCH_V8 zu BRANCH_V9 falsch ist, da sie auch im 'Fix' für die fehlerhafte Zusammenführung zusammengeführt wird, was wir bei BRANCH_V9 nicht wollen. Der Trick hier besteht darin, in separaten Änderungen von BRANCH_V8 zu BRANCH_V9 zusammenzuführen:
Im Detail:
hg update BRANCH_V9
hg merge 14
hg commit -m "Merging in last good state of BRANCH_V8"
Die Situation ist jetzt:hg merge 15
hg revert -a --no-backup -r 17
hg commit -m "Merging in bad merge from BRANCH_V8 and its fix and throwing it all away"
Aktuelle Situation:hg merge BRANCH_V8
hg commit -m "merging changes from BRANCH_V8"
Am Ende sieht die Situation so aus:
Nach all diesen Schritten, in denen Sie keinen Unterschied manuell überprüfen müssen, sind BRANCH_V8 und BRANCH_V9 korrekt, und zukünftige Zusammenführungen von BRANCH_V8 zu BRANCH_V9 sind ebenfalls korrekt.
quelle
</pre>
nach dem vorletzten Codeblock fehlte etwas. Es hat eine Weile gedauert, bis ich gefunden habe, aber gerade als ich bereit war aufzugeben ... Jetzt wird alles richtig angezeigt, denke ich :)Zur Not können Sie das Repository in eine Reihe von Unterschieden exportieren, den Verlauf bearbeiten und dann genau das wieder zusammenkleben, was Sie möchten - in ein neues Repository, sodass kein Risiko einer Beschädigung besteht. Wahrscheinlich nicht schlecht für Ihr Beispiel, aber ich weiß nicht, wie die wahre Geschichte aussieht.
Ich habe auf diese Seite verwiesen, während ich eine einfachere Operation ausgeführt habe:
http://strongdynamic.blogspot.com/2007/08/expunging-problem-file-from-mercurial.html
quelle
OK, erstellen Sie zunächst ein neues leeres Repository in einem vom kaputten Repository getrennten Verzeichnis (hg init). Rufen Sie nun die letzte bekannte gute Version auf und fügen Sie sie in das neue Repository ein. stellen Sie sicher , nicht das schlechte Zusammenführung ziehen und tun Pull alles vor sich her. Aktualisieren Sie im alten Repository auf die letzte bekannte gute Version von A und gehen Sie folgendermaßen vor:
Dabei sind r1-3 Änderungen, die nach der verpfuschten Zusammenführung vorgenommen wurden. An dieser Stelle können Konflikte auftreten. repariere sie.
Dies sollte neue Änderungen gegenüber der letzten bekannten guten Version von A hervorrufen . Ziehen Sie diese neuen Änderungen in das neue Repository. Um zu überprüfen, ob Sie nichts verpasst haben, führen Sie einen HG-Eingang für das alte Repository durch. Wenn Sie etwas anderes als die verpfuschte Zusammenführung und r1-3 sehen, ziehen Sie daran.
Werfen Sie das alte Repository weg. Du bist fertig. Die Zusammenführung befindet sich überhaupt nicht im neuen Repository und Sie mussten den Verlauf nie neu schreiben.
quelle
Sie möchten also nur einige Änderungssätze von B in A zusammenführen? Das Zurücksetzen von Änderungssätzen wie bisher ist eine wirklich schlechte Idee, da Sie bereits gelitten haben.
Sie sollten entweder die Transplantatverlängerung verwenden oder einen dritten Zweig haben, in dem Sie allgemeine Änderungen vornehmen, um sowohl A als auch B zusammenzuführen.
quelle
Nach vielen Diskussionen mit einigen der hilfreichen Leute auf #mercurial on freenode hat mpm eine Teillösung bereitgestellt , die für meinen Testfall zu funktionieren scheint (ich habe ein gefälschtes Repository generiert, das versucht, das Szenario zu replizieren).
In meinem eigentlichen Repository ist es jedoch aus Gründen, die ich nicht ganz verstehe, immer noch nicht perfekt.
Hier ist ein Diagramm der derzeit vorgeschlagenen Methode zur Lösung dieses Problems:
[Originalbild verloren]
Es ist jetzt weniger ein Problem zu beheben, aber ich muss immer noch Unterschiede vergleichen (dh: b46: b11 gegen b46: b8, a43: a10 gegen a43: a9) und einige Änderungen von Hand bearbeiten.
Diese Frage nicht schließen / eine Antwort nehmen, bis ich eine garantierte Methode erhalte, die in jedem Repository funktioniert.
Wichtig
Jeder, der dieses Zeug ausprobiert, sollte sein Repository klonen und zuerst wie eine Sandbox damit spielen. Wie Sie es bei jedem Zusammenführungsprozess tun sollten , denn wenn es schief geht, können Sie es einfach wegwerfen und von vorne beginnen.
quelle