Omvatten “git fetch –tags” ook “git fetch”?

Een leuke en simpele vraag – is de functie van “git fetch” een strikte subset van git fetch --tags?

D.w.z. als ik git fetch --tagsuitvoer, is er dan ooit een reden om onmiddellijk daarna git fetchuit te voeren?

Hoe zit het met git pullen git pull --tags? Zelfde situatie?


Antwoord 1, autoriteit 100%

Opmerking: beginnend met git 1.9/ 2.0 (Q1 2014), git fetch --tagshaalt tags op naastwat wordt opgehaald door dezelfde opdrachtregel zonder de optie.

Alleen tags ophalen:

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

In details:

Zie commit c5a84e9door Michael Haggerty (mhagger):

Voorheen werd de optie “--tags” van fetch beschouwd als gelijkwaardig aan het specificeren van de refspec

refs/tags/*:refs/tags/*

op de opdrachtregel;
in het bijzonder zorgde het ervoor dat de configuratie remote.<name>.refspecwerd genegeerd.

Maar het is niet erg handig om tags op te halen zonder ook andere referenties op te halen, terwijl het isbest handig is om tags op te halen naastandere referenties.< br>
Verander dus de semantiek van deze optie om de laatste te doen.

Als een gebruiker alleentags wil ophalen, is het nog steeds mogelijk om een ​​expliciete refspec op te geven:

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

Houd er rekening mee dat de documentatie voorafgaand aan 1.8.0.3 dubbelzinnig was over dit aspect van het gedrag van “fetch --tags“.
Commit f0cb2f1(2012-12-14) fetch --tagszorgde ervoor dat de documentatie overeenkwam met het oude gedrag.
Deze commit wijzigt de documentatie zodat deze overeenkomt met het nieuwe gedrag (zie Documentation/fetch-options.txt).

Verzoek dat alle tags van de afstandsbediening worden opgehaald naast al het andere dat wordt opgehaald.


Sinds Git 2.5 (Q2 2015) is git pull --tagsrobuuster:

Zie commit 19d122bdoor Paul Tan (pyokagan), 13 mei 2015.
(Samengevoegd door Junio ​​C Hamano — gitsterin commit cc77b99, 22 mei 2015)

pull: verwijder --tagsfout in geval van niet-samenvoegen kandidaten

Sinds 441ed41(“git pull --tags“: fout met een beter bericht.,
2007-12-28, Git 1.5.4+), zou git pull --tagseen ander foutbericht afdrukken als
git-fetchheeft geen merge kandidaten geretourneerd:

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

Dit is omdat op dat moment git-fetch --tagselke zou overschrijven
geconfigureerde refspecs, en dus zouden er geen merge-kandidaten zijn. De foutmelding is dus geïntroduceerd om verwarring te voorkomen.

Echter, sinds c5a84e9(fetch --tags: tags ophalen naast
andere dingen, 30-10-2013, Git 1.9.0+), git fetch --tagszou daarnaast nog tags ophalen
naar alle geconfigureerde refspecs.
Als er zich dus een situatie van geen samenvoegkandidaten voordoet, is dit niet omdat --tagsis ingesteld. Als zodanig is deze speciale foutmelding nu niet relevant.

Verwijder deze foutmelding om verwarring te voorkomen.


Met Git 2.11+ (Q4 2016) is git fetchsneller.

Zie commit 5827a03(13 okt 2016) door Jeff King (peff).
(Samengevoegd door Junio ​​C Hamano — gitsterin commit 9fcd144, 26 okt 2016)

fetch: gebruik “quick” has_sha1_filevoor het volgen van tags

Bij het ophalen van een afstandsbediening die veel tags heeft die niet relevant zijn voor branches die we volgen, verspilden we veel te veel cycli bij het controleren of het object waarnaar wordt verwezen door een tag (die we niet gaan ophalen!) bestaat te zorgvuldig in onze repository.

Deze patch leert fetch om HAS_SHA1_QUICK te gebruiken om op te offeren
nauwkeurigheid voor snelheid, in gevallen waar we misschien pittig zijn met a
gelijktijdig opnieuw inpakken.

Hier zijn resultaten van het meegeleverde perf-script, dat een situatie creëert die vergelijkbaar is met de hierboven beschreven situatie:

Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%

Dat geldt alleen voor een situatie waarin:

  1. Je hebt veel pakketten aan de clientzijde om reprepare_packed_git()duur te maken (het duurste deel is het vinden van duplicaten in een ongesorteerde lijst, die momenteel kwadratisch is).
  2. Je hebt een groot aantal tagrefs aan de serverkant nodig die in aanmerking komen voor automatisch volgen (d.w.z. die de client niet heeft).
    Elk triggert een herlezing van de pakketdirectory.
  3. Onder normale omstandigheden zou de client die tags automatisch volgen en na één grote ophaalactie zou (2) niet langer waar zijn.
    Maar als die tags verwijzen naar de geschiedenis die los staat van wat de klant anders ophaalt, dan zal deze nooit automatisch volgen en hebben die kandidaten invloed op elke ophaalactie.

Git 2.21 (feb. 2019) lijkt een regressie te hebben geïntroduceerd wanneer de config remote.origin.fetchis nietde standaardinstelling('+refs/heads/*:refs/remotes/origin/*')

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

Git 2.24 (Q4 2019) voegt nog een optimalisatie toe.

Zie commit b7e2d8b(15 sep 2019) door Masaya Suzuki (draftcode).
(Samengevoegd door Junio ​​C Hamano — gitsterin commit 1d8b0df, 07 okt 2019)

fetch: gebruik oidsetom de gewenste OID’s te behouden voor sneller opzoeken

Tijdens git fetchcontroleert de client of de OID’s van de geadverteerde tags al in de gewenste OID-set van het ophaalverzoek staan.
Deze controle wordt gedaan in een lineaire scan.
Voor een repository met veel refs duurt het herhalen van deze scan meer dan 15 minuten.

Om dit te versnellen, maakt u een oid_setaan voor de OID’s van andere refs.


Antwoord 2, autoriteit 68%

Opmerking: dit antwoord is alleen geldig voor git v1.8 en ouder.

Het meeste hiervan is al gezegd in de andere antwoorden en opmerkingen, maar hier is een beknopte uitleg:

  • git fetchhaalt alle branch heads op (of alle gespecificeerd door de remote.fetch config optie), alle commits die daarvoor nodig zijn, en alle tags die bereikbaar zijn vanuit deze branches. In de meeste gevallen zijn alle tags op deze manier bereikbaar.
  • git fetch --tagshaalt alle tags op, alle commits die daarvoor nodig zijn. Het zal nietvertakkingskoppen bijwerken, zelfs niet als ze bereikbaar zijn via de tags die zijn opgehaald.

Samenvatting: als je echt helemaal up-to-date wilt zijn en alleen fetch wilt gebruiken, moet je beide doen.

Het is ook niet “twee keer zo traag”, tenzij je bedoelt in termen van typen op de opdrachtregel, in welk geval aliassen je probleem oplossen. Er is in wezen geen overhead bij het maken van de twee verzoeken, omdat ze om verschillende informatie vragen.


Antwoord 3, autoriteit 26%

Ik ga dit zelf beantwoorden.

Ik heb vastgesteld dat er een verschil is. “git fetch –tags” kan alle tags binnenbrengen, maar het brengt geen nieuwe commits binnen!

Blijkbaar moet je dit doen om helemaal “up-to-date” te zijn, d.w.z. een “git pull” repliceren zonder de merge:

$ git fetch --tags
$ git fetch

Dit is jammer, want het is twee keer zo traag. Had “git fetch” maar een optie om te doen wat het normaal doet enalle tags binnen te halen.


Antwoord 4, autoriteit 16%

Het algemene probleem hier is dat git fetch+refs/heads/*:refs/remotes/$remote/*zal ophalen. Als een van deze commits tags heeft, worden die tags ook opgehaald. Als er echter tags zijn die door geen enkele tak op de afstandsbediening kunnen worden bereikt, worden ze niet opgehaald.

De optie --tagsschakelt de refspec naar +refs/tags/*:refs/tags/*. Je zougit fetchkunnen vragen om beide te pakken. Ik ben er vrij zeker van dat ik gewoon een git fetch && git fetch -tzou je het volgende commando gebruiken:

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

En als je dit de standaard voor deze repo wilt maken, kun je een tweede refspec toevoegen aan de standaard fetch:

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

Hiermee wordt een tweede regel fetch =toegevoegd in de .git/configvoor deze afstandsbediening.


Ik heb een tijdje gezocht naar de manier om dit voor een project aan te pakken. Dit is wat ik bedacht.

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

In mijn geval wilde ik deze functies

  • Pak alle heads en tags van de afstandsbediening dus gebruik refspec refs/*:refs/*
  • Lokale branches en tags overschrijven met non-fast-forward +voor de refspec
  • Overschrijf de momenteel uitgecheckte tak indien nodig -u
  • Verwijder vertakkingen en tags die niet aanwezig zijn in externe -p
  • En forceer om zeker te zijn -f

Antwoord 5, autoriteit 6%

In de meeste situaties zou git fetchmoeten doen wat je wilt, namelijk ‘iets nieuws uit de externe repository halen en het in je lokale kopie plaatsen zonder samen te voegen met je lokale branches’. git fetch --tagsdoet precies dat, behalve dat het niets anders krijgt dan nieuwe tags.

In die zin is git fetch --tagsop geen enkele manier een superset van git fetch. Het is in feite precies het tegenovergestelde.

git pullis natuurlijk niets anders dan een wrapper voor een git fetch <thisrefspec>; git merge. Het is aan te raden om te wennen aan handmatig git fetching en git mergeing voordat je de sprong naar git pullmaakt, simpelweg omdat het je helpt begrijpen wat git pullin de eerste plaats doet.

Dat gezegd hebbende, de relatie is precies hetzelfde als met git fetch. git pullis de superset van git pull --tags.


Antwoord 6, Autoriteit 2%

git fetch upstream --tags

Werkt prima, het krijgt alleen nieuwe tags en krijgt geen andere codebasis.

Other episodes