Unterschiede zwischen "Git Pull" -Befehlen beim Ziehen vom Ursprung?

80

Was sind die Unterschiede zwischen diesen Befehlen?:

# 1
git pull
# 2
git pull origin
# 3
git pull origin master
# 4
git pull origin/master
# 5
git pull origin HEAD:master
Ben Gao
quelle
Nun, selbst nach dem Lesen der Manpage ist nicht in allen Fällen klar, was genau passiert. Zum Beispiel: Was bedeutet es git pullohne einen konfigurierten Upstream? (Die Manpage gibt nur die Standardeinstellung als konfigurierter Upstream an.)
Michas
Kurz gesagt: 1. schlägt ohne Konfiguration für den aktuellen Zweig fehl und ist ansonsten wie 2. mit dem Remote-Namen. 2. verwendet die Standardabrufkonfigurationen für die angegebene Fernbedienung (und führt die erste zusammen), während Sie in 3. angeben, was abgerufen und zusammengeführt werden soll. 4. ist ungültig, imho. 5. (wenn es funktioniert), setzt den Remote-HEAD in refs / remotes / origin / master und führt diesen zusammen.
andi5
2
Abstimmung, um diese Frage erneut zu öffnen, da dies leider eines der Suchergebnisse für ist site:stackoverflow.com git Difference "git pull" "git pull origin master".

Antworten:

79

git pullist ein Convenience-Befehl, der gleichzeitig verschiedene Dinge ausführt. Grundsätzlich ist es nur eine Kombination aus git fetch, die eine Verbindung zum Remote-Repository herstellt und neue Commits abruft, und git merge(oder git rebase) die neuen Commits in Ihre lokale Niederlassung integriert. Aufgrund der zwei unterschiedlichen Befehle ist die Bedeutung von git pullnicht immer offensichtlich.

Sie können einen Upstream für einen lokalen Zweig konfigurieren. Nach einem neuen Klon haben Sie einen lokalen Zweig "Master", einen entfernten "Ursprung" und Ihr Hauptzweig hat "Ursprung / Master" als Upstream. Ich nehme dieses Setup unten an. (Sie können Ihre Upstream-Konfiguration mit git branch -vvoder unter .git / config anzeigen.)

Nun zu Ihren Fragen:

  1. git pull= git fetch origin+ git merge origin/master(oder was auch immer dein Upstream ist)
  2. git pull origin= git pull(solange der Ursprung Ihre Upstream-Fernbedienung ist)
  3. git pull origin master= git fetch origin master+git merge FETCH_HEAD
  4. git pull origin/master : ungültig, es sei denn, Sie haben eine Fernbedienung namens "origin / master"
  5. git pull origin HEAD:master: Versucht, Ihren lokalen Master direkt auf den HEAD zurückzusetzen, auf den der Ursprung verweist. (Tu das nicht.)
michas
quelle
2
Warum wird git pull origin HEAD:mastereine schlechte Idee ausgeführt?
Ryan Edwards
2
Die rechte Seite soll ein entfernter Zweig sein. Siehe Warnung in der Manpage. Stellen Sie sicher, dass Sie wissen, was Sie tun, wenn Sie dies verwenden.
Michas
Wenn ich in einem anderen Zweig wäre git pull, würde ich diesen Zweig oder Master ziehen
aWebDeveloper
1
@aWebDeveloper: Der Vollständigkeit halber: Im git pull origin HEAD:masterWesentlichen (wurde buchstäblich bis zum Umschreiben des Skripts in C in Git 2.6) wird der HEAD:masterTeil an übergeben git fetch, sodass das git fetchfür diesen Schritt getan wird. Anschließend wird der Commit-Hash, den der git fetchSchritt erhalten hat, zusammengeführt oder neu erstellt . Refspecs sind source: dest und werden HEADdem anderen Git zur Übersetzung übergeben. Es liegt also am anderen Git - aber normalerweise ist der andere Git HEADein Name für seinen master. Wenn Sie nicht alleine sind master, verwendet das Zusammenführen oder Wiederherstellen Ihr aktualisiertes Abruf master( dest ) (es sei denn, das fetchschlägt fehl).
Torek
1
Eine andere Sache, bei der Sie vorsichtig sein sollten: Niemals tun git pull origin br1 br2. Es sieht so aus und fühlt sich so an git checkout br1; git pull origin; git checkout br2; git pull origin- sollte es aber nicht! Stattdessen führt es git fetch origin && git merge origin/br1 origin/br2tatsächlich Folgendes aus :: Beide Abrufergebnisse werden in Ihrem aktuellen Zweig zusammengeführt . Git nennt dies eine Octopus-Zusammenführung . Das will niemand. Wahrscheinlich git pullsollte den Befehl vollständig ablehnen (jemand, der wirklich nicht will , dass es zunächst laufen holen, dann verschmelzen).
Torek
17

A pullist im Grunde genommen a fetch(das einige Commits und zugehörige Objekte aus einem Remote-Repository in Ihr Repository überträgt) und dann eine Operation, die diese in Ihre Arbeitskopie "anwendet". Die zweite Stufe wird standardmäßig mit a ausgeführt, mergeaber Sie können die pull.rebaseVariable auf setzen trueund sie wird stattdessen neu basiert.

