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 --tags
uitvoer, is er dan ooit een reden om onmiddellijk daarna git fetch
uit te voeren?
Hoe zit het met git pull
en git pull --tags
? Zelfde situatie?
Antwoord 1, autoriteit 100%
Opmerking: beginnend met git 1.9/ 2.0 (Q1 2014), git fetch --tags
haalt 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 refspecrefs/tags/*:refs/tags/*
op de opdrachtregel;
in het bijzonder zorgde het ervoor dat de configuratieremote.<name>.refspec
werd 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 --tags
zorgde ervoor dat de documentatie overeenkwam met het oude gedrag.
Deze commit wijzigt de documentatie zodat deze overeenkomt met het nieuwe gedrag (zieDocumentation/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 --tags
robuuster:
Zie commit 19d122bdoor Paul Tan (pyokagan
), 13 mei 2015.
(Samengevoegd door Junio C Hamano — gitster
—in commit cc77b99, 22 mei 2015)
pull
: verwijder--tags
fout in geval van niet-samenvoegen kandidaten
Sinds 441ed41(“
git pull --tags
“: fout met een beter bericht.,
2007-12-28, Git 1.5.4+), zougit pull --tags
een ander foutbericht afdrukken als
git-fetch
heeft 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 --tags
elke 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 --tags
zou daarnaast nog tags ophalen
naar alle geconfigureerde refspecs.
Als er zich dus een situatie van geen samenvoegkandidaten voordoet, is dit niet omdat--tags
is 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 fetch
sneller.
Zie commit 5827a03(13 okt 2016) door Jeff King (peff
).
(Samengevoegd door Junio C Hamano — gitster
—in commit 9fcd144, 26 okt 2016)
fetch
: gebruik “quick”has_sha1_file
voor 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:
- 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).- 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.- 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.fetch
is 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 — gitster
—in commit 1d8b0df, 07 okt 2019)
fetch
: gebruikoidset
om de gewenste OID’s te behouden voor sneller opzoeken
Tijdens
git fetch
controleert 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_set
aan 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 fetch
haalt 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 --tags
haalt 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 --tags
schakelt de refspec naar +refs/tags/*:refs/tags/*
. Je zougit fetch
kunnen vragen om beide te pakken. Ik ben er vrij zeker van dat ik gewoon een git fetch && git fetch -t
zou 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/config
voor 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 fetch
moeten 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 --tags
doet precies dat, behalve dat het niets anders krijgt dan nieuwe tags.
In die zin is git fetch --tags
op geen enkele manier een superset van git fetch
. Het is in feite precies het tegenovergestelde.
git pull
is natuurlijk niets anders dan een wrapper voor een git fetch <thisrefspec>; git merge
. Het is aan te raden om te wennen aan handmatig git fetch
ing en git merge
ing voordat je de sprong naar git pull
maakt, simpelweg omdat het je helpt begrijpen wat git pull
in de eerste plaats doet.
Dat gezegd hebbende, de relatie is precies hetzelfde als met git fetch
. git pull
is 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.