Rebasen Sie einen Zweig, ohne ihn auszuchecken

Lesezeit: 5 Minuten

Benutzer-Avatar
Manisherde

Ich arbeite also an einem Projekt, das manchmal lange Build-Zeiten hat, und der Build wird sehr oft vermasselt. Wenn ich einen älteren Zweig mit einigen laufenden Arbeiten habe (der festgeschrieben wurde, aber auf einem älteren Elternteil basiert), wird ausgeführt git checkout oldbranch ändert das Arbeitsverzeichnis, um den gesamten alten Code darzustellen, was dazu führt, dass ich erneut einen vollständigen Build ausführen muss.

Normalerweise habe ich jedoch nur ein oder zwei Dateien geändert, und der Rest muss nicht zurückgesetzt werden. Was ich tun möchte, ist, diesen Zweig auf den aktuellen Masterhead umzubasieren und diese Änderungen an den Dateien beizubehalten.

Grundsätzlich, wenn a.rs und b.rs geändert wurden, dann brauche ich eine Möglichkeit, diese Änderungen auf dem aktuellen Kopf basieren zu lassen, ohne andere Dateien als diese beiden zu berühren.

Gibt es einen Git-ish-Weg, dies zu tun? Derzeit jongliere ich mit Patch-Dateien, um dies zu tun.

  • Das macht keinen Sinn. Wenn für den alten Zweig „Arbeiten im Gange“ sind, warum ist er nicht bereits ausgecheckt?

    – Zombo

    6. April 2014 um 4:26 Uhr

  • @StevenPenny Weil ich vielleicht zu einem anderen Zweig gewechselt bin, um mehr Arbeit zu erledigen? Die Arbeit ist begangen, zu Ihrer Information. Nur dieser Upstream wurde aktualisiert, und ich arbeite an einem weiteren Fix in einem neueren Zweig.

    – Menschenerde

    6. April 2014 um 4:36 Uhr


  • Warum müssen Sie den gesamten Code neu erstellen, wenn Sie einen Checkout durchführen? Hast du die kompilierten Binärdateien festgeschrieben oder so?

    – Leigh

    6. April 2014 um 4:46 Uhr

  • Erledigen Sie die Arbeit einfach in einem Klon und verschieben Sie die Ergebnisse zurück. git clone -b oldbranch . ../oldbranch; cd !$; work work commit commit lalala; git push origin oldbranch; cd -

    – jthill

    6. April 2014 um 4:46 Uhr


  • Warum nicht? Sie haben einen Arbeitsbaum, in den Sie nicht eingreifen möchten, verwenden Sie einen anderen. Eine Sache – wissen Sie davon git cherry-pick? Es ist das Gegenteil von rebasegreift es Arbeit von anderen Commits und wendet sie lokal an.

    – jthill

    6. April 2014 um 4:56 Uhr

Ich habe jetzt dasselbe durchgemacht, wie ich gelernt habe git rebase ermöglicht es Ihnen, zwei Zweige auf einmal anzugeben, was im Wesentlichen dazu führt git rebase <remote> <local>z.B.

git rebase origin/master dev

Dies führt zu einem effizienteren Rebase, bei dem Ihre Dateien nicht alle neu geschrieben werden (was der Fall ist, wenn Sie den Zweig zuerst auschecken). Sie müssen immer noch zuerst Merge-Konflikte lösen und erhalten am Ende ein Repository, in dem Ihr local dev Zweig ist ausgecheckt.

  • Beachten Sie, dass dies mit kombiniert werden kann --onto Flagge. Angenommen, Sie haben versehentlich eine Funktionsverzweigung von der erstellt master Filiale in Ihrer master Arbeitsbaum statt aus der release Filiale in Ihrer release Arbeitsbaum. cd ../release-branch-worktree; git rebase --onto origin/release origin/master your_feature_branch Voilà. Die Arbeit wurde nur mit der minimal notwendigen Neukompilierung verschoben.

    – Parker-Beschichtungen

    3. Januar 2020 um 13:09 Uhr


  • Keine Ahnung, ob das wirklich einen Unterschied macht. Die Dokumentation sagt “Wenn angegeben ist, führt git rebase einen automatischen Git-Checkout durch, bevor irgendetwas anderes getan wird.”

    – Andreas Häferburg

    18. Februar 2020 um 14:33 Uhr

  • Es hilft, weil Sie es sonst tun müssten git checkout devdann git rebase (was einen weiteren Checkout macht, diesmal von Upstream). Das checkout dev dient nur dazu, git mitzuteilen, welcher Zweig rebasiert werden soll, und wenn er weit in der Geschichte zurückliegt, kann er ohne triftigen Grund alle möglichen Dateien berühren.

    – Paul du Bois

    12. Januar 2021 um 1:54 Uhr


  • Wenn Sie irgendwo zwischen dem Rebase-Ziel und Ihrem Zweig ein Git-Submodul entfernt haben, wird (kann) das Auschecken einfach fehlschlagen. Der Ansatz in dieser Antwort funktionierte, um den historischen Zweig auf den aktuellen Master umzubasieren, ohne die Checkout-Probleme aufgrund des Entfernens von Submodulen zu beheben.

    – Irfi

    1. September 2021 um 20:32 Uhr

