Scarica un tag specifico con Git


1941

Sto cercando di capire come posso scaricare un particolare tag di un repository Git: è una versione dietro la versione corrente.

Ho visto che c'era un tag per la versione precedente sulla pagina web di git, con il nome dell'oggetto di un numero esadecimale lungo.

Ma il nome della versione è " Tagged release 1.1.5" secondo il sito.

Ho provato un comando come questo (con i nomi cambiati):

git clone http://git.abc.net/git/abc.git my_abc

E ho ottenuto qualcosa: una directory, un mucchio di sottodirectory, ecc.

Se è l'intero repository, come posso ottenere alla versione che sto cercando? In caso contrario, come posso scaricare quella particolare versione?


11
Sviluppo su un repository completamente diverso rispetto alla produzione, quindi la mia produzione non conosceva alcun tag quando ho provato a usare git checkout. La soluzione era usare "git pull --tags" e poi usare git checkout.
Enterprise Architect il

11
"git fetch --tags" funziona anche
John Erck,

16
Per evitare la clonazione dell'intero repository e il passaggio a un tag, è possibile eseguire direttamente a clone -b "Tagged release 1.1.5" http://git.abc.net/git/abs.git my_abc. Funzionerà solo se non hai un ramo con lo stesso nome ovviamente (a seconda della tua metodologia, questo potrebbe non succedere mai).
RedGlyph

3
@ RedGlyph Grazie ci proverò. Altrimenti possiamo fare così. git checkout -b new-branch tag-name. Ora clona il tuo nuovo ramo. Quando mai vogliamo, possiamo eliminare il nuovo ramo.
Kalidasan,

Risposte:


2871
$ git clone

ti darà l'intero repository.

Dopo il clone, puoi elencare i tag con $ git tag -le quindi verificare un tag specifico:

$ git checkout tags/<tag_name>

Ancora meglio, fai il checkout e crea un ramo (altrimenti sarai su un ramo chiamato dopo il numero di revisione del tag):

$ git checkout tags/<tag_name> -b <branch_name>

15
Sì. git è diverso dalla sovversione in questo senso. Un tag svn fondamentalmente copia i file in una nuova cartella, quindi è possibile svn estrarre uno specifico gruppo di file, mentre i tag git sono semplicemente puntatori a revisioni specifiche.
sabato

5
Cosa succede se si dispone di un ramo e un tag con lo stesso nome? Se dite semplicemente "git checkout <nome>", dice "avviso: refname '<nome>' è ambiguo. Passato al ramo '<nome>'" - come si dice invece di passare al tag?
MatrixFrog,

54
quando si effettua un checkout e, come menzionato da Derek, il repository passa in uno stato di "testa separata". aggiungi invece la -bbandiera che dice a git di creare un nuovo ramo e specifica un nome di ramo:git checkout <tag_name> -b <branch_name>
hellatan

22
@hellatan Dovresti farlo solo quando vuoi davvero creare un ramo, ma la maggior parte delle volte probabilmente non lo fai. Correre nello stato di "testa staccata" non ti farà male, ed è probabilmente esattamente quello che vuoi se vuoi solo controllare un po 'di cronologia git.
machineghost,

4
Nella versione git 1.8.3.5e successive, --branch <tag ref>dovrebbe consentire di scaricare il repository a partire dal proprio <tag ref>come repository HEAD; combinato con --depth 1farà un checkout tag superficiale. Vedere stackoverflow.com/a/21699307/1695680
ThorSummoner

410
git clone --branch my_abc http://git.abc.net/git/abc.git

Clonerà il repository e ti lascerà sul tag che ti interessa.

Documentazione per 1.8.0 degli stati del clone git .

--branch può anche prendere tag e scollegare HEAD a quel commit nel repository risultante.


7
Questo funziona (almeno ora) per i tag, anche se si finisce in uno stato HEAD distaccato.
mxcl,

72
Cordiali saluti: specificare anche --depth 1per evitare il download di commit non correnti.
Acumenus,

4
Questo in effetti non funziona con i tag. Solo rami. Modifica: sembra che solo le versioni più recenti di git lo supportino.
lzap,

Possiamo anche modificare .git / config (o in qualche modo configurarlo) per eseguire un clone superficiale di due o più tag, se necessario, aggiornare un clone superficiale a clone completo, ecc.
Sam Watkins,

puoi anche specificare il ramo desiderato insieme al tag. Come la git clone --branch my_abc http://git.abc.net/git/abc.git -b qualityqualità è il nome del ramo che vogliamo tra l'altro.
hazimdikenli,

180

