Pregunta ¿Cómo puedo clonar un subdirectorio solo de un repositorio de Git?


Tengo mi repositorio de Git que, en la raíz, tiene dos subdirectorios:

/finisht
/static

Cuando esto estaba en SVN, /finisht fue verificado en un solo lugar, mientras /static fue revisado en otro lugar, así:

svn co svn+ssh://admin@domain.com/home/admin/repos/finisht/static static

¿Hay alguna manera de hacer esto con Git?


999
2018-03-01 16:46


origen


Respuestas:


Esta respuesta está desactualizada y solo se aplica a las versiones de GIT inferiores a 1.7.0 (febrero de 2012). Vea a continuación las versiones más recientes.

No, eso no es posible en Git.

Implementar algo como esto en Git sería un esfuerzo sustancial y significaría que ya no se puede garantizar la integridad del repositorio del cliente. Si está interesado, busque discusiones sobre "clonación dispersa" y "búsqueda escasa" en la lista de correo git.

En general, el consenso en la comunidad de Git es que si tiene varios directorios que siempre se revisan de forma independiente, estos son realmente dos proyectos diferentes y deben vivir en dos repositorios diferentes. Puedes pegarlos nuevamente usando Submódulos de Git.


421
2018-03-01 18:00



Lo que estás tratando de hacer se llama pago escasoy esa característica se agregó en git 1.7.0 (febrero de 2012). Los pasos para hacer un escaso clon son como sigue:

mkdir <repo>
cd <repo>
git init
git remote add -f origin <url>

Esto crea un repositorio vacío con su control remoto y recupera todos los objetos, pero no los revisa. Entonces hazlo:

git config core.sparseCheckout true

Ahora necesita definir qué archivos / carpetas quiere verificar realmente. Esto se hace al enumerarlos en .git/info/sparse-checkout, p.ej:

echo "some/dir/" >> .git/info/sparse-checkout
echo "another/sub/tree" >> .git/info/sparse-checkout

Por último, actualice su repositorio vacío con el estado desde el control remoto:

git pull origin master

Ahora tendrá los archivos "desprotegidos" para some/dir y another/sub/tree en su sistema de archivos (con esas rutas todavía), y no hay otras rutas presentes.

Es posible que desee echar un vistazo a la tutorial extendido y probablemente deberías leer el oficial documentación para el pago escaso.

Como una función:

function git_sparse_clone() (
  rurl="$1" localdir="$2" && shift 2

  mkdir -p "$localdir"
  cd "$localdir"

  git init
  git remote add -f origin "$rurl"

  git config core.sparseCheckout true

  # Loops over remaining args
  for i; do
    echo "$i" >> .git/info/sparse-checkout
  done

  git pull origin master
)

Uso:

git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin"

Tenga en cuenta que esto descargará todo el repositorio del servidor, solo se reduce el tamaño de la caja. Por el momento, no es posible clonar solo un directorio. Pero si no necesita el historial del repositorio, al menos puede ahorrar ancho de banda creando un clon superficial. Ver La respuesta de udondan a continuación para obtener información sobre cómo combinar aguas poco profundas clon y escaso checkout.


1347
2017-12-06 07:37



Puedes combinar el pago escaso y el clon superficial caracteristicas. los clon superficial corta la historia y el pago escaso solo saca los archivos que coinciden con sus patrones.

git init <repo>
cd <repo>
git remote add origin <url>
git config core.sparsecheckout true
echo "finisht/*" >> .git/info/sparse-checkout
git pull --depth=1 origin master

Necesitarás un git mínimo de 1.9 para que esto funcione. Lo probé solo con 2.2.0 y 2.2.2.

De esta manera, todavía podrá empujar, que no es posible con git archive.


325
2018-01-20 07:33



Para otros usuarios que solo quiero descargar un archivo / carpeta de github, simplemente use:

svn export <repo>/trunk/<folder>

p.ej.

svn export https://github.com/lodash/lodash.com/trunk/docs

(Sí, eso es svn aquí. Aparentemente en 2016 todavía necesitas svn simplemente descargar algunos archivos github)

Cortesía: Descargue una sola carpeta o directorio de un repositorio de GitHub 

Importante - Asegúrate de actualizar la URL de github y reemplazar /tree/master/ con '/ trunk /'.

Como script bash:

git-download(){
    folder=${@/tree\/master/trunk}
    folder=${folder/blob\/master/trunk}
    svn export $folder
}

Nota Este método descarga una carpeta, no la clona ni la comprueba. No puede enviar los cambios al repositorio. Por otro lado, esto se traduce en una descarga más pequeña en comparación con el pago escaso o el pago superficial.


77
2017-09-04 13:02



Git 1.7.0 tiene "salidas dispersas". Ver "Core.sparseCheckout" en el git config página de manual, "Pago escaso" en el git read-tree página de manualy "Bit del salto de trabajo" en el git update-index página de manual.

La interfaz no es tan conveniente como SVN (por ejemplo, no hay forma de hacer una salida dispersa en el momento de un clon inicial), pero la funcionalidad base sobre la cual se podrían construir las interfaces más simples ahora está disponible.


63
2018-05-18 21:15



Si nunca planeas interactuar con el repositorio desde el que clonaste, puedes hacer un completo git clone y reescribe tu repositorio usando git filter-branch --subdirectory-filter. De esta manera, al menos la historia será preservada.


60
2018-03-01 21:17



Esta parece mucho más simple:

git archive --remote=<repo_url> <branch> <path> | tar xvf -

60
2017-09-10 17:03



No es posible clonar el subdirectorio solo con Git, pero a continuación hay algunas soluciones.

Filtrar rama

Es posible que desee volver a escribir el repositorio para que parezca trunk/public_html/ había sido su raíz de proyecto, y descartaba toda la otra historia (usando filter-branch), prueba ya la rama de pago y envío:

git filter-branch --subdirectory-filter trunk/public_html -- --all

Notas: El -- que separa las opciones de la rama de filtro de las opciones de revisión, y --all para volver a escribir todas las ramas y etiquetas. Toda la información, incluidos los tiempos de confirmación originales o la información de fusión, será Preservado. Este comando honra .git/info/grafts archivo y refs en el refs/replace/ espacio de nombres, por lo que si tiene injertos o reemplazo refs definido, ejecutar este comando los hará permanentes.

¡Advertencia! El historial reescrito tendrá diferentes nombres de objetos para todos los objetos y no convergerá con la rama original. No podrá empujar y distribuir fácilmente la rama reescrita en la parte superior de la rama original. No utilice este comando si no conoce todas las implicaciones, y evite usarlo de todos modos, si una simple confirmación simple fuera suficiente para solucionar su problema.


Escaso pago

Aquí hay pasos simples con pago escaso enfoque que poblará escasamente el directorio de trabajo, por lo que puede decirle a Git qué carpeta (s) o archivo (s) en el directorio de trabajo vale la pena visitar.

  1. Repositorio de clones como de costumbre (--no-checkout es opcional):

    git clone --no-checkout git@foo/bar.git
    cd bar
    

    Puede omitir este paso, si ya ha clonado su repositorio.

    Sugerencia: para grandes repositorios, considere clon superficial (--depth 1) para pagar solo la última revisión y / o --single-branch solamente.


22
2018-03-22 23:06



yo solo escribió un guión para GitHub.

Uso:

python get_git_sub_dir.py path/to/sub/dir <RECURSIVE>

11
2018-01-23 18:49