Baixe uma tag específica com Git

1941

Estou tentando descobrir como posso baixar uma tag específica de um repositório Git - é uma versão por trás da versão atual.

Vi que havia uma tag para a versão anterior na página da web git, com o nome do objeto com um número hexadecimal longo.

Mas o nome da versão é " Tagged release 1.1.5" de acordo com o site.

Eu tentei um comando como este (com nomes alterados):

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

E consegui algo - um diretório, um monte de subdiretórios etc.

Se for o repositório inteiro, como chego à versão que estou procurando? Caso contrário, como faço para baixar essa versão específica?

Jack BeNimble
fonte
11
Eu desenvolvo um repositório completamente diferente da produção, para que minha produção não conhecesse nenhuma tag quando tentei usar o git checkout. A solução foi usar "git pull - tags" e depois usar o git checkout.
Enterprise Architect
11
O "git fetch --tags" também funciona #
John Erck
16
Para evitar a clonagem de todo o repositório e a troca para uma tag, você pode fazer diretamente a clone -b "Tagged release 1.1.5" http://git.abc.net/git/abs.git my_abc. Isso só funcionará se você não tiver uma ramificação com o mesmo nome, é claro (dependendo da sua metodologia, isso pode nunca acontecer).
RedGlyph
3
@RedGlyph Obrigado, vou tentar. Senão, podemos fazer assim. git checkout -b new-branch tag-name. Agora clone sua nova ramificação. Sempre que quisermos, podemos excluir o novo ramo.
kalidasan

Respostas:

2871
$ git clone

lhe dará todo o repositório.

Após o clone, você pode listar as tags $ git tag -le fazer check-out de uma tag específica:

$ git checkout tags/<tag_name>

Melhor ainda, faça o checkout e crie uma filial (caso contrário, você estará em uma filial com o nome do número de revisão da tag):

$ git checkout tags/<tag_name> -b <branch_name>
atormentado
fonte
15
Sim. O git é diferente da subversão a esse respeito. Uma tag svn basicamente copia os arquivos para uma nova pasta, para que você possa fazer o svn checkout de um monte específico de arquivos, enquanto as tags git são simplesmente indicadores de revisões específicas.
DBR
5
E se você tiver um ramo e uma tag com o mesmo nome? Se você acabou de dizer "git checkout <name>", ele diz "warning: refname '<name>' é ambíguo. Alterado para o ramo '<name>'" - como você diz para alternar para a tag?
MatrixFrog
54
ao fazer um checkout e, como Derek mencionou, o repo entra em um estado de "cabeça desanexada". em vez disso, adicione o -bgit bandeira revelador para criar um novo ramo e especificar um nome de ramo:git checkout <tag_name> -b <branch_name>
hellatan
22
@ hellatan Você só deve fazer isso quando realmente deseja criar um ramo, mas na maioria das vezes provavelmente não. A execução no estado de "cabeça desanexada" não o machucará e provavelmente é exatamente o que você deseja se apenas quiser verificar algum histórico do git.
Machineghost
4
Na versão git 1.8.3.5e mais recente, o --branch <tag ref>deve permitir que você baixe o repositório começando no seu <tag ref>como repositório HEAD; combinado com --depth 1fará uma verificação superficial de tags. Veja stackoverflow.com/a/21699307/1695680
ThorSummoner 2/14
410
git clone --branch my_abc http://git.abc.net/git/abc.git

Clonará o repo e o deixará na tag de seu interesse.

Documentação para 1.8.0 dos estados do clone git .

--branch também pode pegar tags e desanexar o HEAD naquele commit no repositório resultante.

Toni
fonte
7
Isso funciona (pelo menos agora) para tags, embora você acabe em um estado HEAD desanexado.
Mxcl
72
FYI: especifique também --depth 1para evitar o download de confirmações não atuais.
Acumenus 27/03
4
Isso realmente não funciona com tags. Apenas galhos. Edit: Parece que apenas as versões mais recentes do git suportam isso.
lzap
Nós também pode editar .git / config (ou de alguma forma configurá-lo) para fazer um clone de dois ou mais tags rasa, se isso pode ser necessário, atualizar um clone superficial para clone completo, etc.
Sam Watkins
você também pode especificar o ramo que deseja junto com a tag. Como git clone --branch my_abc http://git.abc.net/git/abc.git -b qualityqualidade é o nome do ramo que queremos entre.
hazimdikenli
180

Para verificar apenas uma determinada tag para implantação, eu uso, por exemplo:

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

Essa parece ser a maneira mais rápida de verificar o código de um repositório remoto, se houver interesse apenas no código mais recente, em vez de em um repositório completo. Dessa maneira, assemelha-se ao comando 'svn co'.

Nota: De acordo com o manual do Git , passar a --depthbandeira implica --single-branchpor padrão.

--profundidade

Crie um clone superficial com um histórico truncado para o número especificado de confirmações. Implica - único ramo, a menos que - nenhum ramo único seja fornecido para buscar os históricos próximos às pontas de todos os ramos. Se você deseja clonar submodulos superficialmente, também passe --shallow-submódulos.

Yuan HOng
fonte
10
Não posso acreditar que é tão complicado. acho que ninguém espera que seu código seja usado por outras pessoas.
Ben
9
@ Ben, esta é realmente a solução mais simples (é necessário um único comando)
Eliran Malka
3
@ Ben por que isso é complicado? É um caso de usuário especial com alguns recursos que você deseja executar de maneira diferente do padrão. Claro que você precisa especificá-lo. A solução normal seria fazer o checkout de todo o repositório em um vcs distribuído .
Erikbwork
9
@ Ben está certo. O git é complicado e foi escrito há anos por Linus e ele é o único que "realmente" entende como isso funciona. xkcd.com/1597
RyanNerd
11
--depth nimplica --single-branch. Você não precisa dos dois.
Niyaz
98

Não sou especialista em git, mas acho que isso deve funcionar:

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

OU

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

A segunda variação estabelece uma nova ramificação baseada na tag, o que permite evitar um 'HEAD desanexado'. (manual do git-checkout)

Cada repositório git contém todo o histórico de revisões, portanto, a clonagem do repositório fornece acesso ao commit mais recente, além de tudo o que veio antes, incluindo a tag que você está procurando.

grossvogel
fonte
4
Valeu. Eu precisava usar git checkout -b b1.5.0 v1.5.0ao fazer o check-out de uma versão dentro de um ramo 'gh-pages' para enviar com êxito para as páginas do Github. Este Gist Eu escrevi poderia ajudar outros re: ramo / etiqueta / submódulos ... gist.github.com/1064750
Chris Jacob
4
Eu não acho que isso seja completamente preciso (por exemplo, colar no terminal), pois você primeiro cdentrou abc/antes de poder fazer o checkout de uma filial
Steven Lu
@StevenLu Você está certo, é claro. Eu estava buscando conceitos em vez de recortar e colar, mas poderia ser o mais preciso possível. Eu adicionei o cd.
grossvogel
81

Você pode usar o git archive para baixar um tar ball para uma determinada tag ou confirmar o ID:

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

Você também pode exportar um arquivo zip de uma tag.

  1. Tags da lista:

    git tag
    
    0.0.1
    0.1.0
    
  2. Exportar uma tag:

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

    • Você não precisa especificar o formato. Será selecionado pelo nome do arquivo de saída.
    • A especificação do prefixo fará com que seu código seja exportado para um diretório (se você incluir uma barra final).
Chris J
fonte
3
Este comando não funciona com submódulos, consulte stackoverflow.com/questions/1591387/…
Zitrax
3
Mas o arquivo git também remove o controle de versão; portanto, você não pode simplesmente fazer outro check-out do git para atualizar para a próxima tag.
Idbrii 6/04
9
Sim, você perde o controle de versão, mas o tempo que o arquivo git economiza em comparação ao clone git é ABSOLUTAMENTE IN inacreditável! 1
MarcH
Isso é TÃO PERTO do que eu quero, exceto que git archiveestá me pedindo uma senha quando tudo que eu quero fazer é baixar de um repositório público. Como posso usar http em vez de ssh?
robru
1
Esta falha com o fatal: Operation not supported by protocol.e Unexpected end of command streamerros. Como alternativa, também pode retornar o fatal: The remote end hung up unexpectedlyerro.
Acumenus 27/03
52

Use o --single-branchcomutador (disponível no Git 1.7.10) . A sintaxe é:

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

Por exemplo:

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

A vantagem: o Git receberá objetos e (precisará) resolver deltas apenas para a ramificação / tag especificada - enquanto verifica exatamente a mesma quantidade de arquivos! Dependendo do repositório de origem, você economizará muito espaço em disco. (Além disso, será muito mais rápido.)

eyecatchUp
fonte
3
Quem votou negativamente / votou negativamente nesta resposta: por favor, também deixe um comentário com uma breve explicação para o voto negativo. (Só estou perguntando, porque estou um pouco confuso. Porque, afinal, esta é a melhor solução para o problema em questão. E se você não acha, eu gostaria de saber o porquê.) Muito obrigado.
precisa
5
Não tente fazer muito sentido das downvotes .. sua resposta é muito boa, seus downvotes provavelmente infundadas .. isso é a vida na SOF ..
javadba
não funcionou na versão git 2.22.0.windows.1
Mahesh
29

primeiro busque todas as tags nesse controle remoto específico

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

ou simplesmente digite

git fetch <remote>

Em seguida, verifique as tags disponíveis

git tag -l

depois mude para essa tag específica usando o comando abaixo

git checkout tags/<tag_name>

Espero que isso ajude você!

tk_
fonte
por que usar 'git tag -l' deve ser o mesmo que 'git tag'?
serup 11/11/19
1
@serup; git tagadicionará uma tag enquanto git tag -llista as tags disponíveis
Joost Döbken
18

Se suas tags puderem ser classificadas usando o sortcomando linux , use o seguinte:

git tag | sort -n | tail -1

por exemplo. se git tagretorna:

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

git tag | sort -n | tail -1 irá produzir:

v1.0.5

git tag | sort -n | tail -2 | head -1 irá produzir:

v1.0.4

(porque você solicitou a segunda tag mais recente)

para efetuar o checkout da tag, primeiro clone o repositório e digite:

git checkout v1.0.4

..ou qualquer tag que você precise.

Peter Johnson
fonte
25
Até chegar v1.0.10, e então as coisas ruins acontecem :)
Laurent Grégoire
10
Para que suas tags sejam classificadas cronologicamente:git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
Bob G
One-liner para automaticamente fazer o checkout da última versão,git checkout `git tag | sort -n | tail -1`
weiji14
Você pode querer usar em sort -Vvez de sort -n. O primeiro manipula corretamente versões que não são necessariamente numéricas, por exemplo, "1.2.3". Ele também entende que "0.4.10" segue após "0.4.1" e não após "0.4.2", o que -nfornecerá a você.
Mateusz Misiorny 15/09
16

Verifiquei a documentação do git checkout , que revelou uma coisa interessante:

git checkout -b <novo_branch_name> <nome_de_artigo>, em que <nome_de_artigo> é o nome de uma confirmação na qual iniciar a nova ramificação; O padrão é HEAD

Portanto, podemos mencionar o nome da tag (como tag nada mais é que o nome de um commit) como, digamos:

>> git checkout -b 1.0.2_branch 1.0.2
depois, modifique alguns arquivos
>> git push --tags

PS: No Git, você não pode atualizar uma tag diretamente (já que a tag é apenas um rótulo para uma confirmação), você precisa fazer o checkout da mesma tag que uma ramificação e, em seguida, confirmar e criar uma tag separada.

Nenhum da
fonte
1
Ou, se você não espera fazer alterações e deseja apenas ver como era o código nessa tag, basta fazer check-out da tag sem criar uma ramificação. Você receberá um texto explicando que está no estado "desanexado" e sempre poderá criar o ramo mais tarde, se desejar.
MatrixFrog
16
git fetch <gitserver> <remotetag>:<localtag>

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

Eu acabei de fazer isso. Primeiro, verifiquei a ortografia do nome da tag.

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

Isso me deu uma lista de tags no meu servidor git para escolher. O pôster original já sabia o nome de sua tag, portanto esta etapa não é necessária para todos. A saída era assim, embora a lista real fosse mais longa.

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

Eu escolhi a etiqueta que eu queria e peguei isso e nada mais como se segue.

git fetch gitserver Fix_110

Em seguida, marquei isso na minha máquina local, dando à minha tag o mesmo nome.

git tag Fix_110 FETCH_HEAD

Eu não queria clonar o repositório remoto como outras pessoas sugeriram, pois o projeto no qual estou trabalhando é grande e quero desenvolver em um ambiente limpo e agradável. Eu sinto que isso está mais próximo das perguntas originais "Estou tentando descobrir como fazer o download de A PARTICULAR TAG" do que a solução que sugere a clonagem de todo o repositório. Não vejo por que alguém deveria ter uma cópia do código-fonte do Windows NT e Windows 8.1 se quiser ver o código-fonte do DOS 0.1 (por exemplo).

Também não queria usar o CHECKOUT, como outros sugeriram. Eu tinha um ramo verificado e não queria afetar isso. Minha intenção era buscar o software que eu queria para poder escolher algo e adicionar isso ao meu desenvolvimento.

Provavelmente, existe uma maneira de buscar a própria tag, em vez de apenas uma cópia da confirmação que foi marcada. Eu tive que marcar o compromisso buscado eu mesmo. EDIT: Ah sim, eu encontrei agora.

git fetch gitserver Fix_110:Fix_110

Onde você vê os dois pontos, ou seja, remote-name: local-name e aqui estão os nomes das tags. Isso funciona sem perturbar a árvore de trabalho, etc. Parece apenas copiar coisas do controle remoto para a máquina local, para que você tenha sua própria cópia.

git fetch gitserver --dry-run Fix_110:Fix_110

com a opção --dry-run adicionada, você poderá ver o que o comando faria, se você quiser verificar o que deseja. Então eu acho que um simples

git fetch gitserver remotetag:localtag

é a verdadeira resposta.

=

Uma observação separada sobre tags ... Quando inicio algo novo, normalmente identifico o repositório vazio após o git init, pois

git rebase -i XXXXX 

requer uma confirmação e surge a pergunta "como você rebase as alterações que incluem sua primeira alteração de software?" Então, quando eu começo a trabalhar, eu faço

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

ou seja, criar uma confirmação antes da minha primeira alteração real e depois usar

git rebase -i EMPTY 

se eu quiser refazer todo o meu trabalho, incluindo a primeira alteração .

Ivan
fonte
8

Trabalhando com a resposta de Peter Johnson, criei um pequeno apelido para mim:

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

aka tag mais recente do check-out do git.

Isso depende da versão GNU do tipo, que lida adequadamente com situações como a que lOranger apontou:

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

Se você estiver em um Mac, brew install coreutilsligue para gsort.

billkw
fonte
6

tentar:

git clone -b <name_of_the_tag> <repository_url> <destination>
Kamil Zając
fonte
Se houver várias ramificações para o repositório, qual ramificação será clonada?
tauseef_CuriousGuy
5

Fazendo check-out de tags

Se você deseja visualizar as versões dos arquivos apontados por uma tag, pode fazer um check-out do git, embora isso coloque o seu repositório no estado "desanexado HEAD", que tem alguns efeitos colaterais ruins:

$ 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

No estado “desanexado HEAD”, se você fizer alterações e depois criar uma confirmação, a tag permanecerá a mesma, mas sua nova confirmação não pertencerá a nenhum ramo e ficará inacessível, exceto pelo hash de confirmação exato. Portanto, se você precisar fazer alterações - digamos que você está corrigindo um bug em uma versão mais antiga, por exemplo - geralmente desejará criar um ramo:

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

Se você fizer isso e confirmar, sua ramificação version2 será um pouco diferente da sua tag v2.0.0, pois seguirá em frente com suas novas alterações, portanto, tenha cuidado.

artamonovdev
fonte
4

Eu faço isso através da API do 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 ; \
J0hnG4lt
fonte
1
Isso funciona para ramificações e tags, mas não para o chefe do mestre que precisa de uma tag criada contra ele. Imho maneira bastante elegante de obter a versão de tamanho mínimo.
precisa saber é o seguinte