Per verificare solo un determinato tag per la distribuzione, utilizzo ad esempio:

git clone -b 'v2.0' --single-branch --depth 1 https://github.com/git/git.git

Questo sembra essere il modo più veloce per estrarre il codice da un repository remoto se si ha interesse solo per il codice più recente invece che per un repository completo. In questo modo, assomiglia al comando 'svn co'.

Nota: per il manuale Git , passare la --depthbandiera implica --single-branchper impostazione predefinita.

--profondità

Crea un clone superficiale con una cronologia troncata al numero specificato di commit. Implica -sele-branch a meno che non venga dato -no-single-branch per recuperare le storie vicino alle punte di tutti i rami. Se si desidera clonare i sottomoduli in modo superficiale, passare anche --shallow-submodules.


10
non posso credere che sia così complicato. suppongo che nessuno si aspetti che il loro codice venga utilizzato da altri.
Ben

9
@Ben, questa è in realtà la soluzione più semplice (è richiesto un solo comando)
Eliran Malka

3
@Ben perché è complicato? È un caso d'uso speciale con alcune funzionalità che si desidera fare diversamente dall'impostazione predefinita. Naturalmente è necessario specificarlo. La soluzione normale sarebbe quella di verificare l'intero repository in un vcs distribuito .
erikbwork,

9
@Ben ha ragione. git è complicato e fu scritto ANNI fa da Linus ed è l'unico che "veramente" capisce come funziona. xkcd.com/1597
RyanNerd

11
--depth nimplica --single-branch. Non hai bisogno di entrambi.
Niyaz,

98

Non sono un esperto git, ma penso che dovrebbe funzionare:

git clone http://git.abc.net/git/abc.git
cd abc
git checkout my_abc 

O

git clone http://git.abc.net/git/abc.git
cd abc
git checkout -b new_branch my_abc

La seconda variante stabilisce un nuovo ramo basato sul tag, che consente di evitare un "HEAD distaccato". (manuale di git-checkout)

Ogni repository git contiene l'intera cronologia delle revisioni, quindi la clonazione del repository ti dà accesso all'ultimo commit, oltre a tutto ciò che è venuto prima, incluso il tag che stai cercando.


4
Grazie. Ho dovuto usare git checkout -b b1.5.0 v1.5.0quando ho verificato una versione all'interno di un ramo 'gh-pages' per inviare correttamente a Github Pages. Questo Gist che ho scritto potrebbe aiutare gli altri a: branch / tag / submodules ... gist.github.com/1064750
Chris Jacob

4
Non penso che sia completamente accurato (per esempio incollare nel terminale) poiché devi prima cdentrare in abc/un ramo
Steven Lu

@StevenLu Naturalmente hai ragione. Stavo cercando concetti piuttosto che taglia e incolla, ma potrebbe anche essere il più preciso possibile. Ho aggiunto il cd.
Grossvogel,

81

Puoi usare git archive per scaricare una tar ball per un dato tag o commit id:

git archive --format=tar --remote=[hostname]:[path to repo] [tag name] > tagged_version.tar

Puoi anche esportare un archivio zip di un tag.

  1. Elenco tag:

    git tag
    
    0.0.1
    0.1.0
    
  2. Esporta un tag:

    git archive -o /tmp/my-repo-0.1.0.zip --prefix=my-repo-0.1.0/ 0.1.0
    
  3. Appunti:

    • Non è necessario specificare il formato. Sarà raccolto dal nome del file di output.
    • Se si specifica il prefisso, il codice verrà esportato in una directory (se si include una barra finale).

3
Questo comando non funziona con i moduli, consultare stackoverflow.com/questions/1591387/...
Zitrax

3
Ma git archive rimuove anche il controllo della versione, quindi non puoi semplicemente fare un altro checkout di git per passare al tag successivo.
idbrii,

9
Sì, perdi il controllo della versione ma il tempo risparmiato dall'archivio git rispetto al clone git è ASSOLUTAMENTE INCREDIBILE! +1
Marc

Questo è così vicino a ciò che voglio, tranne che git archivemi sta chiedendo una password quando tutto ciò che voglio fare è scaricare da un repository pubblico. Come posso farlo usare http invece di ssh?
Robru,

1
Questo non riesce con gli errori fatal: Operation not supported by protocol.e Unexpected end of command stream. In alternativa, può anche restituire l' fatal: The remote end hung up unexpectedlyerrore.
Acumenus,

52

Usa l' --single-branchinterruttore (disponibile da Git 1.7.10) . La sintassi è:

git clone -b <tag_name> --single-branch <repo_url> [<dest_dir>] 

