Cómo extraer un directorio específico con git

193

Tengo un proyecto con git, y solo quiero clonar o extraer un directorio específico, como myproject / javascript, como lo hace Subversion.
hacer algunos cambios, comprometerse y retroceder nuevamente.
¿Es posible?

pie azul
fuente
3
el pago escaso puede interesarle (a pesar de que aún necesita buscar todo): consulte stackoverflow.com/questions/2416815/…
VonC

Respuestas:

205
  1. cd en la parte superior de tu copia del repositorio
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Donde " path/..." en (3) comienza en el directorio justo debajo de la raíz del repositorio que contiene su " .../file"

    • TENGA EN CUENTA que en lugar de "HEAD", se puede usar el código hash de una confirmación específica, y luego obtendrá la revisión (archivo) o las revisiones (dir) específicas de esa confirmación.

Vergueishon
fuente
1
Me acabo de dar cuenta de que entendí mal la pregunta. En cambio, mi respuesta aborda cómo retirar un solo archivo, que luego puede modificarse y confirmarse.
vergueishon
Abordaste el título de la pregunta, que es lo suficientemente bueno. Esto me salvó, así que, en lo que a mí respecta, esta es la respuesta correcta, especialmente porque este fue un gran éxito en Google para este problema.
Morgon
21
Sin embargo, esto todavía obtiene todo el repositorio. Para un proyecto de 2GB de tamaño, esto no ahorra mucho tiempo ..
Pithikos
55
Para aquellos que leen estos comentarios y no saben cómo esto no responde la pregunta, lo que hace esta solución es darle una copia de esa carpeta, pero no es una copia de trabajo, lo que significa que no puede modificar y volver -cometer. Entonces, como dijo @Morgon, aborda el título de la pregunta (PUEDE extraer solo un directorio), pero no responde el cuerpo de la pregunta ("realice algunos cambios, comprométase y retroceda nuevamente").
msb
Sin --embargo, @StanHolodnak no es obligatorio. Obliga a los bits después de ser interpretados como una ruta. Entonces, sí, si tiene un archivo con el nombre --helpque desea retirar, se requerirá el prefijo con estos guiones:git checkout HEAD -- --help
Tim Visée
105

En un directorio vacío:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory
scottalan
fuente
esto funciona si solo quieres usar la versión remota de un archivo para reemplazar el archivo local, creo
John
Esto extrae la carpeta también, ¿cómo no descargar la carpeta, sino solo las cosas dentro de la carpeta?
Al Kasih
No hay ninguna necesidad fetcho checkoutcomandos, simplemente podemos hacer la solicitud de extracción después del remote addcomando para obtener toda la rama maestra.
Iqra
2
Como Pithkos señala en la respuesta aceptada, esta respuesta también descargará TODO el repositorio remoto a su máquina local. La respuesta de shingara es la más clara: no hay forma de extraer remotamente una parte de un repositorio. Sin embargo, para aquellos a quienes no les importa el ancho de banda de TODA la búsqueda y están interesados ​​en hacer una copia de trabajo de una parte de la memoria caché local, la respuesta aceptada les muestra cómo hacerlo. Pero solo quiero dejar en claro que todo el historial del repositorio (en formato comprimido) debe descargarse a su máquina.
Gabe Halsmer
39

Después de mucho buscar una respuesta, no encontrarla, rendirme, intentarlo de nuevo, etc., finalmente encontré una solución para esto en otro hilo SO:

Cómo git-pull todas las carpetas menos una

Para copiar y pegar lo que hay allí:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Para hacer lo que OP quiere (trabajar en un solo directorio), simplemente agregue ese directorio .git/info/sparse-checkoutal realizar los pasos anteriores.

¡Muchas, muchas gracias a @cforbish!

