Wir haben alle gehört , dass man sollte nie rebase Arbeit veröffentlicht, dass es gefährlich ist , usw. Allerdings habe ich keine Rezepte gesehen geschrieben, wie mit der Situation im Falle eines Fütterungsmaterial beschäftigen wird veröffentlicht.
Beachten Sie nun, dass dies nur dann wirklich machbar ist, wenn das Repository nur von einer bekannten (und vorzugsweise kleinen) Gruppe von Personen geklont wird, sodass jeder, der die Rebase oder das Zurücksetzen vorantreibt, alle anderen benachrichtigen kann, dass sie beim nächsten Mal aufpassen müssen holen(!).
Eine offensichtliche Lösung, die ich gesehen habe, funktioniert, wenn Sie keine lokalen Commits haben foo
und diese neu basiert:
git fetch
git checkout foo
git reset --hard origin/foo
Dies wird einfach den lokalen Status foo
zugunsten seiner Geschichte gemäß dem Remote-Repository wegwerfen .
Aber wie geht man mit der Situation um, wenn man in diesem Zweig wesentliche lokale Veränderungen vorgenommen hat?
quelle
git pull --rebase && git push
. Wenn Siemaster
nur daran arbeiten, wird dies nahezu immer das Richtige für Sie tun, selbst wenn Sie am anderen Ende neu gegründet und gedrückt haben.git reset --hard @{upstream}
jetzt auch, da ich weiß, dass die magische Refspec-Beschwörung für "Vergiss, was ich habe / hatte, benutze, was ich von der Fernbedienung abgerufen habe". Siehe meinen letzten Kommentar zu stackoverflow.com/a/15284176/717355push -f
): siehe meine Antwort untenAntworten:
Nach einer Push-Rebase wieder synchron zu sein, ist in den meisten Fällen nicht so kompliziert.
Dh. Zuerst richten Sie ein Lesezeichen für die ursprüngliche Position des Remote-Zweigs ein und verwenden dieses dann, um Ihre lokalen Commits ab diesem Zeitpunkt auf dem neu basierten Remote-Zweig wiederzugeben.
Rebasing ist wie Gewalt: Wenn es Ihr Problem nicht löst, brauchen Sie einfach mehr davon. ☺
Sie können dies natürlich auch ohne Lesezeichen tun, wenn Sie die
origin/foo
Commit-ID vor dem Rebase nachschlagen und diese verwenden.So gehen Sie auch mit der Situation um, in der Sie vergessen haben, vor dem Abrufen ein Lesezeichen zu erstellen. Es geht nichts verloren - Sie müssen nur das Reflog für den Remote-Zweig überprüfen:
Dadurch wird die Festschreibungs-ID gedruckt,
origin/foo
auf die vor dem letzten Abruf verwiesen wurde, der den Verlauf geändert hat.Sie können dann einfach
quelle
git reflog show origin/foo
Einzeiler nur in der Ausgabe von nach der ersten Zeile mit der Aufschrift "fetch: Forced-Update"; Das ist es, was Git aufzeichnet, wenn ein Abruf den Remote-Zweig dazu veranlasst, alles andere als einen schnellen Vorlauf durchzuführen. (Sie können es auch einfach von Hand machen - das erzwungene Update ist wahrscheinlich das Neueste.)Ich würde sagen, dass der Abschnitt zum Wiederherstellen von Upstream-Rebase auf der Manpage zu git-rebase so ziemlich alles abdeckt.
Es ist wirklich nicht anders, als sich von Ihrer eigenen Rebase zu erholen - Sie verschieben einen Zweig und stützen alle Zweige, die ihn in ihrer Geschichte hatten, auf seine neue Position.
quelle
Beginnend mit git 1.9 / 2.0 Q1 2014 müssen Sie nicht Ihre vorherigen Zweig Ursprung markieren , bevor sie auf dem neu geschrieben Upstream - Zweig Rebasing, wie sie in der Aristoteles Pagaltzis ‚s Antwort :
Siehe begehen 07d406b und begehen d96855f :
Deshalb hat der
git merge-base
Befehl eine neue Option:Zum Beispiel, wenn die Geschichte wie folgt aussah:
Git 2.1 (Q3 2014) wird diese Funktion noch robuster machen: siehe Commit 1e0dacd von John Keeping (
johnkeeping
)Behandeln Sie das Szenario mit der folgenden Topologie korrekt:
wo:
B'
ist eine feste Version davonB
, die nicht mit dem Patch identisch istB
;C*
undD*
sind pflaster identischC
undD
jeweils und Konflikt textuell , wenn in der falschen Reihenfolge angewandt wird ;E
hängt textlich ab vonD
.Das korrekte Ergebnis
git rebase master dev
ist , dassB
wie die gabelPunkt identifiziert wirddev
undmaster
, so dassC
,D
,E
sind die Festschreibungen , dass Bedarf an wiedergegeben werdenmaster
; aberC
undD
sind patch-identisch mitC*
undD*
und können so gelöscht werden, so dass das Endergebnis ist:Wenn der Gabelpunkt nicht identifiziert wird, führt die Auswahl
B
eines Zweigs, der enthält,B'
zu einem Konflikt. Wenn die patchidentischen Commits nicht korrekt identifiziert werden, führt die AuswahlC
eines Zweigs, derD
(oder gleichwertigD*
) enthält, zu einem Konflikt.Der "
--fork-point
" Modus von "git rebase
" ging zurück, als der Befehl in der Ära 2.20 in C neu geschrieben wurde, was mit Git 2.27 (Q2 2020) korrigiert wurde.Siehe Commit f08132f (09. Dezember 2019) von Junio C Hamano (
gitster
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit fb4175b , 27. März 2020)quelle