Cómo hacer poco profundas submódulos de git?
-
23-09-2019 - |
Pregunta
Es posible tener superficial submódulos?Tengo un superproject con varios submódulos, cada uno con una larga historia, así que es innecesariamente grande arrastrando todo lo que la historia.
Todos los que he encontrado es este hilo sin respuesta.
Debo hack git-submódulo para implementar esto?
Solución
De nuevo en la próxima git1.8.4 (julio de 2013):
"
git submodule update
"opcionalmente puede clonar el submódulo repositorios superficialmente.
(Y git 2.10 Q3 2016 permite grabar de que con git config -f .gitmodules submodule.<name>.shallow true
.
Ver el final de esta respuesta)
Ver cometer 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f:
Agregar el
--depth
opción para agregar y actualizar los comandos de "git submódulo", que se transmite luego a el clon de comandos.Esto es útil cuando el submódulo(s) son enormes y no está realmente interesado en cualquier cosa, pero el último commit.Las pruebas son añadidas y algunas sangría se realizaron los ajustes para cumplir con el resto de la prueba en "submódulo de actualización puede manejar enlaces simbólicos en pwd".
Firmada por:Fredrik Gustafsson
<iveqy@iveqy.com>
Acked por:Jens Lehmann<Jens.Lehmann@web.de>
Que significa esto funciona:
git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]
Con:
--depth::
Esta opción es válida para
add
yupdate
los comandos.
Crear una 'profunda' clon con una historia trunca el número especificado de revisiones.
atwyman agrega en los comentarios:
Como lo que puedo decir que esta opción no es utilizable para submódulos que no hacen un seguimiento de
master
muy de cerca.Si establece el nivel de profundidad 1, entoncessubmodule update
sólo puede tener éxito si el submódulo cometer desea es el último maestro. De lo contrario, usted consigue "fatal: reference is not a tree
".
Que es cierto.
Es decir, hasta git 2.8 (Marzo de 2016).Con 2.8, el submodule update --depth
tiene una oportunidad más para tener éxito, incluso si el SHA1 es directamente accesible desde uno de los remotos repo Cabezas.
Ver cometer fb43e31 (24 de Febrero de 2016) por Stefan Beller (stefanbeller
).
Contribuido por: Junio C Hamano (gitster
).
(Fusionado por Junio C Hamano -- gitster
-- en cometer 9671a76, 26 de Febrero de 2016)
submódulo:esforzarse más para recuperar necesario sha1 directa de la captura sha1
Al revisar un cambio que también las actualizaciones de un submódulo de Gerrit, una revisión de la práctica es la descarga y cherry-pick y el parche de forma local para probarlo.
Sin embargo, cuando las pruebas a nivel local, la 'git submodule update
'puede fallar a que la obtención de la correcta submódulo sha1 como la confirmación correspondiente en el submódulo aún no es parte de la historia del proyecto, pero también una propuesta de cambio.Si
$sha1
no era parte de la predeterminada fetch, tratamos de recuperar la$sha1
directamente.Algunos servidores, sin embargo no apoyo directo de captura por sha1, que llevagit-fetch
a fallar rápidamente.
Podemos fallar a nosotros mismos aquí como los que aún faltan sha1 llevaría a un fracaso más tarde, en el momento de pago de todos modos, por lo que falla aquí es tan buena como la que podemos obtener.
MVG señala en los comentarios a cometer fb43e31 (git 2.9, Feb 2016)
Me parece que cometer fb43e31 las solicitudes de la falta de comprometerse por SHA1 id, por lo que el
uploadpack.allowReachableSHA1InWant
yuploadpack.allowTipSHA1InWant
la configuración en el servidor afectará probablemente si esto funciona.
Escribí un post para el git de la lista de hoy, señalando cómo el uso de poco submódulos podría ser mejor para algunos escenarios, es decir, si la confirmación es también una etiqueta.
Vamos a esperar y ver.Supongo que esta es una razón por la que fb43e31 hecho la captura de un determinado SHA1 un retroceso después de la captura de la rama predeterminada.
Sin embargo, en el caso de "--profundidad 1", creo que tendría sentido para abortar principios:si ninguno de la lista de árbitros coincide con la solicitada, y preguntando por SHA1 no es soportada por el servidor, entonces no hay ningún punto en la obtención de nada, ya que no será capaz de satisfacer el submódulo requisito de cualquier manera.
La actualización de agosto de 2016 (3 años después)
Con Git 2.10 (Q3 2016), usted será capaz de hacer
git config -f .gitmodules submodule.<name>.shallow true
Ver "Git submódulo sin peso extra"por más.
Git 2.13 (Q2 2017) añade en cometer 8d3047c (19 Abr 2017) por Sebastián Schuberth (sschuberth
).
(Fusionado por Sebastián Schuberth -- sschuberth
-- en cometer 8d3047c, 20 de Abr de 2017)
un clon de este submódulo se realiza como un poco clon (con una historia profundidad de 1)
Sin embargo, Ciro Santilli agrega en los comentarios (y detalles en su respuesta)
shallow = true
en.gitmodules
sólo afecta a la referencia de seguimiento por el JEFE del mando a distancia cuando utilice--recurse-submodules
, incluso si el objetivo de cometer es señalado por una rama, e incluso si usted ponebranch = mybranch
en el.gitmodules
así.
Git 2.20 (T4 2018) mejora en el submódulo de apoyo, el cual ha sido actualizado para leer la nota en HEAD:.gitmodules
cuando el .gitmodules
falta el archivo desde el árbol de trabajo.
Ver cometer 2b1257e, cometer 76e9bdc (25 de Octubre de 2018), y cometer b5c259f, cometer 23dd8f5, cometer b2faad4, cometer 2502ffc, cometer 996df4d, cometer d1b13df, cometer 45f5ef3, cometer bcbc780 (05 de Octubre de 2018) por Antonio Ospite (ao2
).
(Fusionado por Junio C Hamano -- gitster
-- en cometer abb4824, 13 de Noviembre de 2018)
submodule
:apoyo a la lectura.gitmodules
cuando no está en el árbol de trabajoCuando el
.gitmodules
archivo no está disponible en el árbol de trabajo, trate de utilizando el contenido del índice y de la rama actual.
Este cubre el caso cuando el archivo es parte del repositorio, pero para algunos razón por la que no está desprotegido, por ejemplo, debido a una escasa checkout.Esto hace posible el uso de al menos el '
git submodule
'comandos que leer elgitmodules
archivo de configuración sin rellenar completamente el árbol de trabajo.Escrito
.gitmodules
se requiere que el archivo está desprotegido, para comprobar que antes de llamarconfig_set_in_gitmodules_file_gently
.Añadir un similar comprobar también en
git-submodule.sh::cmd_add()
para anticipar el eventual fracaso de la "git submodule add
"comando cuando.gitmodules
no está segura de escritura;esto evita que el comando salir del repositorio en un falso estado (por ejemplo,el submódulo repositorio clonado pero.gitmodules
no fue actualizada, porqueconfig_set_in_gitmodules_file_gently
no se pudo).Por otra parte, desde
config_from_gitmodules()
ahora accede al objeto global de la tienda, es necesario para proteger a todas las rutas de código que llame a la función contra el acceso simultáneo a la de objeto global de la tienda.
En la actualidad esto sólo sucede enbuiltin/grep.c::grep_submodules()
, así que llamegrep_read_lock()
antes de invocar el código que implicanconfig_from_gitmodules()
.NOTA:hay un raro caso en el que esta nueva característica no funciona correctamente:anidado submódulos sin
.gitmodules
en su árbol de trabajo.
Otros consejos
2.9.0 apoyo clon submódulos poco profunda directamente, por lo que ahora sólo puede llamar a:
git clone url://to/source/repository --recursive --shallow-submodules
Tras la respuesta de Ryan yo era capaz de subir con este sencillo script que itera a través de todos submódulos y clones poco profundas ellos:
#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
spath=$(git config -f .gitmodules --get submodule.$i.path)
surl=$(git config -f .gitmodules --get submodule.$i.url)
git clone --depth 1 $surl $spath
done
git submodule update
Lectura a través del git-submódulo "fuente", parece que puede manejar git submodule add
submódulos que ya tienen sus repositorios presente. En ese caso ...
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...
Usted querrá asegurarse de que la requerida comprometer está en el repositorio submódulo, por lo que asegúrese de que establece una --depth apropiado.
Editar: Usted puede ser capaz de salirse con múltiples clones submódulo manuales seguido de una sola actualización:
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update
Resumen de cochecito / comportamiento inesperado / molesto como de Git 2.14.1
-
shallow = true
en.gitmodules
sólo afectagit clone --recurse-submodules
si elHEAD
de los puntos submódulo remotos a la requerida cometió, incluso si el objetivo cometer es apuntado por una rama, e incluso si se ponebranch = mybranch
en el.gitmodules
también.script de prueba local . Mismo comportamiento en GitHub 2017-11, donde
HEAD
es controlado por el ajuste de recompra rama por defecto:git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow cd test-shallow-submodule-top-branch-shallow/mod git log # Multiple commits, not shallow.
-
git clone --recurse-submodules --shallow-submodules
falla si la confirmación se hace referencia ni por una rama o una etiqueta con un mensaje:.error: Server does not allow request for unadvertised object
script de prueba local . Mismo comportamiento en GitHub:
git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha # error
También preguntó sobre la lista de correo: https://marc.info/?l = git & m = 151863590026582 & w = 2 y la respuesta fue:
En teoría, esto debería ser fácil. :)
En la práctica no tanto, por desgracia. Esto se debe a que la clonación se acaba de obtener la última punta de una rama (normalmente maestro). No existe un mecanismo en el clon para especificar el sha1 exacta que se desea.
Los soportes de protocolo de alambre por preguntar sha1s exactas, de manera que debe ser cubierto. (Advertencia: sólo funciona si el operador del servidor permite uploadpack.allowReachableSHA1InWant que github tiene no AFAICT)
git-fetch permite a buscar sha1 arbitraria, así como una solución puede ejecutar una zona de alcance después de la clonación recursiva mediante el uso de "actualización submódulo git" como que usar recuperaciones después de la clonación inicial.
Prueba de TODO:. allowReachableSHA1InWant
Son canónica de la ubicación de los submódulos remoto?Si es así, ¿estás bien con la clonación de ellos de una vez?En otras palabras, ¿quieres que la poca profundidad de los clones sólo porque usted está sufriendo el desperdicio de ancho de banda de frecuencia de submódulo (re)en los clones?
Si desea superficial clones para ahorrar espacio en disco local, luego Ryan Graham respuesta parece una buena manera de ir.Manualmente clon de los repositorios por lo que son poco profundas.Si usted piensa que podría ser útil, adaptar git submodule
para que la apoyen.Enviar un correo electrónico a la lista preguntar al respecto (asesoramiento para su aplicación, sugerencias sobre la interfaz, etc.).En mi opinión, la gente de allí son bastante apoyo de los potenciales contribuyentes que sinceramente quieren mejorar Git de manera constructiva.
Si usted está bien con la realización de una completa clon de cada submódulo (más tarde capturas para mantenerlos al día), puede intentar usar el --reference
opción de git submodule update
(es en Git 1.6.4 y posterior) para referirse a un local de almacenes de objetos (por ejemplo,hacer --mirror
los clones de la canónica submódulo repositorios, a continuación, utilizar --reference
en su submódulos para señalar a estos locales de los clones).Sólo asegúrese de leer acerca de git clone --reference
/git clone --shared
antes de usar --reference
.La única posibilidad problema con hacer referencia a los espejos sería si alguna vez terminan yendo a buscar no-avance rápido de actualizaciones (aunque podría habilitar reflogs y ampliar su vencimiento de windows para ayudar a retener cualquier abandonado compromete a que puede causar un problema).Usted no debería tener ningún problema siempre y cuando
- no hacen ningún local submódulo se compromete, o
- cualquier cometa que quedan colgando por no avanza que la canónica de repositorios puede publicar no son los antepasados de su local submódulo se compromete, o
- usted es diligente en mantener su local submódulo se compromete reajustado en la parte superior de lo que no avanza podrían ser publicados en la canónica submódulo de los repositorios.
Si vas con algo como esto y no hay ninguna posibilidad de que usted podría llevar submódulo se compromete en su trabajo árboles, probablemente sería una buena idea crear un sistema automatizado que asegura crítica de los objetos referenciados por la desprotegido submódulos que no se quede colgando en el espejo de los repositorios (y si encuentra alguno, copias de ellas a los repositorios que los necesita).
Y, como el git clone
manual dice, no utilice --reference
si usted no entiende estas implicaciones.
# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git
# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super
# To avoid extra packs in each of the superprojects' submodules,
# update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done
cd super
git pull # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
# but no download since they reference the updated mirrors
Como alternativa, en lugar de --reference
, usted podría utilizar el espejo de los clones en combinación con el defecto de hardlinking la funcionalidad de git clone
por el uso de locales de espejos como el origen de su submódulos.En el nuevo super-proyecto de clones, hacer git submodule init
, editar el submódulo Url en .git/config
a punto para el local de espejos, a continuación, hacer git submodule update
.Usted tendría que reclone existentes desprotegido submódulos para obtener los enlaces permanentes.Usted podría ahorrar ancho de banda descargando sólo una vez en los espejos, luego ir a local de aquellos que en su desprotegido submódulos.La difícil vinculación permitiría ahorrar espacio en el disco (aunque recupera tienden a acumularse y ser duplicada a través de múltiples instancias de la desprotegido submódulos' almacenes de objetos;periódicamente reclone el check-out submódulos de los espejos para recuperar el espacio de disco de ahorro proporcionado por hardlinking).
I creó una versión ligeramente diferente, ya que cuando no se está ejecutando en el borde de la sangría, que no todos los proyectos hacen. Las adiciones submódulo estándar did't trabajo ni tampoco la secuencia de comandos. Por lo que añade una búsqueda de hash que el árbitro etiqueta, y si no lo tiene, se cae de nuevo a plena clon.
#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
spath=$(git config -f .gitmodules --get submodule.$name.path)
surl=$(git config -f .gitmodules --get submodule.$name.url)
sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
if [ -z $sbr ]; then
git clone $surl $spath
else
git clone -b $sbr --depth 1 --single-branch $surl $spath
fi
done
git submodule update
Cómo clonar repositorio git con la revisión específica / conjunto de cambios?
He escrito un script sencillo que no tiene ningún problema cuando su referencia submódulo está lejos del maestro
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
Esta declaración será buscar la versión de referencia del submódulo.
Es rápido pero no se puede comprometer tu edición en el submódulo (que tiene a buscar unshallow antes https://stackoverflow.com / a / 17937889/3156509 )
en su totalidad:
#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive
clon superficial de un submódulo es perfecto porque instantánea en una revisión en particular / conjunto de cambios. Es fácil de descargar una postal de la página web, así que traté de una secuencia de comandos.
#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
mysha=${value%:*}
mysub=${value#*:}
myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
mydir=$(dirname $mysub)
wget $myurl/archive/$mysha.zip
unzip $mysha.zip -d $mydir
test -d $mysub && rm -rf $mysub
mv $mydir/*-$mysha $mysub
rm $mysha.zip
done
git submodule init
git submodule deinit --all -f
despeja el árbol submódulo que permite que el guión sea reutilizable.
git submodule
recupera la sha1 40 Char seguido por un camino que corresponde a la misma en .gitmodules
. Utilizo Perl para concatenar esta información, delimitado por dos puntos, a continuación, emplean transformación variable para separar los valores en mysha
y mysub
.
Estas son las claves críticos porque necesitamos el sha1 de descarga y el camino para correlacionar la url
en .gitmodules.
Dada una entrada submódulo típico:
[submodule "label"]
path = localpath
url = https://github.com/repository.git
llaves myurl
en path =
luego mira 2 líneas después de obtener el valor. Este método no puede trabajar de forma constante y requieren refinamiento. El grep url tiras de cualquier referencia de tipo .git
restantes de juego para el último /
y cualquier cosa hasta un .
.
mydir
es mysub
menos un /name
final que lo haría por el directorio líder hasta el nombre submódulo.
El siguiente es un wget
con el formato de archivo zip descargable url. Esto puede cambiar en el futuro.
Descomprimir el archivo en mydir
lo que sería el subdirectorio especifica en la ruta submódulo. La carpeta resultante será el último elemento de la url
-sha1
.
Compruebe si existe el subdirectorio especificado en la ruta submódulo y retirarlo para permitir el cambio de nombre de la carpeta extraída.
mv
cambiar el nombre del extrae carpeta que contiene nuestra sha1 a su trayectoria submódulo correcta.
Borrar el archivo zip descargado.
submódulo init
Esto es más una prueba de concepto de trabajo en curso en lugar de una solución. Cuando funciona, el resultado es un clon superficial de un submódulo a un conjunto de cambios especificado.
Debería el repositorio de volver a casa un sub-módulo a otro cometen, vuelva a ejecutar la secuencia de comandos de actualización.
La única vez que un guión como este sería útil es para la construcción local no colaboración de un proyecto de código.