Enthält „git fetch --tags“ „git fetch“?
Frage
Eine schöne und einfache Frage: Ist die Funktion von „git fetch“ eine strikte Teilmenge von git fetch --tags
?
D.h.wenn ich renne git fetch --tags
, Gibt es jemals einen Grund, sofort zu rennen? git fetch
gleich danach?
Wie wäre es mit git pull
Und git pull --tags
?Gleiche Situation?
Lösung
Notiz:beginnen mit Git 1.9/2.0 (Q1 2014), git fetch --tags
ruft Tags ab zusätzlich zu was von derselben Befehlszeile ohne die Option abgerufen wird.
Sehen c5a84e9 begehen von Michael Haggerty (mhagger):
Zuvor war fetch's „
--tags
Die Option „wurde als gleichbedeutend mit der Angabe der Referenzspezifikation angesehenrefs/tags/*:refs/tags/*
auf der Befehlszeile;Insbesondere verursachte es die
remote.<name>.refspec
Konfiguration, die ignoriert werden soll.Es ist jedoch nicht sehr nützlich, Tags abzurufen, ohne auch andere Referenzen abzurufen Ist Sehr nützlich, um Tags abrufen zu können zusätzlich zu Weitere Referenzen.
Ändern Sie also die Semantik dieser Option, um Letzteres zu erreichen.Wenn ein Benutzer abrufen möchte nur Tags, dann ist es immer noch möglich, eine explizite Refspec anzugeben:
git fetch <remote> 'refs/tags/*:refs/tags/*'
Bitte beachten Sie, dass die Dokumentation vor 1.8.0.3 in Bezug auf diesen Aspekt von „
fetch --tags
" Verhalten.
Commit f0cb2f1 (2012-12-14)fetch --tags
Die Dokumentation wurde an das alte Verhalten angepasst.
Dieser Commit ändert die Dokumentation, um sie an das neue Verhalten anzupassen (sieheDocumentation/fetch-options.txt
).Fordern Sie an, dass alle Tags von der Fernbedienung abgerufen werden zusätzlich zu dem, was sonst noch abgerufen wird.
Seit Git 2.5 (Q2 2015) git pull --tags
ist robuster:
Sehen Commit 19d122b von Paul Tan (pyokagan
), 13. Mai 2015.
(Zusammengeführt von Junio C Hamano -- gitster
-- In Commit cc77b99, 22. Mai 2015)
pull
:entfernen--tags
Fehler im Fall „Keine Zusammenführungskandidaten“.Seit 441ed41 ("
git pull --tags
":Fehler mit einer besseren Nachricht., 2007-12-28, Git 1.5.4+),git pull --tags
würde eine andere Fehlermeldung ausgeben, wenngit-fetch
hat keine Zusammenführungskandidaten zurückgegeben:It doesn't make sense to pull all tags; you probably meant: git fetch --tags
Dies liegt daran, dass damals
git-fetch --tags
Würde alle konfigurierten REFSPECS überschreiben, und daher würde es keine Zusammenführungskandidaten geben.Die Fehlermeldung wurde daher eingeführt, um Verwirrung zu vermeiden.Allerdings seitdem c5a84e9 (
fetch --tags
:Tags abrufen zusätzlich zuandere Sachen, 30.10.2013, Git 1.9.0+),git fetch --tags
Würde zusätzlich zu allen konfigurierten REFSpecs Tags abrufen.
Wenn also eine Situation ohne Zusammenführungskandidaten auftritt, liegt dies nicht daran--tags
war eingestellt.Daher ist diese spezielle Fehlermeldung jetzt irrelevant.Um Verwirrung zu vermeiden, entfernen Sie diese Fehlermeldung.
Mit Git 2.11+ (4. Quartal 2016) git fetch
ist schneller.
Sehen Commit 5827a03 (13. Okt. 2016) von Jeff King (peff
).
(Zusammengeführt von Junio C Hamano -- gitster
-- In Commit 9fcd144, 26. Okt. 2016)
fetch
:Verwenden Sie „schnell“has_sha1_file
für Tag-FolgenBeim Abrufen von einem entfernten Objekt mit vielen Tags, die für die von uns verfolgten Zweige irrelevant sind, haben wir früher viel zu viele Zyklen verschwendet, um zu prüfen, ob das Objekt, auf das ein Tag zeigt (das wir nicht abrufen werden!), in unserem Repository vorhanden ist zu vorsichtig.
Dieser Patch lehrt Fetch, HAS_SHA1_QUICK zu verwenden, um die Genauigkeit für Geschwindigkeit zu opfern, in Fällen, in denen wir mit einer gleichzeitigen Wiederverpackung möglicherweise rassig sind.
Hier sind die Ergebnisse des enthaltenen Perf-Skripts, das eine ähnliche Situation wie oben beschrieben herstellt:
Test HEAD^ HEAD
----------------------------------------------------------
5550.4: fetch 11.21(10.42+0.78) 0.08(0.04+0.02) -99.3%
Dies gilt nur für eine Situation, in der:
- Sie müssen auf der Clientseite viele Pakete erstellen
reprepare_packed_git()
teuer (der teuerste Teil besteht darin, Duplikate in einer unsortierten Liste zu finden, die derzeit quadratisch ist).- Sie benötigen eine große Anzahl von Tag-Referenzen auf der Serverseite, die Kandidaten für die automatische Verfolgung sind (d. h. die der Client nicht hat).Jeder einzelne löst ein erneutes Lesen des Paketverzeichnisses aus.
- Unter normalen Umständen würde der Client diesen Tags automatisch folgen und nach einem großen Abruf wäre (2) nicht mehr wahr.
Wenn diese Tags jedoch auf den Verlauf verweisen, der nichts mit dem zu tun hat, was der Client sonst abruft, wird er nie automatisch folgen und diese Kandidaten wirken sich bei jedem Abruf darauf aus.
Git 2.21 (Feb.2019) scheint eine Regression eingeleitet zu haben, als die config remote.origin.fetch
Ist nicht die Standardeinstellung ('+refs/heads/*:refs/remotes/origin/*'
)
fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed
Andere Tipps
Hinweis: Diese Antwort gilt nur für Git v1.8 und älter.
Das meiste davon wurde in den anderen Antworten und Kommentaren gesagt, aber hier ist eine kurze Erklärung:
git fetch
Abrufen Sie alle Zweigköpfe (oder alle von der Option Remote.fetch -Konfiguration angegeben), alle für sie erforderlichen Commits und alle Tags, die aus diesen Zweigen erreichbar sind. In den meisten Fällen sind alle Tags auf diese Weise erreichbar.git fetch --tags
Abrets alle Tags, alle für sie notwendigen Commits. Es wird nicht Aktualisieren Sie Branch -Köpfe, auch wenn sie von den abgerufenen Tags erreichbar sind.
Zusammenfassung: Wenn Sie wirklich völlig auf dem neuesten Stand sein möchten, müssen Sie beides tun.
Es ist auch nicht "doppelt so langsam", es sei denn, Sie meinen in Bezug auf die Eingabe der Befehlszeile. In diesem Fall lösen Aliase Ihr Problem. Es gibt im Wesentlichen keinen Overhead bei den beiden Anfragen, da sie nach unterschiedlichen Informationen fragen.
Ich werde das selbst beantworten.
Ich habe festgestellt, dass es einen Unterschied gibt. "Git Fetch -Tags" könnte alle Tags einbringen, aber es bringt keine neuen Commits ein!
Es stellt sich heraus, dass man dies tun muss, um völlig "aktuell" zu sein, dh ein "Git Pull" ohne die Zusammenführung:
$ git fetch --tags
$ git fetch
Das ist eine Schande, denn es ist doppelt so langsam. Wenn nur "Git Fetch" die Option hätte, das zu tun, was es normalerweise tut und Bringen Sie alle Tags ein.
Das allgemeine Problem hier ist das git fetch
wird holen +refs/heads/*:refs/remotes/$remote/*
. Wenn einer dieser Commits Tags hat, werden diese Tags ebenfalls abgerufen. Wenn jedoch Tags von einem Zweig in der Fernbedienung erreichbar sind, werden sie nicht abgerufen.
Das --tags
Option schaltet den RefSpec auf +refs/tags/*:refs/tags/*
. Du könnte Fragen git fetch
beides zu greifen. Ich bin ziemlich sicher, dass ich nur eine mache git fetch && git fetch -t
Sie würden den folgenden Befehl verwenden:
git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"
Und wenn Sie dies zur Standardeinstellung für dieses Repo machen möchten, können Sie dem Standardfetch einen zweiten Refc hinzufügen:
git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"
Dies wird eine Sekunde hinzufügen fetch =
Linie in der .git/config
für diese Fernbedienung.
Ich habe eine Weile nach dem Weg gesucht, dies für ein Projekt zu behandeln. Das habe ich mir ausgedacht.
git fetch -fup origin "+refs/*:refs/*"
In meinem Fall wollte ich diese Funktionen
- Nehmen Sie alle Köpfe und Tags aus der Fernbedienung, also verwenden Sie RefSpec
refs/*:refs/*
- Überschreibe lokale Zweige und Tags mit nicht schneller Forward
+
vor dem RefSpec - Überschreiben Sie derzeit bei Bedarf die Filiale
-u
- Löschen Sie Zweige und Tags, die nicht in der Fernbedienung vorhanden sind
-p
- Und zwingen, sicher zu sein
-f
In den meisten Situationen, git fetch
Sollte das tun, was Sie wollen, das heißt, "holen Sie sich etwas Neues aus dem Remote -Repository und legen Sie es in Ihre lokale Kopie, ohne sich an Ihre lokalen Filialen zu verschmelzen". git fetch --tags
Tut genau das, außer dass es nichts anderes als neue Tags bekommt.
In diesem Sinne, git fetch --tags
ist in keiner Weise ein Superset von git fetch
. Es ist in der Tat genau das Gegenteil.
git pull
, ist natürlich nichts als eine Wrapper für a git fetch <thisrefspec>; git merge
. Es wird empfohlen, sich an das Handbuch zu gewöhnen git fetch
und git merge
Bevor Sie den Sprung machen zu git pull
Einfach weil es Ihnen hilft zu verstehen was git pull
tut es überhaupt erst.
Davon abgesehen ist die Beziehung genau die gleiche wie bei git fetch
. git pull
ist das Superet von git pull --tags
.
git fetch upstream --tags
Funktioniert gut, es wird nur neue Tags erhalten und keine andere Codebasis erhalten.