Es gibt zwei Fragen, die mit dem pullBefehl auftauchen . Das erste ist, was genau wird geholt? Und die zweite ist, wie werden diese Änderungen auf meine Arbeitskopie angewendet? Beginnen wir mit dem ersten. Die vollständige Form des Befehls ist

git pull [options] [repository] [<refspec>...]

Das optionsist Flags , dass Regelverhalten (zB --rebase zu machen pullArbeit als fetch+ rebaseauch wenn pull.rebaseist false).

repository ist der Name (oder die URL) der Fernbedienung, von der abgerufen werden soll.

refspecs sind eine prägnante Methode, um anzugeben, welche Referenzen auf der Fernbedienung Sie abrufen möchten und wo Sie sie in Ihre aktuelle Arbeitskopie einfügen möchten.

Nehmen wir zuerst die expliziteste Form an.

 git pull origin branch1:branch2

Dies bedeutet im Grunde, dass Sie die Änderungen in der Referenz branch1auf der aufgerufenen Fernbedienung originabrufen und sie dann in der lokalen Verzweigung zusammenführen (oder neu gründen) branch2. Wenn ich zum Beispiel sage git pull origin master:dev, erhalte ich einen lokalen Zweig namens dev, der auf dasselbe Commit wie verweist master. Einzelheiten zum Angeben von Refspecs finden Sie hier . Sie können a verwenden *, um mehrere Referenzspezifikationen anzugeben. Zieht beispielsweise git pull origin refs/heads/*:refs/heads/*alle (unter heads) gespeicherten Zweige in das lokale Repository und führt sie zu gleichnamigen lokalen Zweigen zusammen.

Entfernen wir nun die Argumente nacheinander, um zu erläutern, wie die Standardeinstellung funktioniert. Erstens können wir das Ziel aus unserer Referenz entfernen und einfach sagen git pull origin branch1. Dadurch wird zuerst fetchder Remote-Zweig branch1in Ihr lokales Repository verschoben. Es wird als temporäre Referenz mit dem Namen verfügbar sein FETCH_HEAD. Danach wird es ausgeführt, git merge FETCH_HEADwodurch dieser Zweig mit Ihrem aktuell aktiven Zweig (dh HEAD) zusammengeführt wird. Dies geschieht häufig, wenn Sie sich in einem lokalen Zweig befinden und Änderungen von einer Fernbedienung in diesen Zweig abrufen möchten.

Lassen Sie uns das jetzt ganz fallen branch1und sagen Sie es einfach git pull origin. Jetzt weiß Git, wo er von ( origin) abrufen soll, weiß aber nicht, was er abrufen soll. Es hat einige Standardeinstellungen dafür. Das meiste Szenario ist, wenn Ihre Konfigurationsdatei eine branch.<name>.mergeOption hat (dies ist ein Eintrag, der mergein einem Abschnitt wie aufgerufen wird [branch "master"]). In diesem Fall werden die dort angegebenen Refspecs für die Operation verwendet.

Wenn wir das originvollständig git pulllöschen und einfach sagen , wird die Konfiguration überprüft, um festzustellen, ob es eine gibt, branch.<name>.remotedie angibt, von welcher Fernbedienung gezogen werden soll. Das zusammen mit dem oben genannten sagt Ihnen, was Sie ziehen müssen.

Ihre Punkte 4 und 5 sind keine normalen Anwendungsfälle. Das erste ist sinnvoll, wenn Sie eine Fernbedienung haben, origin/masterdie unwahrscheinlich ist. origin/masterist normalerweise eine lokale Referenz, die den masterZweig auf der Fernbedienung verfolgt origin. Der zweite Versuch versucht, Änderungen auf HEADder Fernbedienung abzurufen (normalerweise der Standardzweig master) und diese dann in Ihrem lokalen Zweig zusammenzuführen master. Dies ist möglicherweise etwas, das Sie regelmäßig ausführen möchten, aber der Befehl ist ziemlich unkonventionell und nicht etwas, das ich oft gesehen habe.

Ich habe ein paar Details übersprungen, aber diese sollten ausreichen, um Sie bei Ihrer täglichen Arbeit sicher und komfortabel zu halten. Alle wichtigen Details finden Sie auf der Handbuchseite git pull.

Noufal Ibrahim
quelle
"Wenn ich zum Beispiel git pull origin master: dev sage, erhalte ich einen lokalen Zweig namens dev, der auf dasselbe Commit wie master verweist." Sie würden also einen neuen Zweig namens dev herunterladen und er würde auf master verweisen?
user33276346
Nein, Sie würden den Zweig mastervon der Fernbedienung erhalten, aber er würde devlokal aufgerufen .
Noufal Ibrahim
git pull origin refs/heads/*:refs/heads/*hat bei mir nicht funktioniert und ich habe no matches found: refs/heads/*:refs/heads/*. Ich habe es auch versucht git pull origin refs/remotes/origin/*:refs/heads/*, aber das hat auch nicht funktioniert. Ich denke nicht, dass es möglich ist, alle Zweige auf Remote in einem Befehl zu ziehen, und auch nicht das anschließende Zusammenführen / Umbasieren aller dieser Zweige in ihre nachfolgenden lokalen Zweige.
Ben Butterworth