Per esempio:

git clone -b 'v1.9.5' --single-branch https://github.com/git/git.git git-1.9.5

Il vantaggio: Git riceverà oggetti e (sarà necessario) risolvere i delta solo per il ramo / tag specificato - controllando esattamente la stessa quantità di file! A seconda del repository di origine, questo ti farà risparmiare molto spazio su disco. (Inoltre, sarà molto più veloce.)


3
Chiunque abbia votato / declassato questa risposta: si prega di lasciare un commento con una breve spiegazione per il downvote. (Sto solo chiedendo, perché sono un po 'confuso. Perché, a proposito, questa è la soluzione migliore per il problema dato. E se non la pensi così, mi piacerebbe sapere perché.) Molte grazie.
eyecatchUp

5
Non cercare di dare troppo senso ai downvotes .. la tua risposta è molto buona, i loro downvotes sono probabilmente privi di fondamento .. questa è la vita su SOF ..
javadba,

non ha funzionato su git versione 2.22.0.windows.1
Mahesh,

29

prima prendi tutti i tag in quel telecomando specifico

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

o semplicemente digita

git fetch <remote>

Quindi controlla i tag disponibili

git tag -l

quindi passa a quel tag specifico usando il comando seguente

git checkout tags/<tag_name>

Spero che questo ti aiuti!


perché usare ´git tag -l´ dovrebbe essere lo stesso di ggit tag´?
serup

1
@serup; git tagaggiungerà un tag mentre git tag -lelenca i tag disponibili
Joost Döbken

18

Se i tuoi tag sono ordinabili usando il sortcomando linux , usa questo:

git tag | sort -n | tail -1

per esempio. se git tagritorna:

v1.0.1
v1.0.2
v1.0.5
v1.0.4

git tag | sort -n | tail -1 produrrà:

v1.0.5

git tag | sort -n | tail -2 | head -1 produrrà:

v1.0.4

(perché hai richiesto il secondo tag più recente)

per verificare il tag, prima clonare il repository, quindi digitare:

git checkout v1.0.4

..o qualunque tag tu abbia bisogno.


25
Fino a quando non raggiungi la v1.0.10, e poi succedono cose brutte :)
Laurent Grégoire,

10
Per ordinare i tag in ordine cronologico:git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
Bob G,

One-liner per il checkout automatico dell'ultima versione,git checkout `git tag | sort -n | tail -1`
weiji14

Potresti voler usare sort -Vinvece di sort -n. Il primo gestisce correttamente le versioni, che non sono necessariamente numeriche, ad esempio "1.2.3". Comprende anche che "0.4.10" va dopo "0.4.1" e non dopo "0.4.2" che -nti darà.
Mateusz Misiorny,

16

Ho controllato la documentazione di checkout git , ha rivelato una cosa interessante:

git checkout -b <nome_nuovo_braccio> <punto_inizio>, dove <punto_inizio> è il nome di un commit in cui avviare il nuovo ramo; Il valore predefinito è HEAD

Quindi possiamo menzionare il nome del tag (poiché il tag non è altro che il nome di un commit) come, diciamo:

>> git checkout -b 1.0.2_branch 1.0.2 in
seguito, modifica alcuni file
>> git push --tags

