¿Es posible hacer un pago escaso sin consultar primero todo el repositorio?

171

Estoy trabajando con un repositorio con una gran cantidad de archivos que demora horas en pagar. Estoy investigando la posibilidad de que Git funcione bien con este tipo de repositorio ahora que admite pagos escasos, pero cada ejemplo que puedo encontrar hace lo siguiente:

git clone <path>
git config core.sparsecheckout true
echo <dir> > .git/info/sparse-checkout
git read-tree -m -u HEAD

El problema con esta secuencia de comandos es que el clon original también realiza un pago. Si agrega -n al comando de clonación original, el comando read-tree produce el siguiente error:

error: el pago escaso no deja ninguna entrada en el directorio de trabajo

¿Cómo puede hacer el pago escaso sin revisar primero todos los archivos?

dromodel
fuente
Nota: git worktree add --no-checkouttambién funcionará (no solo git clone --no-checkout) con git 2.9 (solo 2016). Vea mi respuesta a continuación
VonC
Después de probar todas las soluciones aquí, la única que simplemente descarga el directorio (¡sin presionar después!) Es esta .
LondonRob

Respuestas:

24

En 2020 hay una forma más sencilla de lidiar con el pago escaso sin tener que preocuparse por los archivos .git. Así es como lo hice:

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

Tenga en cuenta que requiere la versión 2.25 de git instalada. Lea más sobre esto aquí: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

ACTUALIZAR:

El git clonecomando anterior seguirá clonando el repositorio con su historial completo, aunque sin retirar los archivos. Si no necesita el historial completo, puede agregar el parámetro --depth al comando, así:

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1
Alexey Grinko
fuente
1
Eso es cierto, buen punto. Votado Seguí la sparse-checkout --conefunción en stackoverflow.com/a/59515426/6309
VonC
Valdría la pena agregar clon parcial ( --filter) a su respuesta aquí.
Tao
@ alexey-grinko, el primer comando aún tenía que clonar todo el repositorio en cuestión, incluso si no lo comprobaba ... Estaba buscando ahorrar el tiempo de no clonar todas las cosas que no necesito ... .
mropp
1
@mropp, actualicé la respuesta agregando un --depthparámetro que nos permite hacer un clon superficial. ¿Eso ayudará? @Tao, no estoy seguro de cómo usarlo --filteren este caso, no lo intenté. ¿Podría dar un ejemplo o publicar otra respuesta a este tema?
Alexey Grinko
44
Tenga en cuenta que no funciona igual en la versión 2.27, no sé por qué.
Resplandores
162

Tenga en cuenta que esta respuesta descarga una copia completa de los datos de un repositorio. El git remote add -fcomando clonará todo el repositorio. De la página del manual degit-remote :

Con la -fopción, git fetch <name>se ejecuta inmediatamente después de configurar la información remota.


Prueba esto:

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add -f origin git://...
echo "path/within_repo/to/desired_subdir/*" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

Ahora encontrará que tiene un pago "podado" con solo archivos de la ruta / inside_repo / to / desired_subdir presentes (y en esa ruta).

Tenga en cuenta que en la línea de comandos de Windows no debe citar la ruta, es decir, debe cambiar el sexto comando con este:

