¿Hacer una "exportación git" (como "exportación svn")?
Me he estado preguntando si existe una buena solución de "exportación de git" que cree una copia de un árbol sin el .git
directorio del repositorio. Hay al menos tres métodos que conozco:
git clone
seguido de la eliminación del.git
directorio del repositorio.git checkout-index
alude a esta funcionalidad pero comienza con "Simplemente lea el árbol deseado en el índice...", lo cual no estoy del todo seguro de cómo hacerlo.git-export
es un script de terceros que esencialmente ingresagit clone
a una ubicación temporal y luegorsync --exclude='.git'
al destino final.
Ninguna de estas soluciones me parece realmente satisfactoria. La más cercana svn export
podría ser la opción 1, porque ambas requieren que el directorio de destino esté vacío primero. Pero la opción 2 parece aún mejor, suponiendo que pueda entender qué significa leer un árbol en el índice.
Probablemente la forma más sencilla de lograrlo sea con git archive
. Si realmente necesitas sólo el árbol expandido, puedes hacer algo como esto.
git archive master | tar -x -C /somewhere/else
La mayoría de las veces que necesito "exportar" algo desde git, quiero un archivo comprimido en cualquier caso, así que hago algo como esto.
git archive master | bzip2 >source-tree.tar.bz2
Archivo ZIP:
git archive --format zip --output /full/path/to/zipfile.zip master
git help archive
para más detalles, es bastante flexible.
Tenga en cuenta que, aunque el archivo no contendrá el directorio .git, sí contendrá otros archivos ocultos específicos de git como .gitignore, .gitattributes, etc. Si no los quiere en el archivo, asegúrese de use el atributo export-ignore en un archivo .gitattributes y confírmelo antes de archivar. Leer más...
Nota: Si está interesado en exportar el índice, el comando es
git checkout-index -a -f --prefix=/destination/path/
(Vea la respuesta de Greg para más detalles)
Aquí hay un ejemplo del mundo real usando libchrony en Linux:
mkdir $HOME/dev
cd $HOME/dev
pushd /tmp
git clone https://gitlab.com/chrony/libchrony.git
cd libchrony
BRANCH=$(git rev-parse --abbrev-ref HEAD)
git archive -o ../libchrony.zip --prefix="libchrony/" $BRANCH
popd
unzip /tmp/libchrony.zip
Esos comandos generan un archivo zip y lo extraen en $HOME/dev/libchrony
. Podemos echar un vistazo al archivo usando:
$ unzip -v /tmp/libchrony
Archive: /tmp/libchrony.zip
e0a3807f770b56f6b0e9833254baa7c4fc13564b
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
0 Stored 0 0% 2023-07-20 09:37 00000000 libchrony/
49 Defl:N 47 4% 2023-07-20 09:37 37c3f2e2 libchrony/.gitignore
26530 Defl:N 9350 65% 2023-07-20 09:37 5622583e libchrony/COPYING
961 Defl:N 467 51% 2023-07-20 09:37 da9221e3 libchrony/Makefile
475 Defl:N 304 36% 2023-07-20 09:37 cae27f70 libchrony/README.adoc
3313 Defl:N 1119 66% 2023-07-20 09:37 37eb110f libchrony/chrony.h
7673 Defl:N 2261 71% 2023-07-20 09:37 5d455a52 libchrony/client.c
6190 Defl:N 2093 66% 2023-07-20 09:37 7ea9d81b libchrony/example-reports.c
16348 Defl:N 3855 76% 2023-07-20 09:37 e82f5fe3 libchrony/message.c
2946 Defl:N 1099 63% 2023-07-20 09:37 945ee82b libchrony/message.h
-------- ------- --- -------
64485 20595 68% 10 files
Descubrí lo que significa la opción 2. Desde un repositorio, puedes hacer:
git checkout-index -a -f --prefix=/destination/path/
La barra diagonal al final de la ruta es importante; de lo contrario, los archivos estarán en /destino con el prefijo 'ruta'.
Dado que en una situación normal el índice contiene el contenido del repositorio, no hay nada especial que hacer para "leer el árbol deseado en el índice". Ya está ahí.
La -a
bandera es necesaria para verificar todos los archivos en el índice (no estoy seguro de qué significa omitir esta bandera en esta situación, ya que no hace lo que quiero). La -f
bandera fuerza a sobrescribir cualquier archivo existente en la salida, lo que este comando normalmente no hace.
Este parece ser el tipo de "exportación git" que estaba buscando.
git archive
También funciona con repositorio remoto.
git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -
Para exportar una ruta particular dentro del repositorio, agregue tantas rutas como desee como último argumento a git, por ejemplo:
git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
Una respuesta de caso especial si el repositorio está alojado en GitHub.
Solo usa svn export
.
Hasta donde yo sé, Github no lo permite archive --remote
. Aunque GitHub es compatible con svn y tienen todos los repositorios de git svn
accesibles, puedes usarlos svn export
como lo harías normalmente con algunos ajustes en tu URL de GitHub.
Por ejemplo, para exportar un repositorio completo, observe cómo trunk
en la URL se reemplaza master
(o lo que sea que esté configurada la rama HEAD del proyecto ):
svn export https://github.com/username/repo-name/trunk/
Y puedes exportar un solo archivo o incluso una determinada ruta o carpeta:
svn export https://github.com/username/repo-name/trunk/src/lib/folder
Ejemplo con la biblioteca jQuery JavaScript
La HEAD
rama o rama maestra estará disponible usando trunk
:
svn ls https://github.com/jquery/jquery/trunk
Las no HEAD
sucursales serán accesibles en /branches/
:
svn ls https://github.com/jquery/jquery/branches/2.1-stable
Todas las etiquetas/tags/
de la misma manera:
svn ls https://github.com/jquery/jquery/tags/2.1.3
Del manual de Git :
Usando git-checkout-index para "exportar un árbol completo"
La capacidad de prefijo básicamente hace que sea trivial usar git-checkout-index como una función de "exportar como árbol". Simplemente lea el árbol deseado en el índice y haga:
$ git checkout-index --prefix=git-export-dir/ -a