Wie kann man in einen Zweig ziehen, der nicht der aktuelle ist?

126

Wenn Sie git pullauf dem masterZweig laufen , wird er normalerweise von gezogen origin/master. Ich bin in einem anderen Zweig namens newbranch, aber ich muss einen Befehl ausführen, der ein git pullvon origin/masterin aus ausführt, masteraber ich kann nicht ausgeführt werden git checkout, um den ausgewählten Zweig zu ändern, bis der Pull abgeschlossen ist. Gibt es eine Möglichkeit, dies zu tun?

Um Hintergrundinformationen zu geben, speichert das Repository eine Website. Ich habe einige Änderungen vorgenommen newbranchund sie bereitgestellt, indem ich auf die Website umgestellt habe newbranch. Jetzt, da diese Änderungen vorgelagert in der masterFiliale zusammengeführt wurden, versuche ich, die Website auch wieder in die masterFiliale zu verschieben. An diesem Punkt, newbranchund origin/mastersind identisch, aber masterRückstand origin/masterund aktualisiert werden muss. Das Problem ist, wenn ich es auf traditionelle Weise mache:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Ich muss dasselbe wie oben ( git checkout master && git pull) erreichen, ohne jedoch das Arbeitsverzeichnis während des Prozesses auf eine frühere Version zu ändern.

Malvineous
quelle
@phi: Ich glaube nicht, dass es funktionieren würde, weil ich dabei bin newbranchund es nichts zu verstauen gibt!
Malvineous
Ich würde in ein neues Verzeichnis klonen, newbranch in master zusammenführen, master wieder in newbranch zusammenführen und dann von dort ziehen, wo Sie sind. Master und Newbranch werden gleich sein.
aet
@aet Er könnte das jetzt in seinem aktuellen Verzeichnis tun, indem er es git fetch; git merge origin/mastervon innen heraus tut newbranch. Das Klonen einer gesamten zweiten Kopie des Repositorys hat keinen Vorteil.
Meagar
3
eng verwandt: stackoverflow.com/questions/3216360/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Antworten:

5

Sie haben einen Arbeitsbaum, den Sie nicht berühren möchten, verwenden Sie also einen anderen. Klon ist billig, es ist dafür gebaut.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Das Problem mit all den anderen Antworten hier ist, dass sie nicht wirklich ziehen. Wenn Sie die Zusammenführung oder Neubasis benötigen, für die Sie Pull eingerichtet haben, benötigen Sie einen anderen Arbeitsbaum und das oben beschriebene Verfahren. Sonst reicht es einfach git fetch; git checkout -B master origin/master.

jthill
quelle
2
Wenn Sie ausführen, werden git checkout masterSie den alten masterZweig auschecken, da Sie git pullim mainOrdner keine vorgenommen haben , um ihn mit origin / master zu synchronisieren. Das versuche ich zu vermeiden.
Malvineous
Das vom Klon durchgeführte Auschecken ist vom alten Master, aber das Auschecken befindet sich in einem Verzeichnis, das der Webserver nicht betrachtet. Die Master-Kasse am Ende ist der vollständig zusammengeführte Master, der vom Wip zurückgeschoben wurde.
Bis zum
In Zeile 6 schieben Sie die zusammengeführte (aktualisierte) masterzurück zu origin, aber ich glaube nicht, dass Ihre endgültige Kaufabwicklung von dieser Aktualisierung ist master. Es gibt keine git pullMöglichkeit, den masterZweig im mainVerzeichnis zu aktualisieren. Wenn mir also nichts fehlt, unterscheiden sich Ihre Befehle nicht davon, einfach git checkout masteralleine zu laufen und den alten masterBaum abzurufen. Wenn Sie genau hinschauen, führen Sie keine Befehle in dem mainVerzeichnis aus, die Upstream kommunizieren (abgesehen von Zeile 1, die ausgeführt wird, bevor Sie Änderungen am Upstream-Repo vorgenommen haben.)
Malvineous
Nun, Sie können es auf einem Test-Repo versuchen oder die Push-Dokumente überprüfen.
Bis zum
1
@jwg im Vergleich zu was, bitte? Stellen Sie sicher, dass Sie alle angegebenen Anforderungen des OP erfüllen.
Bis zum
163

Unkompliziert: Aktualisierung von einem Remote-Zweig in einen derzeit nicht ausgecheckten Zweig- Master :

git fetch origin master:master

Wobei der Ursprung Ihre Fernbedienung ist und Sie derzeit in einem Zweig ausgecheckt sind, z . B. dev .

Wenn Sie Ihren aktuellen Zweig zusätzlich zum angegebenen Zweig auf einmal aktualisieren möchten:

git pull origin master:master
Martin Peter
quelle
4
Hm, es scheint jedoch nicht immer zu funktionieren; Ich wurde gerade aufgefordert, mich mit meinem WIP-Zweig zusammenzuschließen.
underscore_d
@underscore_d das gleiche für mich.
Greg
1
Hat für mich funktioniert ... wenn es zum Zusammenführen auffordert, stelle ich mir vor, dass es Änderungen in Ihrem Zweig gibt, die Sie aktualisieren und die nicht dem Ursprung verpflichtet sind
überfliegen Sie den
2
Wie soll das funktionieren? Es funktioniert bei mir nicht, es versucht nur, origin / master in meinem aktuell ausgecheckten Zweig zusammenzuführen.
mhogerheijde
3
Dies zieht den Master in den aktuellen Zweig. Dies ist definitiv NICHT das, wonach gefragt wird. Wenn Sie Pull in Fetch ändern, ist dies genau das, wonach Sie gefragt werden.
Jeff Wolski
90