Das klingt nach einem guten Anwendungsfall für git cherry-pick. Anstatt den Branch auszuchecken und ihn auf Ihren aktuellen Branch umzubasieren, können Sie auf dem aktuellen Branch bleiben und Commits aus dem alten Branch herauspicken.

Wenn der Branch, aus dem Sie die Rosinen herauspicken, nur aus einem einzigen Commit besteht, können Sie sogar mit seinem Branch-Namen darauf verweisen, z.

git cherry-pick old-branch

dh. nimm den letzten Commit von alter Zweig und wenden Sie die Änderungen an, um einen neuen Commit (unter Beibehaltung der Commit-Nachricht, des Autors usw.) auf Ihrem aktuellen Zweig zu erstellen.

Benutzer-Avatar
Timmm

Ich habe den Quellcode überprüft und leider sieht es so aus Es überprüft immer den Basis-Commit Leider denke ich, dass die einzige Möglichkeit, dies zu tun, darin besteht, das Repo in ein anderes Verzeichnis zu klonen, es dort neu zu erstellen und dann die Änderungen wieder in das ursprüngliche Repo zu verschieben und es schließlich zu löschen.

Beachten Sie, dass beim Klonen eines lokalen Repos an einen anderen Ort im selben Dateisystem Hardlinks für die darunter liegenden Dateien verwendet werden .git Es ist also nicht wirklich so langsam, wie Sie denken.

Bearbeiten: Eigentlich ist eine bessere Alternative die Verwendung eines Arbeitsbaums, etwa so:

cd <your repo>
git worktree add ../tmp <branch to rebase>
cd ../tmp
git rebase master
cd -
git worktree remove tmp

Beachten Sie, dass Sie jeweils nur einen Zweig in einem Arbeitsbaum auschecken können.

Benutzer-Avatar
Frax

HINWEIS:
Für die einfache Lösung für das genaue Problem in der Frage suchen Sie nach den Antworten unten, sie sind einfacher.

Für das allgemeinere Problem “Ich möchte einige Änderungen vornehmen, ohne mein Arbeitsverzeichnis zu beschädigen”, lesen Sie weiter.

Siehe die Kommentare dazu git worktree add wenn Ihr Repo sehr groß ist.


Klonen Sie das Repo, erstellen Sie eine Rebase in der geklonten Kopie und schieben Sie es zurück.

Wenn Sie sich in Ihrem Repo befinden, sollte es Folgendes sein:

cd ..
git clone <name_of_your_repo_directory> tmp_repo
cd tmp_repo
git checkout origin/oldBranch
git rebase origin/master
git push -f origin HEAD:oldBranch

In tmp_repo origin ist natürlich der Name Ihres lokalen Repos (das Sie geklont haben).

Hinweis: Der Effekt wird so sein wie tun

git checkout oldBranch
git rebase master

in Ihrem ursprünglichen Repo, nicht wie

git checkout oldBranch
git rebase origin/master

Wenn Sie haben

-A---o---o---o---o---D
 \---B---o---C

und D ausgecheckt ist (was meiner Meinung nach Ihre Situation ist), können Sie

git cherry-pick B..C

um das zu erreichen:

-A---o---o---o---o---D---B---o---C

wobei C jetzt Kopf ist, und ohne die Dateien zu berühren, die in A..D. geändert wurden

1294120cookie-checkRebasen Sie einen Zweig, ohne ihn auszuchecken

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy