Descargar una etiqueta específica con Git

1941

Estoy tratando de descubrir cómo puedo descargar una etiqueta particular de un repositorio de Git: es una versión detrás de la versión actual.

Vi que había una etiqueta para la versión anterior en la página web de git, con el nombre del objeto de un número hexadecimal largo.

Pero el nombre de la versión es " Tagged release 1.1.5" según el sitio.

Intenté un comando como este (con nombres cambiados):

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

Y obtuve algo: un directorio, un montón de subdirectorios, etc.

Si es todo el repositorio, ¿cómo obtengo la versión que estoy buscando? Si no, ¿cómo descargo esa versión en particular?

Jack BeNimble
fuente
11
Desarrollé en un repositorio completamente diferente a la producción, por lo que mi producción no conocía ninguna etiqueta cuando intenté usar git checkout. La solución fue usar "git pull --tags" y luego usar git checkout.
Arquitecto empresarial el
11
"git fetch --tags" también funciona
John Erck
16
Para evitar clonar todo el repositorio y luego cambiar a una etiqueta, puede hacer directamente un clone -b "Tagged release 1.1.5" http://git.abc.net/git/abs.git my_abc. Esto solo funcionará si no tiene una sucursal con el mismo nombre, por supuesto (dependiendo de su metodología, esto puede nunca suceder).
RedGlyph
3
@ RedGlyph Gracias lo intentaré. De lo contrario, podemos hacer así. git checkout -b new-branch tag-name. Ahora clona tu nueva rama. Cuando queramos podemos eliminar la nueva rama.
kalidasan

Respuestas:

2871
$ git clone

te dará todo el repositorio.

Después del clon, puede enumerar las etiquetas con $ git tag -ly luego retirar una etiqueta específica:

$ git checkout tags/<tag_name>

Aún mejor, finalice la compra y cree una rama (de lo contrario, estará en una rama con el nombre del número de revisión de la etiqueta):

$ git checkout tags/<tag_name> -b <branch_name>
besen
fuente
15
Sí. git es diferente a la subversión a este respecto. Una etiqueta svn básicamente copia los archivos a una nueva carpeta, por lo que puede svn retirar un grupo específico de archivos, mientras que las etiquetas git son simplemente punteros a revisiones específicas.
dbr
55
¿Qué sucede si tiene una rama y una etiqueta que tienen el mismo nombre? Si solo dice "git checkout <nombre>" dice "advertencia: refname '<nombre>' es ambiguo. Cambió a la rama '<nombre>'". ¿Cómo le dice que cambie a la etiqueta?
MatrixFrog
54
al hacer un pago y, como Derek mencionó, el repositorio entra en un estado de "cabeza separada". En su lugar, añadir el -bgit indicador revelador para crear una nueva rama y especificar un nombre de rama:git checkout <tag_name> -b <branch_name>
hellatan
22
@hellatan Solo debes hacer eso cuando realmente quieras crear una rama, pero la mayoría de las veces probablemente no lo hagas. Correr en el estado de "cabeza separada" no te hará daño, y es probable que sea exactamente lo que quieres si solo quieres ver un poco de historial de git.
machineghost
44
En la versión git 1.8.3.5y posteriores, --branch <tag ref>debería permitirte descargar el repositorio comenzando en tu <tag ref>como el repositorio HEAD; combinado con --depth 1hará un pago superficial de la etiqueta. Ver stackoverflow.com/a/21699307/1695680
ThorSummoner
410
git clone --branch my_abc http://git.abc.net/git/abc.git

Clonará el repositorio y lo dejará en la etiqueta que le interesa.

Documentación para 1.8.0 de estados de clon git .

--branch también puede tomar etiquetas y separa el HEAD en ese commit en el repositorio resultante.

Toni
fuente
77
Esto (al menos ahora) funciona para las etiquetas, aunque terminas en un estado HEAD separado.
mxcl
72
FYI: especifique también --depth 1para evitar la descarga de confirmaciones no actuales.
Acumenus
44
De hecho, esto no funciona con etiquetas. Solo ramas. Editar: Parece que solo las versiones más nuevas de git lo admiten.
lzap
También podemos editar .git / config (o de alguna manera configurarlo) para hacer un clon superficial de dos o más etiquetas, si es necesario, actualice un clon superficial a clon completo, etc.
Sam Watkins
También puede especificar la rama que desea junto con la etiqueta. Como git clone --branch my_abc http://git.abc.net/git/abc.git -b qualitycalidad es el nombre de la sucursal que queremos por cierto.
hazimdikenli
180

Para retirar solo una etiqueta dada para la implementación, utilizo, por ejemplo:

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

Esta parece ser la forma más rápida de extraer código de un repositorio remoto si uno solo está interesado en el código más reciente en lugar de en un repositorio completo. De esta manera, se parece al comando 'svn co'.

Nota: Según el manual de Git , pasar la --depthbandera implica --single-branchpor defecto.

--profundidad

Cree un clon superficial con un historial truncado al número especificado de confirmaciones. Implica una sola rama a menos que no se dé una sola rama para obtener las historias cerca de las puntas de todas las ramas. Si desea clonar submódulos superficialmente, también pase --shallow-submodules.

Yuan HOng
fuente
10
No puedo creer que sea tan complicado. supongo que nadie espera que otros usen su código.
Ben
99
@Ben, esta es en realidad la solución más simple (se requiere un solo comando)
Eliran Malka
3
@Ben, ¿por qué es esto complicado? Es un caso de uso especial con algunas características que desea hacer de manera diferente a la predeterminada. Por supuesto que necesita especificarlo. La solución normal sería verificar el repositorio completo en un vcs distribuido .
erikbwork
99
@Ben tiene razón. git es complicado y fue escrito hace AÑOS por Linus y él es el único que "realmente" entiende cómo funciona. xkcd.com/1597
RyanNerd
11
--depth nimplica --single-branch. No necesitas los dos.
Niyaz
98

No soy un experto en git, pero creo que esto debería funcionar:

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 segunda variación establece una nueva rama basada en la etiqueta, que le permite evitar una 'CABEZA separada'. (manual de git-checkout)

Cada repositorio de git contiene el historial de revisiones completo, por lo que clonar el repositorio le da acceso a la última confirmación, además de todo lo anterior, incluida la etiqueta que está buscando.

Grossvogel
fuente
44
Gracias. Necesitaba usarlo git checkout -b b1.5.0 v1.5.0cuando revisaba una versión dentro de una rama 'gh-pages' para empujar con éxito a las páginas de Github. Este Gist que escribí podría ayudar a otros a re: branch / tag / submodules ... gist.github.com/1064750
Chris Jacob
44
No creo que esto sea completamente exacto (por ejemplo, pegar en la terminal) ya que debes cdingresar abc/primero antes de que puedas pagar una sucursal
Steven Lu
@StevenLu Tienes razón, por supuesto. Estaba buscando conceptos en lugar de cortar y pegar, pero podría ser lo más preciso posible. He agregado el cd.
grossvogel
81

Puede usar el archivo git para descargar una bola de alquitrán para una etiqueta determinada o confirmar la identificación:

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

También puede exportar un archivo zip de una etiqueta.

  1. Etiquetas de lista:

    git tag
    
    0.0.1
    0.1.0
    
  2. Exportar una etiqueta:

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

    • No necesita especificar el formato. Será recogido por el nombre del archivo de salida.
    • Si especifica el prefijo, su código se exportará a un directorio (si incluye una barra inclinada final).
Chris J
fuente
3
Este comando no funciona con submódulos, consulte stackoverflow.com/questions/1591387/…
Zitrax
3
Pero el archivo git también elimina el control de versión, por lo que no puede hacer otra compra de git para actualizar a la siguiente etiqueta.
idbrii
99
Sí, pierde el control de la versión, pero el tiempo que ahorra el archivo git en comparación con el clon git es ¡ABSOLUTAMENTE INCREÍBLE! +1
MarcH
Esto está TAN CERCA de lo que quiero, excepto que git archiveme pide una contraseña cuando todo lo que quiero hacer es descargarlo de un repositorio público. ¿Cómo puedo hacer que use http en lugar de ssh?
robru
1
Esto falla con los errores fatal: Operation not supported by protocol.y Unexpected end of command stream. Alternativamente, también puede devolver el fatal: The remote end hung up unexpectedlyerror.
Acumenus
52

Use el --single-branchinterruptor (disponible a partir de Git 1.7.10) . La sintaxis es:

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

Por ejemplo:

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

El beneficio: Git recibirá objetos y (necesitará) resolver los deltas solo para la rama / etiqueta especificada, ¡mientras verifica exactamente la misma cantidad de archivos! Dependiendo del repositorio de origen, esto le ahorrará mucho espacio en disco. (Además, será mucho más rápido).

eyecatchUp
fuente
3
Quien haya rechazado / rechazado esta respuesta: Por favor, también deje un comentario con una breve explicación del voto negativo. (Solo pregunto, porque estoy un poco confundido. Porque, afaik, esta es la mejor solución para el problema dado. Y si no lo crees, me gustaría saber por qué). Muchas gracias.
eyecatchUp
55
No trate de hacer demasiado sentido de las downvotes .. su respuesta es muy buena, sus downvotes probablemente sin fundamento .. así es la vida en SOF ..
javadba
no funcionó en git versión 2.22.0.windows.1
Mahesh
29

primero busque todas las etiquetas en ese control remoto específico

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

o simplemente escriba

git fetch <remote>

Luego verifique las etiquetas disponibles

git tag -l

luego cambie a esa etiqueta específica usando el siguiente comando

git checkout tags/<tag_name>

Espero que esto te ayude!

tk_
fuente
¿por qué usar 'etiqueta de git -l' debería ser lo mismo que 'etiqueta de git'?
serup
1
@serup; git tagagregará una etiqueta mientras git tag -lenumera las etiquetas disponibles
Joost Döbken
18

Si sus etiquetas se pueden ordenar usando el sortcomando linux , use esto:

git tag | sort -n | tail -1

p.ej. si git tagvuelve:

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

git tag | sort -n | tail -1 dará salida:

v1.0.5

git tag | sort -n | tail -2 | head -1 dará salida:

v1.0.4

(porque solicitó la segunda etiqueta más reciente)

para pagar la etiqueta, primero clone el repositorio, luego escriba:

git checkout v1.0.4

... o cualquier etiqueta que necesites.

Peter Johnson
fuente
25
Hasta que llegue a v1.0.10, y luego sucedan cosas malas :)
Laurent Grégoire
10
Para ordenar sus etiquetas cronológicamente:git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
Bob G
One-liner para git checkout `git tag | sort -n | tail -1`
verificar
Es posible que desee utilizar en sort -Vlugar de sort -n. El primero maneja correctamente las versiones, que no son necesariamente numéricas, por ejemplo, "1.2.3". También entiende que "0.4.10" va después de "0.4.1" y no después de "0.4.2" que -nle dará.
Mateusz Misiorny
16

Revisé la documentación de pago de git , reveló una cosa interesante:

git checkout -b <nombre_de_nuevo_rango> <punto_inicio>, donde <punto_inicio> es el nombre de una confirmación en la que iniciar la nueva rama; El valor predeterminado es HEAD

Entonces podemos mencionar el nombre de la etiqueta (ya que la etiqueta no es más que el nombre de una confirmación) como, por ejemplo:

>> git checkout -b 1.0.2_branch 1.0.2
más tarde, modifica algunos archivos
>> git push --tags

PD: en Git, no puede actualizar una etiqueta directamente (dado que la etiqueta es solo una etiqueta para una confirmación), debe verificar la misma etiqueta que una rama y luego confirmarla y luego crear una etiqueta separada.

Ninguno-da
fuente
1
O si no espera hacer ningún cambio y solo desea ver cómo se veía el código en esa etiqueta, puede simplemente retirar la etiqueta sin crear una rama. Recibirá un texto que explica que está en estado de "cabeza separada", y siempre puede crear la rama más adelante si lo desea.
MatrixFrog
16
git fetch <gitserver> <remotetag>:<localtag>

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

Acabo de hacer esto. Primero me aseguré de saber la ortografía del nombre de la etiqueta.

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

Esto me dio una lista de etiquetas en mi servidor git para elegir. El póster original ya sabía el nombre de su etiqueta, por lo que este paso no es necesario para todos. El resultado se veía así, aunque la lista real era más larga.

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

Elegí la etiqueta que quería y obtuve eso y nada más de la siguiente manera.

git fetch gitserver Fix_110

Luego etiqueté esto en mi máquina local, dándole a mi etiqueta el mismo nombre.

git tag Fix_110 FETCH_HEAD

No quería clonar el repositorio remoto como otras personas me han sugerido, ya que el proyecto en el que estoy trabajando es grande y quiero desarrollarlo en un ambiente limpio y agradable. Siento que esto está más cerca de las preguntas originales "Estoy tratando de descubrir cómo descargar UNA ETIQUETA PARTICULAR" que la solución que sugiere clonar todo el repositorio. No veo por qué alguien debería tener una copia del código fuente de Windows NT y Windows 8.1 si quieren ver el código fuente de DOS 0.1 (por ejemplo).

Tampoco quería usar CHECKOUT como otros han sugerido. Revisé una sucursal y no quise afectarla. Mi intención era buscar el software que quería para poder elegir algo y agregarlo a mi desarrollo.

Probablemente haya una manera de obtener la etiqueta en sí en lugar de solo una copia de la confirmación que fue etiquetada. Tuve que etiquetar el compromiso obtenido yo mismo EDITAR: Ah sí, lo he encontrado ahora.

git fetch gitserver Fix_110:Fix_110

Donde ve los dos puntos, ese es el nombre remoto: nombre local y aquí están los nombres de las etiquetas. Esto se ejecuta sin alterar el árbol de trabajo, etc. Parece que copia cosas del control remoto a la máquina local para que tenga su propia copia.

git fetch gitserver --dry-run Fix_110:Fix_110

con la opción --dry-run agregada, le permitirá ver lo que haría el comando, si desea verificar que es lo que desea. Así que supongo que un simple

git fetch gitserver remotetag:localtag

Es la verdadera respuesta.

=

Una nota separada sobre las etiquetas ... Cuando comienzo algo nuevo, generalmente etiqueto el repositorio vacío después de git init, ya que

git rebase -i XXXXX 

requiere un compromiso, y surge la pregunta "¿cómo se vuelven a modificar los cambios que incluyen su primer cambio de software?" Entonces cuando empiezo a trabajar lo hago

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

es decir, crear un commit antes de mi primer cambio real y luego usarlo

git rebase -i EMPTY 

si quiero reajustar todo mi trabajo, incluido el primer cambio .

Ivan
fuente
8

A partir de la respuesta de Peter Johnson, creé un pequeño alias para mí:

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

también conocido como 'git checkout última etiqueta'.

Esto se basa en la versión GNU de sort, que maneja adecuadamente situaciones como la que lOranger señaló:

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

Si estás en una Mac, brew install coreutilsy luego llama a gsort en su lugar.

billkw
fuente
6

tratar:

git clone -b <name_of_the_tag> <repository_url> <destination>
Kamil Zając
fuente
Si hay varias ramas para el repositorio, ¿qué rama se clonará?
tauseef_CuriousGuy 13/03/18
5

Revisando etiquetas

Si desea ver las versiones de los archivos a los que apunta una etiqueta, puede hacer un pago git, aunque esto pone su repositorio en estado "HEAD separado", lo que tiene algunos efectos secundarios negativos:

$ 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

En el estado "HEAD separado", si realiza cambios y luego crea un commit, la etiqueta permanecerá igual, pero su nuevo commit no pertenecerá a ninguna rama y será inalcanzable, excepto por el hash de commit exacto. Por lo tanto, si necesita realizar cambios, por ejemplo, si está reparando un error en una versión anterior, generalmente querrá crear una rama:

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

Si hace esto y realiza una confirmación, la rama de su versión2 será ligeramente diferente de su etiqueta v2.0.0, ya que avanzará con sus nuevos cambios, así que tenga cuidado.

artamonovdev
fuente
4

Lo hago a través de la API de 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
fuente
1
Esto funciona para ramas y etiquetas, pero no para el jefe del maestro que necesita una etiqueta creada en su contra. Imho manera bastante elegante para obtener la versión de tamaño mínimo.
J0hnG4lt