echo path/within_repo/to/desired_subdir/* > .git/info/sparse-checkout

si no lo hace, obtendrá las cotizaciones en el archivo de pago escaso, y no funcionará

Apenwarr
fuente
3
No puedo usar el comando "git checkout [nombre de sucursal]" (también se encontró un error: el pago escaso no deja ninguna entrada en el directorio de trabajo). He usado "git pull origin master" y funciona correctamente.
Natty
2
Con git versión 1.7.2.5 en linux, obtuve los siguientes resultados: echo 'dir / *' verifica solo los archivos en dir / pero no en sus subdirectorios; echo 'dir /' (¡sin asterisco!) desprotege correctamente todo el árbol bajo dir /. HTH
pavek
37
Esto simplemente no funcionó para mí: el comando "git remote" resultó en la verificación del repositorio completo - ¡bam! - en ese mismo momento; entonces la "configuración de git ..." y la especificación de un subdirectorio de interés en los siguientes comandos no tuvieron efecto. ¿La URL de repositorio especificada en el comando "git remote" es solo la ruta al archivo .git de nivel superior? ¿O debería ser un camino hacia el subdirectorio de interés?
Rob Cranfill
10
Aquí hay una versión simplificada (no es necesario crear manualmente el directorio, hacer un inicio y agregar remotamente, solo haga el ciclo normal de git clone + checkout con la opción --no-checkout como lo menciona @onionjake): git clone --no-checkout <project> cd <project> echo <dir>> .git / info / sparse-checkout git checkout <branch>
Gregor
22
El git remote addcomando descarga todo porque eso es lo que -fhace: le dice que busque inmediatamente, antes de que haya definido las opciones de pago escaso. Pero omitir o reordenar eso no va a ayudar. Los pagos escasos solo afectan al árbol de trabajo, no al repositorio. Si desea que su repositorio siga una dieta, entonces debe mirar las opciones --deptho en su --single-branchlugar.
Miral
43

Git Clone tiene una opción ( --no-checkouto -n) que hace lo que quieres.

En su lista de comandos, simplemente cambie:

git clone <path>

A esto:

git clone --no-checkout <path>

A continuación, puede usar el pago escaso como se indica en la pregunta.

cebolla
fuente
77
Sí, no hace un pago, pero aún así una zona de alcance para descargar toda la historia de recompra
Jason S
9
@JasonS la pregunta fue específicamente sobre no hacer un pago. Si no lo desea, puede usar el historial completo de la --depth <depth>opción en git clone. Eso solo descargará los últimos <depth>commits del historial. Actualmente no hay forma de descargar parcialmente un solo commit con git, aunque si su control remoto lo admite, puede usarlo git archive --remotepara descargar conjuntos parciales de archivos.
onionjake
Ahora también puede 'verificar' una confirmación sin descargar ningún archivo usando vfsforgit.org . Esto podría ser útil si alguien está tratando de pagar solo un pequeño subconjunto de una sola confirmación.
onionjake
22

Tuve un caso de uso similar, excepto que quería verificar solo el commit para una etiqueta y podar los directorios. El uso lo --depth 1hace muy escaso y realmente puede acelerar las cosas.

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add origin <url>  # Note: no -f option
echo "path/within_repo/to/subdir/" > .git/info/sparse-checkout
git fetch --depth 1 origin tag <tagname>
git checkout <tagname>
fuentedelica
fuente
3
- la profundidad 1 se llama un clon superficial, solo para su información.
Mark Allison
1
Esto ayudó! Gracias
kp123
1
Gracias por esto. Lo entendí bien después de probar muchas otras formas de evitar la descarga de todo el repositorio.
J ... S
12

Encontré la respuesta que estaba buscando en el one-liner publicado anteriormente por pavek (¡gracias!), Así que quería proporcionar una respuesta completa en una sola respuesta que funcione en Linux (GIT 1.7.1):

1--> mkdir myrepo
2--> cd myrepo
3--> git init
4--> git config core.sparseCheckout true
5--> echo 'path/to/subdir/' > .git/info/sparse-checkout
6--> git remote add -f origin ssh://...
7--> git pull origin master

Cambié un poco el orden de los comandos, pero eso no parece tener ningún impacto. La clave es la presencia de la barra diagonal "/" al final de la ruta en el paso 5.

JF Bergeron
fuente
3
¿Estás seguro de que esto es lo que quieres? the -f significa obtener todos los datos, aún obtienes toda la otra información que no deseas y es lenta. (Esto todavía está "revisando todo el repositorio")
Shuman
1
Intenté los pasos anteriores en Windows, pero el pago de repuesto no funciona en el símbolo del sistema, así que probé el shell Git Bash y funcionó. el símbolo del sistema puede ejecutar todos los comandos de git como push, pull, etc., pero cuando se trata de una comprobación escasa, falla.
user593029
Cómo hacer solo archivos del subdirectorio. Solo quiero buscar los archivos dentro de un subdirectorio específico.
Babish Shrestha
@BabishShrestha ver comentario de onionjake en otra respuesta FWIW: |
rogerdpack
9

Lamentablemente, nada de lo anterior funcionó para mí, así que pasé mucho tiempo probando diferentes combinaciones de sparse-checkoutarchivos.

En mi caso, quería omitir carpetas con configuraciones IntelliJ IDEA.

Aquí esta lo que hice:


correr git clone https://github.com/myaccount/myrepo.git --no-checkout

correr git config core.sparsecheckout true

Creado .git\info\sparse-checkoutcon el siguiente contenido

!.idea/*
!.idea_modules/*
/*

Ejecute 'git checkout -' para obtener todos los archivos.


Lo crítico para hacerlo funcionar fue agregar /*después del nombre de la carpeta.

Tengo git 1.9

experto
fuente
3
No, todavía descarga todo, todos los commits y todos los archivos, git 2.3.2
Tyguy7
66
Los pagos escasos solo afectan al árbol de trabajo. No afectan el tamaño del repositorio o lo que se obtiene. Necesita diferentes opciones si lo desea.
Miral
Pruebe Git Bash Shell la próxima vez si trabaja en Windows y use los pasos anteriores de 'pbetkier', funciona bien
user593029
6

Sí, es posible descargar una carpeta en lugar de descargar todo el repositorio. Incluso cualquier / último compromiso

Buena manera de hacer esto

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r HEAD solo descargará la última revisión, ignorará todo el historial.

  2. Nota troncal y / carpeta específica

Copie y cambie la URL antes y después /trunk/. Espero que esto ayude a alguien. Disfruta :)

Actualizado el 26 sep 2019

Qamar
fuente
solo aplicable para aquellos que vienen o usan svn. No votará este.
C Johnson
@CJohnson como puedes ver, estoy clonando la carpeta git repo. Funciona bien
Qamar el
1
Tenga en cuenta que esto no es algo que Git ofrece de fábrica, sino que es algo que Git Hub ofrece junto a la oferta regular de Git. Sin embargo, funciona de maravilla cuando puede utilizarlo. ¡Gracias!
Qix - MONICA FUE MALTRATADA el
1
De las innumerables sugerencias sobre SO, la suya es la solución más concisa y clara.
Boardrider
5

Respuesta actualizada 2020:

Ahora hay un comando git sparse-checkoutque presento en detalle con Git 2.25 (Q1 2020)

La respuesta de nicono ilustra su uso:

git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

Ha evolucionado con Git 2.27 y sabe cómo "volver a aplicar" un pago escaso, como aquí .
Tenga en cuenta que con Git 2.28, git statusmencionará que está en un repositorio escaso y desprotegido

Respuesta original: 2016

git 2.9 (junio de 2016) generalizará la --no-checkoutopción de git worktree add(el comando que permite trabajar con múltiples árboles de trabajo para un repositorio )

Ver commit ef2a0ac (29 de marzo de 2016) por Ray Zhang ( OneRaynyDay) .
Ayudado por: Eric Sunshine ( sunshineco) y Junio ​​C Hamano ( gitster) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 0d8683c , 13 abr 2016)

La git worktreepágina del manual ahora incluye:

--[no-]checkout:

Por defecto, addlos cheques <branch>, sin embargo, --no-checkoutse pueden utilizar para reprimir la caja con el fin de realizar personalizaciones, como la configuración de escasa-checkout .

VonC
fuente
4

Pasos para escanear solo la carpeta específica:

1) git clone --no-checkout  <project clone url>  
2) cd <project folder>
3) git config core.sparsecheckout true   [You must do this]
4) echo "<path you want to sparce>/*" > .git/info/sparse-checkout
    [You must enter /* at the end of the path such that it will take all contents of that folder]
5) git checkout <branch name> [Ex: master]
SANDEEP MACHIRAJU
fuente
Para su información, en el primer (1) paso, no necesita usar --no-checkout. Simplemente clone todo el repositorio y luego ejecute todos los pasos 2-5 a continuación (mencionados anteriormente), obtendrá la salida que desea. Avísame si no lo entendiste.
SANDEEP MACHIRAJU
4

En base a esta respuesta de apenwarr y este comentario de Miral, se me ocurrió la siguiente solución que me ahorró casi el 94% del espacio en disco al clonar el repositorio de Linux git localmente mientras solo quería un subdirectorio de documentación:

$ cd linux
$ du -sh .git .
2.1G    .git
894M    .
$ du -sh 
2.9G    .
$ mkdir ../linux-sparse-test
$ cd ../linux-sparse-test
$ git init
Initialized empty Git repository in /…/linux-sparse-test/.git/
$ git config core.sparseCheckout true
$ git remote add origin ../linux
# Parameter "origin master" saves a tiny bit if there are other branches
$ git fetch --depth=1 origin master
remote: Enumerating objects: 65839, done.
remote: Counting objects: 100% (65839/65839), done.
remote: Compressing objects: 100% (61140/61140), done.
remote: Total 65839 (delta 6202), reused 22590 (delta 3703)
Receiving objects: 100% (65839/65839), 173.09 MiB | 10.05 MiB/s, done.
Resolving deltas: 100% (6202/6202), done.
From ../linux
 * branch              master     -> FETCH_HEAD
 * [new branch]        master     -> origin/master
$ echo "Documentation/hid/*" > .git/info/sparse-checkout
$ git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
$ ls -l
total 4
drwxr-xr-x 3 abe abe 4096 May  3 14:12 Documentation/
$  du -sh .git .
181M    .git
100K    .
$  du -sh
182M    .

Así que bajé de 2.9GB a 182MB, que ya es bastante agradable.

I, aunque no llegué a este trabajo con git clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test( insinuado aquí ) ya que entonces los archivos que faltan se añaden como todos los archivos eliminados en el índice. Entonces, si alguien sabe el equivalente de git clone --filter=blob:nonefor git fetch, probablemente podamos ahorrar más megabytes. (Leer la página del manual git-rev-listtambién sugiere que hay algo así --filter=sparse:path=…, pero tampoco conseguí que eso funcionara.

(Todos intentaron con git 2.20.1 de Debian Buster).

Axel Beckert
fuente
1
Comentarios interesantes Votado Yo tampoco lo sé --filter=sparse:path=….
VonC
3

Soy nuevo en git, pero parece que si hago el pago de git para cada directorio, entonces funciona. Además, el archivo de pago disperso debe tener una barra inclinada final después de cada directorio como se indica. Alguien con más experiencia confirma que esto funcionará.

Curiosamente, si desprotege un directorio que no está en el archivo de desagüe escaso, parece que no hay diferencia. No se muestran en estado git y git read-tree -m -u HEAD no hace que se elimine. git reset --hard tampoco hace que se elimine el directorio. ¿Alguien más experimentado se preocupa por comentar qué piensa git de los directorios que están desprotegidos pero que no están en el escaso archivo de pago?

dromodel
fuente
1

En git 2.27, parece que git sparse checkout ha evolucionado. La solución en esta respuesta no funciona exactamente de la misma manera (en comparación con git 2.25)

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

Estos comandos funcionaron mejor:

git clone --sparse <URL> <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

Ver también: git-clone --sparse y git-sparse-checkout add

nicono
fuente
1
Buena actualización Votado He editado mi propia respuesta en consecuencia. He presentado ese comando en diciembre de 2019: stackoverflow.com/a/59515426/6309
VonC hace
0

En mi caso, quiero omitir la Podscarpeta al clonar el proyecto. Lo hice paso a paso como a continuación y funciona para mí. Espero eso ayude.

mkdir my_folder
cd my_folder
git init
git remote add origin -f <URL>
git config core.sparseCheckout true 
echo '!Pods/*\n/*' > .git/info/sparse-checkout
git pull origin master

Memo, si desea omitir más carpetas, simplemente agregue más líneas en el archivo de pago escaso.

eric largo
fuente