git version-control sparse-checkout

Escaso checkout en Git 1.7.0?



version-control sparse-checkout (7)

Con la nueva característica de pago escaso en Git 1.7.0, ¿es posible obtener el contenido de un subdirectorio como lo hace en SVN? Encontré este ejemplo , pero conserva la estructura completa del directorio. Imagine que solo quería los contenidos del directorio ''perl'', sin un directorio real llamado ''perl''.

- EDITAR -

Ejemplo:

Mi repositorio de git contiene las siguientes rutas

repo/.git/ repo/perl/ repo/perl/script1.pl repo/perl/script2.pl repo/images/ repo/images/image1.jpg repo/images/image2.jpg repo/doc/ repo/doc/readme.txt repo/doc/help.txt

Lo que quiero es poder producir desde el repositorio anterior este diseño:

repo/.git/ repo/script1.pl repo/script2.pl

Sin embargo, con la función de pago escaso actual, parece que solo es posible obtener

repo/.git/ repo/perl/script1.pl repo/perl/script2.pl

que NO es lo que quiero


Ahora, sin entrar en detalles sobre por qué querrías hacer esto, tu problema puede (probablemente) resolverse fácilmente mediante un enlace simbólico / acceso directo.

Para responder la pregunta, no, y con una razón significativa. Toda la historia del repositorio se descarga incluso con un ''pago escaso''. Para aclarar por qué es necesario, de lo contrario, el seguimiento de los archivos renombrados sería un dolor en el ... cuello. Imagine que mueve el archivo /repo_root/asd/file1.cpp a /repo_root/fgh/file1.cpp - ahora si solo hubiera descargado /repo_root/fgh deltas, no sabrá acerca de file1.cpp. Esto significa que debes descargar todos los deltas. Pero luego tienes un repositorio completo; no solo un corte de carpeta, por lo tanto, solo la /rero_root/fgh no es un repositorio en sí. Puede que esto no suene importante cuando finaliza la compra, pero cuando se compromete, es posible que git no sepa lo suficiente como para funcionar bien.

Solución alternativa : si realmente lo desea, puede crear un script que invoque git-checkout de esa manera (para el sh shell, el lote para Windows no debería ser difícil de producir):

!/bin/sh curDir=`pwd` cd $2 git-checkout $1 cp -R $3/* $4 cd $curDir

Aquí el primer argumento es la bifurcación para pagar, el segundo - la carpeta donde el bono está actualmente presente, el tercero - el subdirectorio que realmente quiere usar, y el cuarto - la ubicación en la que desea que se copie.

Advertencia: mis habilidades de shell son casi inexistentes, así que utilízalo después de la prueba. No debería ser difícil volver a crear el reverso de este script, que copia cosas atrás, para que pueda ser comprometido con el repositorio.


La respuesta corta es no. Git ve todos los archivos como una sola unidad.

Lo que recomiendo es que desgloses tus repositorios en pedazos lógicos. Una separada para perl, imágenes y documentos. Si también necesita mantener el estilo uber repo, puede crear un repositorio compuesto por Submodules .



Parece que lo que intenta hacer es cambiar el nombre del árbol de directorios para que sus archivos terminen en un lugar diferente. Me parece que lo que está pidiendo hacer es una anti-plantilla para la administración de código / proyecto en dos aspectos: categorización de módulos (bits Java bajo el nodo Java, Perl en el nodo perl) y tener un proyecto con archivos en diferentes ubicaciones desde donde el desarrollador los visualiza. Dado que git mantiene hashes de los contenidos del directorio para ver qué se cambia, esto también rompe a git como tal.

Daemeon Reiydelle



Todavía necesita clonar todo el repositorio, que tendrá todos los archivos. Puede usar el indicador --depth para recuperar solo una cantidad limitada de historial.

Una vez que se clona el repositorio, el truco del árbol de lectura limita su "vista" del repositorio a solo aquellos archivos o directorios que se encuentran en el archivo .git/info/sparse-checkout .

Escribí un guión rápido para ayudar a manejar la escasez, ya que por el momento es un poco antipático:

#!/bin/sh echo > .git/info/sparse-checkout for i in "$@" do echo "$i" >> .git/info/sparse-checkout done git read-tree -m -u HEAD

Si guarda esta secuencia de comandos como git-sparse.sh en la ruta reportada al llamar a git --exec-path , entonces puede ejecutar git sparse foo/ bar/ para solo "verificar" los directorios foo y bar, o git sparse ''*'' para recuperar todo de nuevo.


git filter-branch --subdirectory-filter es lo que necesita, vea Detach (move) subdirectory en un repositorio separado de Git .

Aquí hay un pequeño script bash para hacer eso.

Esto primero hará una copia de trabajo del repositorio original, luego filtrará la sucursal usando el filtro de subdirectorio para que obtenga lo que desea.

#!/bin/bash # # git-subdir.sh # git clone --no-hardlinks $1 $2 cd $2 git filter-branch --subdirectory-filter $2 --prune-empty --tag-name-filter cat HEAD -- --all git reset --hard git remote rm origin refbak=$(git for-each-ref --format="%(refname)" refs/original/) if [ -n "$refbak" ];then echo -n $refbak | xargs -n 1 git update-ref -d fi git reflog expire --expire=now --all git repack -ad git gc --aggressive --prune=now

Utilícelo para el ejemplo en la pregunta, git-subdir.sh repo perl funcionaría.