Wenn ein Unterprojekt eine Teilbaumzusammenführung ist, wie kann ich ein Commit rückgängig machen, das von der Teilbaum-Fernbedienung kam?

8

Ich habe ein Testcase-Shell-Skript . Ich möchte ein Teilprojekt herabstufen , kann aber nicht herausfinden, wie. Hier ist die Geschichte:

Ich habe zwei Repos erstellt, " Unterprojekt " und " superproject ". Ich habe mehrere Versionen einiger Dateien in ein Unterprojekt geschrieben und ihnen die Tags "v0", "v1", "v2" usw. gegeben. Im Superprojekt habe ich das Unterprojekt als Repo hinzugefügt und es als Teilbaum zusammengefügt:

%Vor%

Als nächstes aktualisiere ich das Unterprojekt auf v3, und das geht gut:

%Vor%

Aber dann merke ich, dass ich wirklich v2 will. Ich denke, was ich hier brauche, ist eine Rebase, aber ich bin mir nicht sicher. Folgendes habe ich versucht:

%Vor%

Aber ich sehe, dass der Inhalt des Unterprojekts über das Hauptverzeichnis meines Superprojekts hinausgespuckt wird!

Also habe ich etwas gelesen und ein paar andere Ideen gefunden. Dieser hat nicht funktioniert:

%Vor%

Es spoojed auch Dateien in meinem Superprojekt und beschwerte sich über Konflikte. Das hat auch nicht funktioniert:

%Vor%

Offensichtlich wurde v3 bereits zusammengeführt, so dass das Zusammenführen von v2 (ein Vorgänger von v3) keine Auswirkungen hat.

Das einzige was ich gefunden habe, was zu einem Downgrade führt ist:

%Vor%

Aber ich mag es nicht, weil es keine korrekte Herkunft in der Commit-DAG anzeigt. Es ist nur ein Brute-Force-Umschreiben des Baumes. Außerdem ist es auf das Patch-Programm angewiesen, um "Zusammenführen" zu machen, was bei weitem nicht so schlau ist wie das Verschmelzen von Git. Wenn superproject vor dem Downgrade Änderungen am Unterprojekt vorgenommen hat, wird Patch nicht so wahrscheinlich Zusammenführungsfehler auflösen, wie es bei der Zusammenführung von Dateien der Fall wäre.

Gibt es eine kanonische Möglichkeit, eine Teilprojektversion mithilfe von Teilbaumverschmelzungen wiederherzustellen? Wenn nicht, gibt es zumindest etwas besser als diff | patch ?

    
Dave 28.04.2011, 18:12
quelle

2 Antworten

13

Letztendlich ist git revert v3 in superproject fehlgeschlagen, weil nicht berücksichtigt wird, dass v3 hinter einer Teilbaumzusammenführung steht (daher unterscheiden sich die aufgezeichneten Pfadnamen in N und v3 ).

Zurücksetzen auf superproject history

Mit Git 1.7.5 können Sie

verwenden %Vor%

anstelle Ihrer git diff | patch; commit -Methode. Es wird möglicherweise die Zusammenführungs-Maschinerie besser nutzen. Bei beiden Methoden wird das übergeordnete Element des neuen Commits jedoch auf dem Verlauf von superproject aufgebaut (was möglicherweise nicht das ist, was Sie wirklich wollen).

Ihr subproject Verlauf sieht folgendermaßen aus:

%Vor%

Ihr superproject history sieht folgendermaßen aus:

%Vor%

Beide Methoden erstellen commit O mit diesem Verlauf:

%Vor%

Zurücksetzen auf subproject history

Sie könnten mit einem Commit, das direkt auf v3 erstellt wurde, glücklicher sein. Sie könnten einen solchen Commit in den superproject Verlauf unterteilen, wie Sie es mit einem neuen subproject commit tun.

  • In subproject : checkout v3 , rückgängig machen ( R ), und das Ergebnis markieren ( revert-v3 )

    %Vor%

    Resultierende Geschichte:

    %Vor%
  • In superproject : Holen Sie das Ergebnis und verwenden Sie Teilbaum-Zusammenführung ( P ), um es einzubinden

    %Vor%

    Resultierende Geschichte:

    %Vor%

Wenn Sie revert-v3 in subproject nicht selbst haben möchten (zB weil v3 im Kontext von subproject in Ordnung ist, aber nicht geeignet ist in superproject ), dann können Sie das tun Erledigen Sie die Arbeit vollständig in superproject auf Kosten von Ihrem Arbeitsbaum (das Hin- und Herwechseln zwischen "nicht verwandten" Commits wird effektiv alle Ihre Arbeitsbaumdateien löschen und wiederherstellen, so dass sich die Mtimes, Inodes usw. geändert haben):

  • In superproject : checkout v3 , rückgängig machen, markieren, zurück zum vorherigen Checkout, Teilbaum den neuen Commit zusammenführen

    %Vor%

Der Hauptunterschied besteht darin, dass das letzte revert-v3 -Tag nur in superproject in dieser zweiten Variation vorhanden ist. Die resultierende Geschichte hat die gleiche Struktur und den gleichen Inhalt wie die erste Variante.

Wenn Sie den Arbeitsbaum von subproject oder superproject nicht belassen können und revert-v3 in subproject nicht möchten, können Sie einen temporären Klon von subproject verwenden (im Klon: Setzen Sie das Commit zurück, markieren Sie es; in superproject : holen Sie das Tag aus dem Klon, fügen Sie den Teilbaum zusammen und löschen Sie den temporären Klon).

git subtree

Vielleicht möchten Sie den git subtree Befehl von apenwarr untersuchen. Die Unterstützung für Teilbaumverschmelzungen ist etwas gestrafft (z. B. git subtree pull -P prefix repository refspec ). Auch sein git subtree split -Befehl kann von besonderem Interesse sein, da Sie damit die aus dem Ergebnis von git diff new old | patch (oder git revert --strategy ) vorgenommene Festschreibung in eine Festschreibung transformieren könnten, die direkt über dem Verlauf des Teilbaums erfolgt zu sein scheint.

git subtree split --prefix=subproject/ --onto v1 1 würde den "revert on top of superproject " Verlauf nehmen:

%Vor%

und extrahiere einen subproject -only-Verlauf wie folgt:

%Vor%

Dabei ist alles vor R' das ursprüngliche subproject Verlauf und R' ist eine Version von R mit nur dem Inhalt von subproject/ .

Diese Fähigkeit, "nach der Tat" zu extrahieren, bedeutet, dass Sie einfach an dem Inhalt in superproject arbeiten können, ohne sich darum kümmern zu müssen, ob die Commits, die subproject/ berühren, Kandidaten für das Senden von "upstream" an die% co_de sein könnten % Repository.

1 Du könntest subproject abbrechen, wenn du --onto v1 benutzt hast, um den Unterbaum 2 hinzuzufügen. Es fügt speziellen Text in die Commit-Nachrichten ein, die es generiert, damit es die "Teilbaum" -Bits des Verlaufs identifizieren kann.

2 Oder Sie könnten mit etwas wie

in git subtree add konvertieren %Vor%     
Chris Johnsen 29.04.2011, 07:41
quelle
1

Vielleicht würde die Verwendung von Git Submodulen mit Hilfe von Git-Slave helfen. Alternativ können Sie auch nur ein Repository verwenden und die Änderungen am Unterprojekt in einer separaten Verzweigung oder Gruppe von Zweigen beibehalten.

Hoffe, das hilft.

    
Adam Dymitruk 28.04.2011 23:54
quelle

Tags und Links