Dies wird hier beantwortet: Zusammenführen, Aktualisieren und Ziehen von Git-Zweigen ohne Verwendung von Kassen

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
Thomas
quelle
2
Dies ist das Beste, da es mit nicht festgeschriebenen lokalen Änderungen funktioniert.
Tomasz Gandor
2
Wenn Sie nur die neuesten Änderungen erfahren möchten, die Sie vornehmen würden git fetch origin master:master. git fetchan sich würde davon ausgehen, dass Sie den aktuellen Zweig und nicht einen anderen Zweig aktualisieren möchten.
John Leidegren
2
Dies ist die einfachste und direkteste Antwort. Dies sollte die akzeptierte Antwort IMO sein.
Keego
@ JohnLeidegren - außer es funktioniert nicht immer wie beabsichtigt. Siehe Kommentare zu stackoverflow.com/a/42902058/274579 Antwort.
Ysap
22

Wie sich herausstellt, ist die Antwort täuschend einfach:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Dadurch können Sie die aktualisieren masterZweig , ohne sie zuvor Schalt bis nach sie aktualisiert wurde.

Malvineous
quelle
11
Dies macht nicht das, was Sie gefragt haben.
Bis zum
Wie der obige Kommentar sagt, ist die Frage, die Sie gestellt haben, nicht wirklich die Frage, die Sie beantwortet haben. Sie sollten Ihre Frage so aktualisieren, dass es weniger darum geht, in einen Zweig zusammengeführt zu werden, ohne ihn auszuchecken, als vielmehr direkt zur neuesten Version eines Zweigs zu wechseln, der auf einer Fernbedienung verfügbar ist, ohne zuerst die alte Version auszuchecken.
Meagar
1
Es ist absolut die Antwort, nach der ich hierher gekommen bin :)
Sophistifunk
1
Nicht das, was OP wollte, aber es hat mir geholfen, um ehrlich zu sein.
Marcel Bro
1
@anoniim, nicht was das OP wollte? Du meinst das OP, das gerade diese Frage beantwortet hat?
smac89
12

Sie machen sich Sorgen um etwas, das nicht behoben werden kann, da Git-Operationen nicht atomar sind. Sie werden immer eine Lücke haben, in der sich Ihr Arbeitsverzeichnis auf halbem Weg zwischen den Zweigen befindet, selbst wenn Sie den Master aktualisieren, ohne vorher zu ihm zu wechseln. Aus diesem Grund ist Git kein Bereitstellungstool .

Da Sie nicht wirklich Code in der Produktionsumgebung zu begehen (hoffe ich), nicht wahr tatsächlich benötigte eine Verzweigung haben ausgecheckt. Sie können einfach eine git fetchOption ausführen, um Ihre Remote-Refs zu aktualisieren und dann git checkout origin/masterdas Arbeitsverzeichnis direkt in das Commit zu verschieben, auf das aktuell verwiesen wird origin/master. Dies versetzt Sie in einen Zustand mit losgelöstem Kopf, aber auch hier spielt es keine Rolle, da Sie keinen Code festschreiben.

Dies ist das kleinste Loch, das Sie bekommen werden, aber wie gesagt, es gibt immer noch ein Loch. checkoutist nicht atomar.

meagar
quelle
Ich verstehe die Einschränkungen bei der Verwendung von Git für die Bereitstellung. Das Problem ist, dass das Loch in diesem Fall Minuten lang sein wird und nicht weniger als eine Sekunde. Gute Idee zum Auschecken origin/master, das könnte genau das Richtige sein.
Malvineous
Was macht das Loch "Minuten" lang? Daten über das Netzwerk ziehen? Machen Sie einfach eine, git fetchbevor Sie etwas anderes tun, und stellen Sie die eigentliche Datenübertragung aus dem Weg.
Meagar
Es dauert Minuten, da eine (jetzt) ​​nicht verfolgte Datei durch ein früheres Commit überschrieben wird. Also muss ich die Datei kopieren, das Git-Zeug machen und es dann zurücklegen. Die 'Minuten lang' kommen von meiner Schreibgeschwindigkeit. (Ja, ich könnte es schreiben, aber es war nur um zu verdeutlichen, dass es schneller ist, wenn Git alles selbst macht.)
Malvineous
3

Sie können update-ref dafür verwenden:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Beachten Sie, dass dadurch alle lokalen Commits in der Hauptniederlassung weggeworfen werden. In Ihrem Fall wird es keine geben, also ist das in Ordnung. Für andere Leute, die dies versuchen, wo es lokale Commits gibt, halte ich es nicht für möglich, da die Zusammenführung nur für den aktuellen Zweig ausgeführt werden kann.

Philip Beber
quelle
Wäre das gleichbedeutend mit git branch --force master origin/master? Dies zwingt den lokalen Kopf master, auf den Kopf von originsmaster
Keego
2

Malvineous 'Lösung funktioniert für mich

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Geben Sie einfach den Fehler ein


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Also laufe ich mit der Option -D

Vielen Dank

Sebastian Oscar Lopez
quelle
0

git fetch origin master:master

  • "Pulls" (tatsächlich holt) master.
  • Wenn Sie Änderungen an Ihrem haben master, die noch nicht gepusht wurden, origin/masterwerden diese in Ihren Master übernommen.
  • Wenn es Zusammenführungskonflikte gibt, müssen Sie diese zuerst lösen.
Luzian
quelle