2013-07-03 7 views
5

Ich wollte „follow-up“ mit einer anderen Frage zu diesem Thema zur Kasse: Checkout old commit and make it a new commitWie ein alten begehen und macht es zu einem neuen begehen

Aber sie sagen, „das nicht tun!“ So scheint es, ich muss eine neue Frage stellen. (Auch wenn es die gleiche Frage ist, wo die Antwort, die ich denke, ist am besten für mich nicht wie erwartet funktionierte ...

Wenn ich verpflichtet A-B-C-D-E-F (man stelle sich diese alle Shas sind). ich das machen möchte gesamte Repository genau wie C und dann verpflichten, dass 'G' zu schaffen, die genau wie C ist. Also, wenn ich das Protokoll ABCDEFG ist sogar fertig bin, obwohl C & G identisch sind.

Eine Antwort cherry-pick angezeigt, die perfekt schien , außer dass ich jeden Konflikt zwischen C und F gelöst habe. Ich schaute auf die Dokumentation und Ich habe versucht, --force sowieso, und dann die Empfehlung für --patch. --patch war am nächsten, aber es war nicht absolut. Also gibt es eine Möglichkeit, Cherry-Pick wählen Sie einfach die C Version des Konflikts?

Die andere nächste Antwort wäre C, aber ich konnte das magische Wort nicht finden, das es auf dem gleichen Zweig behalten würde. Das letzte Training, das ich abgeschlossen habe, sagte "magic dash dash" am Ende, um git zu sagen, dass Sie dies auf dem aktuellen Zweig wollen, aber egal was ich mache, erstellt es einen Zweig "(kein Zweig)".

Wie ich sicher bin, kann ich sagen, ich bin ziemlich neu in Git (und Kommandozeile im Allgemeinen), aber ich habe versucht, es selbst herauszufinden. Wenn Sie die ausführlichen Versionen dessen verwenden könnten, was Sie empfehlen, dann bleibt es in meinem Kopf besser und würde sehr geschätzt werden. (-a = --all oder -a = --annotate oder -a = --albuquerque?)

Es scheint so einfach und genau das, was Sie vielleicht mit git tun wollen - gehen eine vorherige begehen, ohne den Vermittler zu verlieren verpflichtet, falls Sie Ihre Meinung ändern.

+2

Was meinen Sie mit "Wo sind D, E und F genau dort?" –

+0

"genau dort" bedeutet, dass das vollständige Protokoll, wenn ich fertig bin, ABCDEFG ist, obwohl C & G identisch sind –

Antwort

5

Haben Sie etwas dagegen Erzeugungs: A-B-C-D-E-F-F'-E'-D', wo der Zustand des Codes bei D' genau ist, wie es bei C (so G == D') war? In diesem Fall geben Sie einfach F, E und zurück. Wenn Sie die Zwischenschritte nicht möchten, wenden Sie sich nicht an revert und dann Commit. Das heißt:

$ git revert -n HEAD 
$ git revert -n HEAD~ 
$ git revert -n HEAD~2 
$ git commit -m 'Revert D,E,and F' 

Danach wird die aktuelle HEAD ist G, und die beiden Commits G und C sollten den gleichen Codebaum enthalten. Sie können dies überprüfen, indem Sie die Ausgabe von git cat-file -p HEAD | grep ^tree und git cat-file -p C | grep ^tree überprüfen. Beide Befehle sollten die gleiche Ausgabe liefern.

Aber es ist nicht wirklich klar, warum Sie das Zwischenkommando behalten wollen. Wenn Sie sie für die Nachwelt wollen, dann tun Sie etwas wie: git branch old-stuff, git reset C Das wird Ihren aktuellen Zweig wieder auf C, aber , E und F kann immer noch in der Branche mit dem Namen old-stuff angezeigt werden.

+0

Noch einmal, vielleicht ist die Antwort "Nein, es gibt keinen einfachen Ein-Schritt-Befehl, um das gesamte Repository zurück zu a previous commit-state _als_ ein neues Commit ". Ich weiß, dass ich es mit Verzweigungen oder sukzessiven Rückgaben tun kann, aber diese sind für meinen Anwendungsfall übertrieben. Vielen Dank! –

0

Wenn Sie wollen, um am Ende mit: -G-D-E-F („Wo D, E und F sind genau dort“ bin nicht sicher, ich bin verwirrt) dann der beste Weg, um dorthin zu gelangen ist rebase -i und Squash A-B-C zusammen.

+0

Sorry, dieser Satz war nicht präzise. Was ich am Ende will, ist die Full-Commit-Historie von A-B-C-D-E-F-G, obwohl C & G zufällig identisch sind. Ich bin aufgeregt, einen guten Anwendungsfall für Rebase zu finden und ich höre, wie groß es ist, aber von dem, was du schreibst, denke ich nicht, dass es hier gut passt. Vielen Dank! –

+0

Ich bin ein wenig verwirrt darüber, warum du das willst? Es ist nicht etwas, das du schieben möchtest, da es sich um eine verkappte Version von D-E-F handelt. Du könntest tatsächlich mit git revert D E F dorthin gehen. Aber warum? Wenn Sie D E F als Referenz behalten möchten, dann schieben Sie sie in einen separaten Zweig und dann schwer auf C zurückgesetzt erscheint als eine bessere Lösung. – ptyx

0

Geht man von Ihren Kommentar zu meiner anderen Antwort (die ich nicht löschen, da diese Lösung richtiger als das ist, aber dies scheint zu sein, was Sie wollen), können Sie einfach den Befehl Sanitär verwenden commit-tree wie folgt:

Dabei ist $ tree der Hash des dem Baumobjekt zugrunde liegenden Commits C. Dies erzeugt ein neues Commit, in dem der zugrunde liegende Baum identisch mit dem von Commit C ist, aber das Elternteil des neuen Commits ist Commit F. Es setzt auch den aktuellen Zweig, um auf dieses neue Commit zu zeigen, was es zum neuen HEAD macht.

0

Können Sie beschreiben, was Sie wollen als: "Machen Sie Ihren Arbeitsbaum gleich wie C, dann begehen Sie das"? Wenn ja, hier ist ein Weg, dies zu tun:

git checkout C  # working tree same as C. But also moves HEAD to C... 
git reset F  # ...so move HEAD back to F, leaving working tree alone 
git commit -a  # commit working tree 

EDIT könnte dies eine Reihe von Merge Konflikten erzeugen, so ist es nicht, dass ein Teil Ihrer Frage nicht befassen.

EDIT3 Noch einmal, die selected answer zu Ihrer vorherigen Frage löst dies: indem Sie zuerst alles löschen, gibt es keinen Konflikt.


BTW: es wäre schön, den Arbeits Baum gleich zu machen C zu begehen, ohne HEAD zu ändern, aber ich glaube nicht, dass es ein (Porzellan), das zu tun. Sowohl git checkout als auch git reset ändern den aktuellen Zweig, wenn Sie den gesamten Commit wünschen. git checkout können einzelne Dateien in den Arbeits Baum extrahieren, ohne den aktuellen Zweig zu bewegen, aber dann müssen Sie jede Datei einzeln extrahieren, nicht die ganze begehen ...

EDIT2 oh ich von der selected answer zu Ihrer vorherigen Frage zu sehen, Sie können dies tun. Ich hatte git checkout C -- "*" versucht, aber Sie brauchen git checkout C -- . So würde es nur sein:

git checkout C -- . # working tree same as C, without moving branch (NB ".") 
git commit -a 
1
git cherry-pick --strategy=recursive -X ours C 

git-merge(1):

Die rekursive Strategie können die folgenden Optionen nehmen:

unsere

Diese Option erzwingt die automatische Auflösung von in Konflikt stehenden Punkten, indem unsere Version unterstützt wird. [...]

Die "ours" und "ihre" beziehen sich auf die beiden Commits verschmolzen werden.Wie auch immer, ich bin nicht sicher, in welcher Richtung git cherry-pick die Commits behandelt, so dass Sie stattdessen -X theirs benötigen. Du könntest einen neuen Zweig machen, es ausprobieren und sehen.

0

Sieht so aus, als ob C der Endzustand Ihres Git-Repositorys sein soll.

Take "ABCDEFG" als Beispiel,

Sie können einfach wiederherstellen G, F, E, D, um mit

git revert [commitID]

Dann git commit

Nach G verwenden, F, E, D sind alle zurückgesetzt, Ihr Repository bleibt im Zustand wie C.

Eine alternative Möglichkeit, nur für die lokale Niederlassung ist:

git resert --hard HEAD~4

Dies wird Ihre lokale Niederlassung zurückgesetzt C zu begehen und Drop D, E, F, G.

Verwandte Themen