msb
fuente
2
Lo publico aquí principalmente porque cada vez que trato de buscar en Google cómo hacerlo, este es un resultado superior, y ese hilo ni siquiera está cerca de mostrarse. :( Me siento mal copiando, pero calculo que es SO mejores prácticas
msb
1
Esta es la única solución limpia. Intenté las respuestas anteriores. Después de revisar mi rama con las otras respuestas, no pude extraer, y tenía varios archivos nuevos que necesitaban confirmación. Con esta solución todo se ve bien. Pero NOTA: Independientemente de la rama que se haya extraído, git pensará que estás dentro master. Solo asegúrese de hacerlo git branch --set-upstream-to=origin/<branch>para tirar correctamente
seebiscuit
12

No es posible. Necesita extraer todo el repositorio o nada.

shingara
fuente
1
A pesar de que necesita buscar todo, ¿sería interesante un tirón en un árbol de trabajo de pago escaso en este caso? Ver stackoverflow.com/questions/2416815/…
VonC
10
Solo para agregar esto, la razón por la que no puede extraer solo un directorio es porque git usa el seguimiento semántico de datos, no el seguimiento semántico de archivos, por lo que puede mover sin problemas el código (u otros datos) dentro y fuera de los archivos sin tener que decir la fuente sistema de seguimiento (hasta que actualice, por supuesto). Debido a esto, el código también puede moverse dentro y fuera de los directorios sin problemas, por lo que tomar un solo directorio no tiene mucho sentido. Espero que esto ayude.
OmnipotentEntity
12
@OmnipotentEntity Lo siento, pero en mi humilde opinión, tiene sentido. La implementación no debería limitar el uso. Git sabe qué directorios son (al menos al crear una copia de trabajo local), por lo que no hay razón para que no pueda realizar una operación similar en el servidor y simplemente envíe la salida relevante. Por supuesto, eso no está implementado actualmente, pero se debe a la falta de una característica, no a una imposibilidad fundamental. Personalmente, creo que es una característica bastante importante, pero bueno, esa es una razón por la que evito git cuando es posible.
Básico
10

Quizás este comando pueda ser útil:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"Et voilà"

fabrice belle
fuente
2
Esto descarga un directorio específico de archivo para fines de archivo, no extrae una copia que pueda modificar y rechazar.
leetNightshade
Muy genial. Probablemente no sea aceptable como solución para el OP, pero en realidad es lo que buscaba, ya que solo necesito buscar el contenido de una carpeta grande en un repositorio aún más grande que definitivamente no quiero obtener, y no necesito modificar / empujar.
Oliver
7

Si desea obtener los últimos cambios en un directorio sin ingresarlo, puede hacer lo siguiente:

$ git -C <Path to directory> pull
feralamillo
fuente
4

git clone --filter de Git 2.19

Esta opción realmente omitirá la búsqueda de objetos innecesarios del servidor.

He escrito una respuesta detallada que explica el estado actual de soporte en: ¿Cómo clono un subdirectorio solo de un repositorio Git?

Es muy probable que todo lo que se implemente git cloneen esa área también tenga git pullanálogos.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
1

Probado y probado esto funciona!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

¡Espero que esto haya sido útil!

Nnaik
fuente
0

A veces, solo desea echar un vistazo a las copias anteriores de archivos sin la rigurosa rutina de pasar por los diffs.

En tal caso, es igual de fácil hacer un clon de un repositorio y verificar la confirmación específica que le interesa y echar un vistazo al subdirectorio en ese repositorio clonado. Como todo es local, puede eliminar este clon cuando haya terminado.

Abizern
fuente
-1

Para toda esa lucha con rutas de archivos teóricas y ejemplos como lo hice aquí, aquí un ejemplo del mundo real: Microsoft ofrece sus documentos y ejemplos en git hub, desafortunadamente reúnen todos sus archivos de ejemplo para una gran cantidad de temas en este repositorio:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Solo estaba interesado en los archivos js de Microsoft Dynamics en la ruta

msdn-code-gallery-community-s-z/Sdk.Soap.js/

entonces hice lo siguiente

crear un

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

archivo en mi carpeta de repositorios en el disco

git sparse-checkout init

en ese directorio usando cmd en windows

El contenido del archivo de

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

es

Sdk.Soap.js/*

finalmente hacer un

git pull origin master
DM
fuente