Ich arbeite an einem Projekt mit zwei Zweigen, A und B. Ich arbeite normalerweise an Zweig A und füge Dinge aus Zweig B zusammen. Für das Zusammenführen würde ich normalerweise Folgendes tun:
git merge origin/branchB
Ich möchte jedoch auch eine lokale Kopie von Zweig B behalten, da ich gelegentlich den Zweig auschecken kann, ohne ihn zuerst mit meinem Zweig A zusammenzuführen. Dazu würde ich Folgendes tun:
git checkout branchB
git pull
git checkout branchA
Gibt es eine Möglichkeit, das oben genannte in einem Befehl auszuführen, ohne den Zweig hin und her wechseln zu müssen? Soll ich das verwenden git update-ref
? Wie?
git
git-merge
git-pull
git-checkout
Charles
quelle
quelle
--no-ff
Option zusammenführen wollte, wodurch ohnehin ein Zusammenführungs-Commit aufgezeichnet wird. Wenn Sie daran interessiert sind, zeigt meine Antwort dort, wie Sie das tun können - nicht ganz so robust wie meine hier veröffentlichte Antwort, aber die Stärken der beiden könnten sicherlich kombiniert werden.Antworten:
Die kurze Antwort
Solange Sie eine Schnellvorlaufzusammenführung durchführen , können Sie diese einfach verwenden
Beispiele:
Während Bernsteins Antwort auch in Fällen mit schnellem Vorlauf funktioniert, ist die Verwendung
git fetch
auf diese Weise etwas sicherer als nur das gewaltsame Verschieben der Verzweigungsreferenz, dagit fetch
ein versehentliches Nicht-Schnellvorlauf automatisch verhindert wird, solange Sie es nicht verwenden+
in der verwenden refspec.Die lange Antwort
Sie können einen Zweig B nicht mit Zweig A zusammenführen, ohne vorher A ausgecheckt zu haben, wenn dies zu einer Zusammenführung ohne schnellen Vorlauf führen würde. Dies liegt daran, dass eine Arbeitskopie erforderlich ist, um potenzielle Konflikte zu lösen.
Bei Schnellvorlaufzusammenführungen ist dies jedoch möglich , da solche Zusammenführungen per Definition niemals zu Konflikten führen können. Um dies zu tun, ohne vorher einen Zweig
git fetch
auszuchecken , können Sie ihn mit einer Referenzspezifikation verwenden.Hier ist ein Beispiel für die Aktualisierung
master
(das Nicht-Schnellvorlauf-Änderungen nicht zulässt), wenn Sie einen anderen Zweigfeature
ausgecheckt haben:Dieser Anwendungsfall ist so häufig, dass Sie wahrscheinlich einen Alias dafür in Ihrer Git-Konfigurationsdatei erstellen möchten, wie diesen:
Dieser Alias bewirkt Folgendes:
git checkout HEAD
: Dadurch wird Ihre Arbeitskopie in einen Zustand mit getrenntem Kopf versetzt. Dies ist nützlich, wenn Sie ein Update durchführen möchten,master
während Sie es auschecken lassen. Ich denke, es war notwendig, damit zu tun, weil sich sonst die Zweigreferenz fürmaster
nicht bewegt, aber ich erinnere mich nicht, ob das wirklich direkt von meinem Kopf ist.git fetch upstream master:master
: Dies spult Ihren Einheimischen schnellmaster
an den gleichen Ort wie vorupstream/master
.git checkout -
checkt Ihren zuvor ausgecheckten Zweig aus (das-
macht das in diesem Fall).Die Syntax
git fetch
für (Nicht-) SchnellvorlaufzusammenführungenWenn Sie möchten, dass der
fetch
Befehl fehlschlägt, wenn die Aktualisierung nicht schnell vorspult, verwenden Sie einfach eine Referenz des FormularsWenn Sie Aktualisierungen ohne schnellen Vorlauf zulassen möchten, fügen Sie
+
an der Vorderseite der Referenz ein hinzu:Beachten Sie, dass Sie Ihr lokales Repo als "Remote" -Parameter übergeben können, indem Sie
.
:Die Dokumentation
Aus der
git fetch
Dokumentation, die diese Syntax erklärt (Hervorhebung von mir):Siehe auch
Git checkout und zusammenführen, ohne den Arbeitsbaum zu berühren
Zusammenführen ohne das Arbeitsverzeichnis zu ändern
quelle
git checkout --quiet HEAD
istgit checkout --quiet --detach
ab Git 1.7.5.git fetch . origin/foo:foo
um mein lokales foo auf meinen lokalen Ursprung / foo zu aktualisierengit checkout -
Trick! Genauso einfach wiecd -
.Nein, da ist kein. Ein Auschecken des Zielzweigs ist erforderlich, damit Sie unter anderem Konflikte lösen können (wenn Git diese nicht automatisch zusammenführen kann).
Wenn es sich bei der Zusammenführung jedoch um eine Zusammenführung handelt, müssen Sie den Zielzweig nicht auschecken, da Sie eigentlich nichts zusammenführen müssen. Sie müssen lediglich den Zweig aktualisieren, um auf den zu verweisen neuer Kopf ref. Sie können dies tun mit
git branch -f
:Wird aktualisiert
branch-b
, um auf den Kopf von zu zeigenbranch-a
.Die
-f
Option steht für--force
, was bedeutet, dass Sie bei der Verwendung vorsichtig sein müssen.quelle
git reset
Funktioniert nur in der aktuell ausgecheckten Filiale.git fetch upstream branch-b:branch-b
( aus dieser Antwort entnommen ).git fetch <remote> B:A
: B und A sind völlig unterschiedliche Zweige. B kann jedoch schnell in A zusammengeführt werden. Sie können Ihr lokales Repository auch als "Remote" übergeben, indem Sie.
als Remote-Alias Folgendes verwenden:git fetch . B:A
.branch -f
könnte gefährlich sein, wie Sie betonen. Also benutze es nicht! Verwenden Siefetch origin branchB:branchB
diese Option, die sicher fehlschlägt, wenn die Zusammenführung nicht schnell vorspult.Wie Amber sagte, sind Schnellvorlaufzusammenführungen der einzige Fall, in dem Sie dies möglicherweise tun könnten. Jede andere Zusammenführung muss möglicherweise die gesamte Drei-Wege-Zusammenführung durchlaufen, Patches anwenden, Konflikte lösen - und das bedeutet, dass Dateien vorhanden sein müssen.
Ich habe zufällig ein Skript, das ich genau dafür verwende: Schnellvorlauf-Zusammenführungen durchführen, ohne den Arbeitsbaum zu berühren (es sei denn, Sie führen eine Zusammenstellung mit HEAD durch). Es ist ein bisschen lang, weil es zumindest ein bisschen robust ist - es prüft, ob die Zusammenführung ein schneller Vorlauf ist, und führt sie dann aus, ohne den Zweig auszuchecken, aber die gleichen Ergebnisse zu erzielen, als ob Sie es getan hätten - Sie sehen das
diff --stat
Zusammenfassung der Änderungen, und der Eintrag im Reflog ist genau wie eine Schnellvorlauf-Zusammenführung, anstelle der "Zurücksetzen", die Sie erhalten, wenn Sie verwendenbranch -f
. Wenn Sie es benennengit-merge-ff
und in Ihrem bin-Verzeichnis ablegen, können Sie es als git-Befehl aufrufen :git merge-ff
.PS Wenn jemand Probleme mit diesem Skript sieht, kommentieren Sie bitte! Es war ein Job zum Schreiben und Vergessen, aber ich würde ihn gerne verbessern.
quelle
# or git branch -f localbranch remote/remotebranch
erinnert mich an die Quelle und die Optionen. Hat Ihren Kommentar zum anderen Link mit +1 bewertet."$branch@{u}"
als Committish zum Zusammenführen verwendet werden, um den Upstream-Zweig zu erhalten (von kernel.org/pub/software/scm/git/docs/gitrevisions.html )Sie können dies nur tun, wenn die Zusammenführung ein schneller Vorlauf ist. Wenn dies nicht der Fall ist, muss git die Dateien auschecken lassen, damit sie zusammengeführt werden können!
Um dies nur für einen schnellen Vorlauf zu tun :
Wo
<commit>
ist das abgerufene Commit, das Sie schnell vorspulen möchten? Dies ist im Grunde wie mitgit branch -f
das Verschieben des Zweigs, außer dass er auch im Reflog aufgezeichnet wird, als ob Sie die Zusammenführung tatsächlich durchgeführt hätten.Bitte, bitte, bitte tun Sie dies nicht für etwas, das kein schneller Vorlauf ist, oder Sie setzen Ihren Zweig einfach auf das andere Commit zurück. (Um zu überprüfen, ob
git merge-base <branch> <commit>
SHA1 des Zweigs angezeigt wird.)quelle
git merge-base --is-ancestor <A> <B>
. "B" ist das, was in "A" zusammengeführt werden muss. Beispiel wäre A = Master und B = Entwickeln, um sicherzustellen, dass Entwickeln schnell in Master vorspulbar ist. Hinweis: Es existiert mit 0, wenn es nicht ff-fähig ist, existiert mit 1, wenn es ist.In Ihrem Fall können Sie verwenden
was macht, was Sie wollen (vorausgesetzt, die Zusammenführung ist ein schneller Vorlauf). Wenn der Zweig nicht aktualisiert werden kann, weil eine Zusammenführung ohne schnellen Vorlauf erforderlich ist, schlägt dies mit einer Nachricht sicher fehl.
Diese Form des Abrufs bietet auch einige weitere nützliche Optionen:
Beachten Sie, dass
<remote>
dies ein lokales Repository und<sourceBranch>
ein Tracking-Zweig sein kann. So können Sie einen lokalen Zweig aktualisieren, auch wenn er nicht ausgecheckt ist, ohne auf das Netzwerk zuzugreifen .Derzeit erfolgt mein Upstream-Serverzugriff über ein langsames VPN. Daher verbinde ich mich regelmäßig,
git fetch
um alle Fernbedienungen zu aktualisieren und dann die Verbindung zu trennen. Wenn sich dann beispielsweise der Remote-Master geändert hat, kann ich dies tunum meinen lokalen Master sicher auf den neuesten Stand zu bringen, auch wenn ich gerade eine andere Filiale ausgecheckt habe. Kein Netzwerkzugriff erforderlich.
quelle
Ein anderer, zugegebenermaßen ziemlich brutaler Weg besteht darin, den Zweig einfach neu zu erstellen:
Dadurch wird der lokale veraltete Zweig weggeworfen und ein gleichnamiger Zweig neu erstellt. Gehen Sie also vorsichtig vor ...
quelle
Sie können das Repo klonen und die Zusammenführung im neuen Repo durchführen. Auf demselben Dateisystem werden die meisten Daten fest verknüpft, anstatt sie zu kopieren. Zum Abschluss ziehen Sie die Ergebnisse in das ursprüngliche Repo.
quelle
Geben Sie git-forward-merge ein :
https://github.com/schuyler1d/git-forward-merge
Funktioniert nur für automatische Zusammenführungen. Wenn Konflikte auftreten, müssen Sie die reguläre Zusammenführung verwenden.
quelle
In vielen Fällen (z. B. beim Zusammenführen) können Sie nur den Remote-Zweig verwenden, ohne den lokalen Tracking-Zweig aktualisieren zu müssen. Das Hinzufügen einer Nachricht zum Reflog klingt nach Overkill und verhindert, dass es schneller geht. Fügen Sie Ihrer Git-Konfiguration Folgendes hinzu, um die Wiederherstellung zu vereinfachen
Geben Sie dann ein
um den aktuellen Verlauf Ihrer Branche anzuzeigen
quelle
[core]
nicht sein[user]
? (und es ist standardmäßig aktiviert für Repos mit einem Arbeitsbereich (dh nicht nackt).Ich habe eine Shell-Funktion für einen ähnlichen Anwendungsfall geschrieben, auf den ich täglich bei Projekten stoße. Dies ist im Grunde eine Abkürzung, um lokale Filialen mit einer gemeinsamen Filiale wie "Entwickeln" vor dem Öffnen einer PR usw. auf dem neuesten Stand zu halten.
glmh
("git pull and merge here") wird automatischcheckout branchB
,pull
spätestenscheckout branchA
, neu undmerge branchB
.Behebt nicht die Notwendigkeit, eine lokale Kopie von branchA aufzubewahren, kann jedoch leicht geändert werden, indem ein Schritt hinzugefügt wird, bevor branchB ausgecheckt wird. Etwas wie...
Bei einfachen Zusammenführungen mit schnellem Vorlauf wird zur Eingabeaufforderung für die Festschreibungsnachricht gesprungen.
Bei Zusammenführungen ohne schnellen Vorlauf versetzt dies Ihre Niederlassung in den Konfliktlösungsstatus (Sie müssen wahrscheinlich eingreifen).
Zum Einrichten zu
.bashrc
oder hinzufügen.zshrc
usw.:Verwendungszweck:
quelle
Ein anderer Weg, dies effektiv zu tun, ist:
Da es sich um Kleinbuchstaben handelt
-d
, wird es nur gelöscht, wenn die Daten noch irgendwo vorhanden sind. Es ähnelt der Antwort von @ kkoehne, außer dass es nicht erzwingt. Aufgrund dessen-t
wird die Fernbedienung erneut eingerichtet.Ich hatte ein etwas anderes Bedürfnis als OP, das darin bestand , nach dem Zusammenführen einer Pull-Anfrage einen neuen Feature-Zweig ab
develop
(odermaster
) zu erstellen . Dies kann in einem Einzeiler ohne Kraftaufwand erreicht werden, aktualisiert jedoch nicht den lokalendevelop
Zweig. Es geht nur darum, eine neue Niederlassung zu überprüfen und sie zu gründenorigin/develop
:quelle
Nur um den Master zu ziehen, ohne den Master zu überprüfen, den ich benutze
git fetch origin master:master
quelle
Es ist absolut möglich, Zusammenführungen durchzuführen, auch nicht schnelles Zusammenführen ohne
git checkout
. Dieworktree
Antwort von @grego ist ein guter Hinweis. Um das zu erweitern:Sie haben jetzt den lokalen Arbeitszweig mit dem lokalen
master
Zweig zusammengeführt, ohne die Kasse zu wechseln.quelle
Wenn Sie den gleichen Baum wie einer der Zweige behalten möchten, die Sie zusammenführen möchten (dh keine echte "Zusammenführung"), können Sie dies folgendermaßen tun.
quelle
Sie können versuchen
git worktree
, zwei Zweige nebeneinander zu öffnen. Das hört sich so an, als ob es das ist, was Sie wollen, aber ganz anders als einige der anderen Antworten, die ich hier gesehen habe.Auf diese Weise können Sie zwei separate Zweige im selben Git-Repo verfolgen, sodass Sie nur einmal abrufen müssen, um Aktualisierungen in beiden Arbeitsbäumen zu erhalten (anstatt zweimal git-Klonen und jeweils git ziehen zu müssen).
Worktree erstellt ein neues Arbeitsverzeichnis für Ihren Code, in dem Sie gleichzeitig einen anderen Zweig auschecken lassen können, anstatt die Zweige auszutauschen.
Wenn Sie es entfernen möchten, können Sie mit aufräumen
quelle