PS: In Git, non puoi aggiornare direttamente un tag (poiché il tag è solo un'etichetta per un commit), devi effettuare il checkout dello stesso tag di un ramo e quindi eseguire il commit su di esso e quindi creare un tag separato.


1
Oppure, se non ti aspetti di apportare modifiche e vuoi solo vedere come appariva il codice in quel tag, puoi semplicemente controllare il tag senza creare un ramo. Riceverai del testo che spiega che sei nello stato "testa staccata" e puoi sempre creare il ramo in seguito, se lo desideri.
MatrixFrog,

16
git fetch <gitserver> <remotetag>:<localtag>

===================================

L'ho appena fatto. Innanzitutto mi sono assicurato di conoscere l'ortografia del nome del tag.

git ls-remote --tags gitserver; : or origin, whatever your remote is called

Questo mi ha dato un elenco di tag sul mio server Git tra cui scegliere. Il poster originale conosceva già il nome del suo tag, quindi questo passaggio non è necessario per tutti. L'output sembrava così, sebbene la lista reale fosse più lunga.

8acb6864d10caa9baf25cc1e4857371efb01f7cd    refs/tags/v5.2.2.2
f4ba9d79e3d760f1990c2117187b5010e92e1ea2    refs/tags/v5.2.3.1
8dd05466201b51fcaf4ca85897347d82fcb29518    refs/tags/Fix_109
9b5087090d9077c10ba22d99d5ce90d8a45c50a3    refs/tags/Fix_110

Ho scelto il tag che volevo e l'ho preso e niente di più come segue.

git fetch gitserver Fix_110

Ho quindi taggato questo sul mio computer locale, dando al mio tag lo stesso nome.

git tag Fix_110 FETCH_HEAD

Non volevo clonare il repository remoto come altre persone hanno suggerito di fare, poiché il progetto a cui sto lavorando è grande e voglio svilupparmi in un ambiente pulito e gradevole. Penso che questo sia più vicino alle domande originali "Sto cercando di capire come scaricare A PARTICULAR TAG" rispetto alla soluzione che suggerisce la clonazione dell'intero repository. Non vedo perché qualcuno dovrebbe avere una copia del codice sorgente di Windows NT e Windows 8.1 se vogliono guardare il codice sorgente DOS 0.1 (per esempio).

Inoltre non volevo usare CHECKOUT come altri hanno suggerito. Avevo controllato un ramo e non volevo influenzarlo. La mia intenzione era quella di recuperare il software che volevo, in modo da poter scegliere qualcosa e aggiungerlo al mio sviluppo.

C'è probabilmente un modo per recuperare il tag stesso piuttosto che solo una copia del commit che è stato taggato. Ho dovuto etichettare me stesso il commit recuperato. EDIT: Ah sì, l'ho trovato ora.

git fetch gitserver Fix_110:Fix_110

Dove vedi i due punti, questo è il nome remoto: nome locale e qui sono i nomi dei tag. Questo funziona senza stravolgere l'albero di lavoro, ecc. Sembra solo copiare cose dal telecomando al computer locale in modo da avere la tua copia.

git fetch gitserver --dry-run Fix_110:Fix_110

con l'opzione --dry-run aggiunta ti permetterà di dare un'occhiata a cosa farebbe il comando, se vuoi verificarne quello che vuoi. Quindi immagino un semplice

git fetch gitserver remotetag:localtag

è la vera risposta.

=

Una nota separata sui tag ... Quando inizio qualcosa di nuovo di solito taggo il repository vuoto dopo git init, da allora

git rebase -i XXXXX 

richiede un commit e sorge la domanda "come si possono reimpostare le modifiche che includono la prima modifica del software?" Quindi quando inizio a lavorare lo faccio

git init
touch .gitignore
[then add it and commit it, and finally]
git tag EMPTY

cioè creare un commit prima del mio primo vero cambiamento e poi usarlo

git rebase -i EMPTY 

se voglio rifare tutto il mio lavoro, incluso il primo cambiamento .


8

Lavorando sulla risposta di Peter Johnson, ho creato un piccolo alias per me stesso:

alias gcolt="git checkout $(git tag | sort -V | tail -1)"

alias 'git checkout latest tag'.

Questo si basa sulla versione GNU di ordinamento, che gestisce in modo appropriato situazioni come quella indicata da lOranger:

v1.0.1
...
v1.0.9
v1.0.10

Se sei su un Mac, brew install coreutilsquindi chiama gsort.



5

Verifica dei tag

Se vuoi visualizzare le versioni dei file a cui punta un tag, puoi fare un checkout git, anche se questo mette il tuo repository nello stato "staccata HEAD", che ha alcuni effetti collaterali negativi:

$ git checkout 2.0.0
Note: checking out '2.0.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout 2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... add atlas.json and cover image

Nello stato di "HEAD distaccato", se si apportano modifiche e quindi si crea un commit, il tag rimarrà lo stesso, ma il nuovo commit non apparterrà a nessun ramo e sarà irraggiungibile, tranne per l'esatto hash di commit. Pertanto, se è necessario apportare modifiche, ad esempio se si sta risolvendo un bug su una versione precedente, in genere si desidera creare un ramo:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

Se lo fai e fai un commit, il tuo ramo version2 sarà leggermente diverso dal tuo tag v2.0.0 poiché andrà avanti con le tue nuove modifiche, quindi fai attenzione.


4

Faccio questo tramite l'API github:

curl -H "Authorization: token %(access_token)s" -sL -o /tmp/repo.tar.gz "http://api.github.com/repos/%(organisation)s/%(repo)s/tarball/%(tag)s" ;\
tar xfz /tmp/repo.tar.gz -C /tmp/repo --strip-components=1 ; \

1
Questo funziona per rami e tag, ma non per il capo del master che ha bisogno di un tag creato contro di esso. Imho un modo abbastanza elegante per ottenere una versione di dimensioni ridotte.
J0hnG4lt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.