Ich versuche, einen Zweig mit Änderungen zu übernehmen und ihn so wiederherzustellen, dass er mit dem Upstream identisch ist, von dem er abweicht. Die Änderungen sind beide lokal und wurden auf Github verschoben, also weder git reset
noch git rebase
wirklich realisierbar, da sie die Geschichte ändern, was bei einem Zweig, der bereits verschoben wurde, eine schlechte Sache ist.
Ich habe es auch git merge
mit verschiedenen Strategien versucht, aber keine von ihnen macht die lokalen Änderungen rückgängig. Wenn ich also eine Datei hinzugefügt hätte, könnte eine Zusammenführung andere Dateien wieder in Einklang bringen, aber ich habe immer noch diese Datei, die der Upstream nicht hat haben.
Ich könnte einfach einen neuen Zweig außerhalb des Upstreams erstellen, aber ich möchte wirklich eine Zusammenführung, bei der in Bezug auf den Revisionsverlauf alle Änderungen angewendet werden, um meinen Zweig zu übernehmen und ihn wieder mit dem Upstream identisch zu machen, damit ich diese Änderung sicher vorantreiben kann ohne die Geschichte zu zerstören. Gibt es einen solchen Befehl oder eine Reihe von Befehlen?
quelle
Antworten:
Sie können Ihren Upstream-Zweig
dev
mit einem benutzerdefinierten Zusammenführungstreiber "keepTheirs" zu Ihrem Zweig zusammenführen :Siehe " "
git merge -s theirs
"erforderlich - aber ich weiß, dass er nicht vorhanden ist ".In Ihrem Fall
.gitattributes
wäre nur eines erforderlich und einkeepTheirs
Skript wie:git merge --strategy=theirs
Simulation # 1Wird als Zusammenführung angezeigt, wobei Upstream das erste übergeordnete Element ist.
Jefromi erwähnt (in den Kommentaren) das
merge -s ours
, indem er Ihre Arbeit im Upstream (oder in einem temporären Zweig, der vom Upstream ausgeht ) zusammenführt und dann Ihren Zweig schnell zum Ergebnis dieser Zusammenführung vorspult:(Edit 2011):
Dieser Workflow wurde in diesem Blog-Beitrag vom OP gemeldet :
git merge --strategy=theirs
Simulation # 2Shows als Zusammenführung, mit unserer als erstem Elternteil.
(vorgeschlagen von jcwenger )
git merge --strategy=theirs
Simulation # 3Dieser Blog-Beitrag erwähnt :
git merge --strategy=theirs
Simulation # 4(gleicher Blogbeitrag)
git merge --strategy=theirs
Simulation # 5(vorgeschlagen von Barak A. Pearlmutter ):
git merge --strategy=theirs
Simulation # 6(vorgeschlagen von demselben Michael Gebetsroither ):
git merge --strategy=theirs
Simulation # 7quelle
git checkout upstream; git merge -s ours downstream; git checkout downstream; git merge upstream
. (Verwenden Sie bei Bedarf einen temporären Zweig im Upstream.) Dies hat den Vorteil, dass der Upstream-Vorfahr als erstes übergeordnetes Element aufgezeichnet wird, sodass die Zusammenführung "diesen veralteten Themenzweig absorbieren" bedeutet, anstatt "diesen Themenzweig zu zerstören und zu ersetzen" es mit stromaufwärts ".Es klingt für mich so, als müssten Sie nur Folgendes tun:
Wenn es keine Änderung gibt, um Upstream zu pushen, und Sie einfach möchten, dass der Upstream-Zweig Ihr aktueller Zweig ist, wird dies das tun. Es ist nicht schädlich, dies lokal zu tun, aber Sie verlieren alle lokalen Änderungen **, die nicht an den Master gesendet wurden.
** Tatsächlich sind die Änderungen noch vorhanden, wenn Sie sie lokal festgeschrieben haben, da die Festschreibungen
git reflog
normalerweise noch mindestens 30 Tage bei Ihnen liegen .quelle
Sie können dies jetzt ziemlich einfach tun:
Dadurch wird Ihr lokales Repo mit dem Ursprung synchronisiert und der Verlauf bleibt erhalten.
quelle
git merge -s recursive -Xtheirs
führt Binärdateien nicht automatisch zusammen, sodass Sie in eine Konfliktsituation geraten, die Sie manuell lösen müssen. Workflows, die auf basieren,git merge -s ours
leiden nicht darunter.git show
bei einem Zusammenführungs-Commit werden nur Konfliktlösungen angezeigt, und es gibt-Xtheirs
offensichtlich keine Konfliktlösungen, wenn sie verwendet werden.Eine weitere Simulation für
git merge -s theirs ref-to-be-merged
:Eine Alternative zum doppelten Zurücksetzen wäre das Anwenden des umgekehrten Patches:
quelle
HEAD^2
) Die Patch-Methode hat funktioniert.^
richtig eingegeben . Manchmal werden andere Tastenanschläge wie "Strg-C" als "^ C" angezeigt. - Wenn Sie wirklich das richtige "^" eingegeben haben, haben Sie einen schwerwiegenden Fehler in Ihrer Git-Version gefunden.git reset --hard HEAD^^2; git reset --soft HEAD@{1}
Es gibt auch einen Weg mit wenig Hilfe des Sanitärbefehls - IMHO der einfachste. Angenommen, Sie möchten "ihre" für 2 Zweige emulieren:
Dies führt eine beliebige Anzahl von Köpfen (2 im obigen Beispiel) unter Verwendung des Baums eines von ihnen zusammen (Balken im obigen Beispiel, Bereitstellung des Baums "ihrer"), wobei alle Diff / File-Probleme außer Acht gelassen werden (Commit-Tree ist ein Befehl auf niedriger Ebene, also kümmert sich nicht um diese). Beachten Sie, dass der Kopf nur 1 sein kann (entspricht also Kirschpickel mit "ihrem").
Beachten Sie, dass der zuerst angegebene übergeordnete Kopf einige Faktoren beeinflussen kann (siehe z. B. - erster Elternteil des Befehls git-log). Denken Sie also daran.
Anstelle von git-show kann alles andere verwendet werden, das Tree- und Commit-Hashes ausgeben kann - unabhängig davon, was zum Parsen verwendet wird (Cat-File, Rev-List, ...). Sie können alles mit git commit verfolgen - ändern, um die Commit-Nachricht interaktiv zu verschönern.
quelle
Schwerfällig, aber zur Hölle, was kann möglicherweise schief gehen?
cp -r .git /tmp
git checkout y
rm -rf .git && cp -r /tmp/.git
.quelle
Wechseln Sie in den Remote-Upstream-Zweig und führen Sie eine Zusammenführung
git merge
mit der auf festgelegten Zusammenführungsstrategie durchours
.Der gesamte Verlauf ist weiterhin vorhanden, Sie haben jedoch ein zusätzliches Merge-Commit. Das Wichtigste dabei ist, von der Version zu beginnen, bei der Sie sein möchten, und
ours
mit dem Zweig zu verschmelzen, auf dem sich Github tatsächlich befindet.quelle
--strategy=theirs
, außer dass der nächste--strategy=recursive -X=theirs
das nicht ganz macht.--strategy=theirs
ist genau das Gegenteil von--strategy=ours
. Sie beginnen am anderen Ende (beginnen Sie also am Github und führen Sie es in die andere Richtung zusammen).--strategy=theirs
, was das Problem ist. Das nächste ist--strategy=recursive -X theirs
das Gegenteil, da es die irrelevanten lokalen Änderungen nicht entfernt, wenn sie nicht in Konflikt stehen.git checkout dev; git merge origin/master --strategy=ours
undgit checkout origin/master; git merge dev --strategy=ours
ours
Strategie macht es vollständig möglich, einetheirs
Strategie zu erstellen.Verwenden Sie git reset BACKWARDS!
Sie können einen Zweig wie jedes andere Commit aussehen lassen
git reset
, aber Sie müssen dies auf eine Art und Weise tun.Sie können dies tun, damit ein Zweig beim Festschreiben
<old>
wie ein Festschreiben aussieht<new>
um
<new>
den Inhalt des Arbeitsbaums zu machen .Dann mach
um den Zweig wieder auf das ursprüngliche Commit zu ändern, aber den Arbeitsbaum im
<new>
Status zu belassen .Anschließend können Sie die Änderungen hinzufügen und festschreiben, damit Ihr Zweig genau mit dem Inhalt des Festschreibens übereinstimmt
<new>
.Es ist kontraintuitiv, dass Sie ein Von von tun müssen, um vom
<old>
Staat zum Staat zu gelangen . Mit der Option bleibt der Arbeitsbaum jedoch bei und der Verzweigungszeiger wird auf gesetzt , sodass die Verzweigung beim Festschreiben der Änderungen so aussieht, wie wir es möchten.<new>
git reset
<new>
<old>
--mixed
<new>
<old>
Warnung
Verlieren Sie nicht den Überblick über Ihre Commits, z. B. vergessen Sie, was dabei
<old>
passiertgit reset --hard <new>
.quelle
Ich folgte diesen Rollen:
Holen Sie sich den Ursprung, setzen Sie ihn hart von der Verzweigung zurück, rekursiv von ihrer und erzwingen Sie dann das Drücken auf die Verzweigung
AUF EIGENES RISIKO
quelle