webentwicklung-frage-antwort-db.com.de

Enthält "git fetch --tags" "git fetch"?

Eine nette und einfache Frage - ist die Funktion von "git fetch" eine strikte Teilmenge von git fetch --tags?

Das heißt Wenn ich git fetch --tags ausführe, gibt es jemals einen Grund, unmittelbar danach git fetch auszuführen?

Was ist mit git pull Und git pull --tags? Gleiche Situation?

248
davidA

Hinweis: beginnend mit git 1.9/2.0 (Q1 2014) ruft git fetch --tags Die Tags zusätzlich zu ab, die von derselben Befehlszeile ohne das abgerufen werden Möglichkeit.

Siehe commit c5a84e9 von Michael Haggerty (mhagger) :

Zuvor galt die Option "--tags" Von fetch als gleichwertig mit der Angabe der Referenzspezifikation

refs/tags/*:refs/tags/*

in der Befehlszeile; Insbesondere wurde die remote.<name>.refspec - Konfiguration ignoriert.

Es ist jedoch nicht sehr nützlich, Tags abzurufen, ohne auch andere Referenzen abzurufen, wohingegen es ist sehr nützlich ist, in der Lage zu sein, Tags zusätzlich zu anderen Referenzen abzurufen.
Ändern Sie daher die Semantik dieser Option, um Letzteres zu tun.

Wenn ein Benutzer only Tags abrufen möchte, ist es dennoch möglich, einen expliziten Verweis anzugeben:

git fetch <remote> 'refs/tags/*:refs/tags/*'

Bitte beachten Sie, dass die Dokumentation vor 1.8.0.3 in Bezug auf diesen Aspekt des Verhaltens "fetch --tags" Mehrdeutig war.
Commit f0cb2f1 (2012-12-14) fetch --tags Hat die Dokumentation dem alten Verhalten angepasst.
Mit diesem Commit wird die Dokumentation an das neue Verhalten angepasst (siehe Documentation/fetch-options.txt ).

Fordern Sie an, dass alle Tags von der Fernbedienung abgerufen werden zusätzlich zu dem, was gerade abgerufen wird.


Seit Git 2.5 (2. Quartal 2015) ist git pull --tags Robuster:

Siehe commit 19d122b von Paul Tan (pyokagan) , 13. Mai 2015.
(Zusammengeführt von Junio ​​C Hamano - gitster - in Festschreiben von cc77b99 , 22. Mai 2015)

pull: Entfernen Sie den Fehler --tags, wenn keine Kandidaten zusammengeführt werden

Da 441ed41 ("git pull --tags": Fehler mit einer besseren Meldung., 28.12.2007, Git 1.5.4+), würde git pull --tags Eine andere ausgeben Fehlermeldung, wenn git-fetch keine Zusammenführungskandidaten zurückgegeben hat:

It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags

Dies liegt daran, dass zu diesem Zeitpunkt git-fetch --tags Alle konfigurierten Referenzspezifikationen überschreibt und es daher keine Zusammenführungskandidaten gibt. Die Fehlermeldung wurde daher eingeführt, um Verwechslungen zu vermeiden.

Da jedoch c5a84e9 (fetch --tags: Fetch tags zusätzlich zu andere Sachen, 2013-10-30, Git 1.9.0+), git fetch --tags Würde zusätzlich zu den konfigurierten Refspecs Tags abrufen.
Daher liegt es nicht daran, dass --tags Festgelegt wurde, wenn keine Situation für Zusammenführungskandidaten auftritt. Daher ist diese spezielle Fehlermeldung jetzt irrelevant.

Entfernen Sie diese Fehlermeldung, um Verwirrung zu vermeiden.


Mit Git 2.11+ (4. Quartal 2016) ist git fetch Schneller.

Siehe commit 5827a (13. Oktober 2016) von Jeff King (peff) .
(Zusammengeführt von Junio ​​C Hamano - gitster - in Commit 9fcd144 , 26. Oktober 2016)

fetch: Verwenden Sie "quick" has_sha1_file für die Tag-Verfolgung

Beim Abrufen von einem Remote mit vielen Tags, die für die von uns verfolgten Zweige nicht relevant sind, haben wir zu viele Zyklen verschwendet, um zu überprüfen, ob das Objekt, auf das ein Tag zeigt (das wir nicht abrufen wollen!), In unserem Repository vorhanden ist zu vorsichtig.

Dieser Patch lehrt fetch, HAS_SHA1_QUICK zu verwenden, um die Genauigkeit für die Geschwindigkeit zu opfern.

Hier sind die Ergebnisse des enthaltenen Perf-Skripts, das eine ähnliche Situation wie oben beschrieben erstellt:

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:

  1. Sie müssen auf der Client-Seite eine Menge Packs erstellen, um reprepare_packed_git() teuer zu machen (der teuerste Teil besteht darin, Duplikate in einer unsortierten Liste zu finden, die derzeit quadratisch ist).
  2. 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). Jedes löst ein erneutes Lesen des Pack-Verzeichnisses aus.
  3. Unter normalen Umständen würde der Client diesen Tags automatisch folgen, und nach einem großen Abruf wäre (2) nicht mehr wahr.
    Aber wenn diese Tags auf einen Verlauf verweisen, der nicht mit dem übereinstimmt, was der Client sonst abruft, folgt er niemals automatisch, und diese Kandidaten wirken sich bei jedem Abruf darauf aus.

Git 2.21 (Feb. 2019) scheint eine Regression eingeführt zu haben, wenn config remote.Origin.fetch not die Standardeinstellung ist ('+refs/heads/*:refs/remotes/Origin/*' )

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed
160
VonC

Hinweis: Diese Antwort ist nur für Git v1.8 und älter gültig.

Das meiste davon wurde in den anderen Antworten und Kommentaren gesagt, aber hier ist eine kurze Erklärung:

  • git fetch ruft alle Zweigköpfe (oder alle mit der Option remote.fetch config angegebenen), alle für sie erforderlichen Festschreibungen und alle Tags ab, die von diesen Zweigen aus erreichbar sind. In den meisten Fällen sind alle Tags auf diese Weise erreichbar.
  • git fetch --tags holt alle Tags, alle dafür notwendigen Commits. Es werden keine Zweigköpfe aktualisiert , auch wenn diese über die abgerufenen Tags erreichbar sind.

Zusammenfassung: Wenn Sie wirklich auf dem neuesten Stand sein möchten und nur fetch verwenden möchten, müssen Sie beides tun.

Es ist auch nicht "doppelt so langsam", es sei denn, Sie tippen in der Befehlszeile. In diesem Fall lösen Aliase Ihr Problem. Es ist im Wesentlichen kein Aufwand, die beiden Anfragen zu stellen, da sie nach unterschiedlichen Informationen fragen.

130
Cascabel

Ich werde das selbst beantworten.

Ich habe festgestellt, dass es einen Unterschied gibt. "git fetch --tags" bringt zwar alle Tags ein, aber keine neuen Commits!

Es hat sich herausgestellt, dass man dies tun muss, um vollständig "auf dem neuesten Stand" zu sein, d. H. Einen "Git-Pull" ohne die Zusammenführung nachzubilden:

$ git fetch --tags
$ git fetch

Das ist schade, denn es ist doppelt so langsam. Wenn nur "git fetch" die Option hätte, das zu tun, was es normalerweise tut nd alle Tags einspielen.

48
davidA

Das allgemeine Problem hierbei ist, dass git fetch+refs/heads/*:refs/remotes/$remote/* Abruft. Wenn eines dieser Commits Tags enthält, werden diese Tags ebenfalls abgerufen. Wenn es jedoch Tags gibt, die von keinem Zweig auf der Fernbedienung erreichbar sind, werden sie nicht abgerufen.

Die Option --tags Ändert die Referenzspezifikation auf +refs/tags/*:refs/tags/*. Sie könnten bitten git fetch, Sich beide zu schnappen. Ich bin mir ziemlich sicher, dass Sie einfach einen git fetch && git fetch -t - Befehl verwenden würden:

git fetch Origin "+refs/heads/*:refs/remotes/Origin/*" "+refs/tags/*:refs/tags/*"

Und wenn Sie dies als Standard für dieses Repo festlegen möchten, können Sie dem Standardabruf eine zweite Referenzspezifikation hinzufügen:

git config --local --add remote.Origin.fetch "+refs/tags/*:refs/tags/*"

Dadurch wird eine zweite fetch = - Zeile in .git/config Für diese Fernbedienung eingefügt.


Ich habe eine Weile nach einer Möglichkeit gesucht, dies für ein Projekt zu erledigen. Das habe ich mir ausgedacht.

git fetch -fup Origin "+refs/*:refs/*"

In meinem Fall wollte ich diese Funktionen

  • Nimm alle Köpfe und Tags von der Fernbedienung, also benutze refspec refs/*:refs/*
  • Überschreiben Sie lokale Verzweigungen und Tags mit einem nicht schnellen Vorlauf + Vor der Refspezifikation
  • Derzeit ausgecheckten Zweig bei Bedarf überschreiben -u
  • Löschen von Zweigen und Tags, die nicht in remote vorhanden sind -p
  • Und um sicher zu gehen, -f
31
gnarf

In den meisten Situationen sollte git fetch Das tun, was Sie wollen, dh "etwas Neues aus dem Remote-Repository holen und es in Ihre lokale Kopie kopieren, ohne es in Ihre lokalen Zweige zu integrieren". git fetch --tags Macht genau das, außer dass es nur neue Tags bekommt.

In diesem Sinne ist git fetch --tags In keiner Weise eine Obermenge von git fetch. Es ist in der Tat genau das Gegenteil.

git pull Ist natürlich nichts anderes als ein Wrapper für einen git fetch <thisrefspec>; git merge. Es wird empfohlen, dass Sie sich daran gewöhnen, manuell git fetch Und git merge Zu arbeiten, bevor Sie zu git pull Springen, nur weil Sie so besser verstehen, was git pull Ist in erster Linie zu tun.

Abgesehen davon ist die Beziehung genau die gleiche wie bei git fetch. git pull Ist die Obermenge von git pull --tags.

10
Tim Visher
git fetch upstream --tags

funktioniert einwandfrei, es werden nur neue Tags und keine andere Codebasis abgerufen.

1
PAnand