¿Cómo hacer submódulos git poco profundos?

139

¿Es posible tener submódulos poco profundos? Tengo un superproyecto con varios submódulos, cada uno con una larga historia, por lo que se vuelve innecesariamente grande arrastrando toda esa historia.

Todo lo que he encontrado es este hilo sin respuesta .

¿Debería hackear git-submodule para implementar esto?

Mauricio Scheffer
fuente
1
" git submodule add/update" ahora puede clonar los repositorios de submódulos superficialmente. Vea mi respuesta a continuación
VonC

Respuestas:

133

Nuevo en el próximo git1.8.4 (julio de 2013) :

" git submodule update" opcionalmente puede clonar los repositorios de submódulos poco profundos.

(Y git 2.10 Q3 2016 permite grabar eso con git config -f .gitmodules submodule.<name>.shallow true.
Ver el final de esta respuesta)

Ver commit 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :

Agregue la --depthopción a los comandos agregar y actualizar de "git submodule", que luego se pasa al comando clonar. Esto es útil cuando los submódulos son enormes y no estás realmente interesado en nada más que la última confirmación.

Se agregaron pruebas y se hicieron algunos ajustes de sangría para ajustarse al resto del archivo de prueba en "la actualización de submódulos puede manejar enlaces simbólicos en pwd".

Firmado por: Fredrik Gustafsson <[email protected]>
Acked: Jens Lehmann<[email protected]>

Eso significa que esto funciona:

git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]

Con:

--depth::

Esta opción es válida para addy updatecomandos.
Cree un clon 'superficial' con un historial truncado al número especificado de revisiones.


atwyman agrega en los comentarios :

Por lo que puedo decir, esta opción no es utilizable para submódulos que no siguen mastermuy de cerca. Si establece la profundidad 1, submodule updatesolo puede tener éxito si el compromiso de submódulo que desea es el último maestro. De lo contrario, obtienes " fatal: reference is not a tree" .

Eso es verdad.
Es decir, hasta git 2.8 (marzo de 2016). Con 2.8, submodule update --depthtiene una oportunidad más de tener éxito, incluso si se puede acceder directamente al SHA1 desde uno de los HEADs de repositorio remotos.

Ver commit fb43e31 (24 de febrero de 2016) por Stefan Beller ( stefanbeller) .
Ayudado por: Junio ​​C Hamano ( gitster) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 9671a76 , 26 de febrero de 2016)

submódulo: intente más difícil obtener sha1 necesario mediante la obtención directa de sha1

Al revisar un cambio que también actualiza un submódulo en Gerrit, una práctica de revisión común es descargar y seleccionar el parche localmente para probarlo.
Sin embargo, al probarlo localmente, ' git submodule update' puede fallar al buscar el submódulo sha1 correcto, ya que la confirmación correspondiente en el submódulo aún no es parte del historial del proyecto, sino que también es solo un cambio propuesto.

Si $sha1no formaba parte de la recuperación predeterminada, intentamos recuperarla $sha1directamente . Sin embargo, algunos servidores no admiten la búsqueda directa por sha1, lo que lleva git-fetcha fallar rápidamente.
Podemos fallar aquí, ya que el sha1 aún faltante llevaría a una falla más adelante en la etapa de pago de todos modos, por lo que fallar aquí es lo mejor que podemos obtener.


MVG señala en los comentarios para cometer fb43e31 (git 2.9, feb 2016)

Me parece que commit fb43e31 solicita el commit faltante por ID SHA1, por lo que la configuración uploadpack.allowReachableSHA1InWanty uploadpack.allowTipSHA1InWanten el servidor probablemente afectará si esto funciona.
Escribí una publicación en la lista de git hoy , señalando cómo se puede hacer que el uso de submódulos superficiales funcione mejor para algunos escenarios, es decir, si el commit también es una etiqueta.
Vamos a esperar y ver.

Supongo que esta es una razón por la cual fb43e31 hizo que la búsqueda de un SHA1 específico sea una alternativa después de la búsqueda de la rama predeterminada.
Sin embargo, en el caso de "--depth 1" creo que tendría sentido abortar antes de tiempo: si ninguna de las referencias enumeradas coincide con la solicitada, y el servidor no admite las preguntas de SHA1, entonces no tiene sentido buscar cualquier cosa, ya que no podremos satisfacer el requisito de submódulo de ninguna manera.


Actualización de agosto de 2016 (3 años después)

Con Git 2.10 (Q3 2016), podrás hacer

 git config -f .gitmodules submodule.<name>.shallow true

Consulte " Submódulo Git sin peso adicional " para obtener más información.


Git 2.13 (Q2 2017) agrega commit 8d3047c (19 abr 2017) por Sebastian Schuberth ( sschuberth) .
(Fusionada por Sebastian Schuberth - sschuberth- en commit 8d3047c , 20 abr 2017)

un clon de este submódulo se realizará como un clon superficial (con una profundidad de historial de 1)

Sin embargo, Ciro Santilli agrega en los comentarios (y detalles en su respuesta )

shallow = trueen .gitmodulessólo afecta a la referencia seguido por el jefe del mando a distancia cuando se utiliza --recurse-submodules, incluso si el objetivo cometer es apuntado por una rama, e incluso si se pone branch = mybranchen el .gitmodulestambién.


Git 2.20 (Q4 2018) mejora el soporte de submódulos, que se ha actualizado para leer desde el blob HEAD:.gitmodulescuando .gitmodulesfalta el archivo del árbol de trabajo.

Consulte commit 2b1257e , commit 76e9bdc (25 de octubre de 2018) y commit b5c259f , commit 23dd8f5 , commit b2faad4 , commit 2502ffc , commit 996df4d , commit d1b13df , commit 45f5ef3 , commit bcbc780 (05 de octubre de 2018) por Antonio Ospite ( ao2) .
(Fusionada por Junio ​​C Hamano - gitster- en commit abb4824 , 13 de noviembre de 2018)

submodule: admite lectura .gitmodulescuando no está en el árbol de trabajo

Cuando el .gitmodulesarchivo no esté disponible en el árbol de trabajo, intente usar el contenido del índice y de la rama actual.
Esto cubre el caso cuando el archivo es parte del repositorio pero, por alguna razón, no está desprotegido, por ejemplo, debido a un pago escaso.

Esto hace posible utilizar al menos los git submodulecomandos ' ' que leen el gitmodulesarchivo de configuración sin llenar completamente el árbol de trabajo.

Escribir en .gitmodulestodavía requerirá que el archivo esté desprotegido, así que verifíquelo antes de llamar config_set_in_gitmodules_file_gently.

Agregue una verificación similar también git-submodule.sh::cmd_add()para anticipar la falla eventual del git submodule addcomando " " cuando .gitmodulesno se puede escribir de forma segura; esto evita que el comando deje el repositorio en un estado espurio (por ejemplo, el repositorio de submódulos se clonó pero .gitmodulesno se actualizó porque config_set_in_gitmodules_file_gentlyfalló).

Además, dado que config_from_gitmodules()ahora accede al almacén de objetos global, es necesario proteger todas las rutas de código que llaman a la función contra el acceso concurrente al almacén de objetos global.
Actualmente esto solo ocurre en builtin/grep.c::grep_submodules(), así que llame grep_read_lock()antes de invocar el código que involucra config_from_gitmodules().

NOTA: hay un caso raro en el que esta nueva característica aún no funciona correctamente: submódulos anidados sin .gitmodulesen su árbol de trabajo.


Nota: Git 2.24 (Q4 2019) corrige un posible segfault al clonar un submódulo superficial.

Ver commit ddb3c85 (30 Sep 2019) por Ali Utku Selen ( auselen) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 678a9ca , 09 oct 2019)


Git 2.25 (Q1 2020), aclara la git submodule updatedocumentación.

Ver commit f0e58b3 (24 Nov 2019) por Philippe Blain ( phil-blain) .
(Fusionada por Junio ​​C Hamano - gitster- en commit ef61045 , 05 dic 2019)

doc: mencione que 'git submodule update' recupera commits faltantes

Ayudado por: Junio ​​C Hamano
Ayudado por: Johannes Schindelin
Firmado por: Philippe Blain

' git submoduleactualizar' obtendrá nuevas confirmaciones del submódulo remoto si no se encuentra el SHA-1 registrado en el superproyecto . Esto no fue mencionado en la documentación.


Advertencia: con Git 2.25 (Q1 2020), la interacción entre " git clone --recurse-submodules" y el almacén de objetos alternativos estaba mal diseñada.

La documentación y el código se han enseñado a hacer recomendaciones más claras cuando los usuarios ven fallas.

Ver commit 4f3e57e , commit 10c64a0 (02 dic 2019) por Jonathan Tan ( jhowtan) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 5dd1d59 , 10 dic 2019)

submodule--helper: avisar sobre error alternativo fatal

Firmado por: Jonathan Tan
Acked: Jeff King

Cuando .gitmodulesse clona de forma recursiva un superproyecto con algunos módulos poco profundos definidos en él , luego se reclonan con " --reference=<path>", se produce un error. Por ejemplo:

git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

falla con:

fatal: submodule '<snip>' cannot add alternate: reference repository
'<snip>' is shallow

Cuando no se puede agregar una alternativa calculada a partir de la alternativa del superproyecto, ya sea en este caso u otro, aconseje sobre la configuración de la " submodule.alternateErrorStrategy" opción de configuración y el uso de " --reference-if-able" en lugar de " --reference" al clonar.

Eso se detalla en:

Con Git 2.25 (Q1 2020), la interacción entre "git clone --recurse-submodules" y la tienda de objetos alternativos fue mal diseñada.

Doc: explique submodule.alternateErrorStrategy

Firmado por: Jonathan Tan
Acked: Jeff King

Commit 31224cbdc7 (" clone: la opción recursiva y de referencia dispara submódulos alternativos", 2016-08-17, Git v2.11.0-rc0 - fusión que figura en el lote # 1 ) enseñó a Git a admitir las opciones de configuración " submodule.alternateLocation" y " submodule.alternateErrorStrategy" en un superproyecto .

Si " submodule.alternateLocation" está configurado para " superproject" en un superproyecto, cada vez que se clona un submódulo de ese superproyecto, calcula en su lugar la ruta alternativa análoga para ese submódulo desde $GIT_DIR/objects/info/alternatesel superproyecto, y lo referencia.

La submodule.alternateErrorStrategyopción " " determina qué sucede si no se puede hacer referencia a esa alternativa.
Sin embargo, no está claro que el clon proceda como si no se especificara una alternativa cuando esa opción no está configurada para "morir" (como se puede ver en las pruebas en 31224cbdc7 ).
Por lo tanto, documente en consecuencia.

La documentación del submódulo de configuración ahora incluye:

submodule.alternateErrorStrategy::

Especifica cómo tratar los errores con las alternativas para un submódulo tal como se calcula a través de submodule.alternateLocation.
Los valores posibles son ignore, info, die.
Por defecto es die.
Tenga en cuenta que si se establece en ignoreo info, y si hay un error con la alternativa calculada, el clon continúa como si no se hubiera especificado ninguna alternativa .

VonC
fuente
2
Wow eso fue rápido! Gracias por la respuesta por cierto. Ah, y --depthdebería tomar una discusión también;)
Brice
3
Me parece que commit fb43e31 solicita el commit faltante por ID SHA1, por lo que la configuración uploadpack.allowReachableSHA1InWanty uploadpack.allowTipSHA1InWanten el servidor probablemente afectará si esto funciona. Escribí una publicación en la lista de git hoy, señalando cómo se puede hacer que el uso de submódulos superficiales funcione mejor para algunos escenarios, es decir, si el commit también es una etiqueta. Vamos a esperar y ver.
MvG
2
Con la reciente incorporación de la opción superficial .gitmodules, ¿funciona la --depth 1opción para sucursales que no están siguiendo de cerca al maestro?
CMCDragonkai
2
@CiroSantilli 刘晓波 死 六四 事件 法轮功 Gracias por la precisión y la prueba. He incluido tu comentario en la respuesta para mayor visibilidad y he votado tu respuesta.
VonC
2
No está claro en la respuesta cuál es la forma actual de hacerlo. Además, no está claro si todo eso es necesario cada vez que alguien clona una copia nueva o si estas configuraciones de submódulos espaciados se vuelven parte del repositorio que hace referencia a estos submódulos (por ejemplo, cada nueva actualización de clones y submódulos resulta en pagos de submódulos espaciados)
Pavel P
26

Git 2.9.0 admite submódulos clon superficial directamente, por lo que ahora solo puede llamar:

git clone url://to/source/repository --recursive --shallow-submodules
TipoDragon
fuente
2
Esta opción es la más prometedora, pero falla en git 2.14.1 el commit del submódulo no es rastreado por una rama o etiqueta: stackoverflow.com/a/47374702/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli 刘晓波 死 六四 事件 法轮功 Asegúrese de que su servidor git también esté actualizado
KindDragon
Gracias, he probado localmente, sin un servidor, y en GitHub, que no puedo actualizar :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Tengo el mismo problema al usar git 2.20, no funciona cuando el submódulo no está en la punta de la rama.
Zitrax
16

Siguiendo la respuesta de Ryan, pude crear este simple script que itera a través de todos los submódulos y los clona superficialmente:

#!/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
Mauricio Scheffer
fuente
Estoy obteniendo fatal: reference is not a tree: 88fb67b07621dfed054d8d75fd50672fb26349dfpara cada submódulo
llamado el
1
@knocte: Escribí mi respuesta en 2010. Las cosas han cambiado. No puede esperar que todos mantengan todas sus respuestas. Marqué la respuesta válida actual como aceptada.
Mauricio Scheffer
13
@knocte Esta es una de las razones por las que dejé de contribuir a Stackoverflow. La gente tiene estas expectativas poco realistas. Sería un trabajo de tiempo completo mantener cada una de mis 1637 respuestas. Y luego también están los comentarios, supongo que también tendría que mantenerlos. Echa un vistazo a las fechas, para eso están. Si lees algún blog .NET de 2002 con código usando ArrayList en lugar de List, ¿lo usarías? ¿Exigirías que el autor actualice su publicación? El mismo principio se aplica aquí.
Mauricio Scheffer
1
s / statusquo / progress /
knocte
8

Al leer la "fuente" de git-submodule, parece que git submodule addpuede manejar submódulos que ya tienen sus repositorios presentes. En ese caso...

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...

Deberá asegurarse de que la confirmación requerida esté en el repositorio de submódulos, así que asegúrese de establecer una profundidad adecuada.

Editar: es posible que pueda escapar con múltiples clones de submódulos manuales seguidos de una sola actualización:

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update
Ryan Graham
fuente
55
Ahora para git 1.8.0, ya no puede clonar un repositorio dentro de un repositorio. Entonces esta solución ya no funciona.
Bohr
7

Resumen de comportamiento con errores / inesperado / molesto a partir de Git 2.14.1

  1. shallow = trueen .gitmodulessólo afecta git clone --recurse-submodulessi el HEADde los puntos submódulo remotas a la necesaria confirmación, incluso si el objetivo cometer es apuntado por una rama, e incluso si se pone branch = mybranchen el .gitmodulestambién.

    Guión de prueba local . Mismo comportamiento en GitHub 2017-11, donde HEADestá controlado por la configuración predeterminada de repositorio de sucursal:

    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.
    
  2. git clone --recurse-submodules --shallow-submodulesfalla 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.

    Guión 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é en 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 solo obtendrá la última punta de una rama (generalmente maestra). No hay ningún mecanismo en el clon para especificar el sha1 exacto que se desea.

    El protocolo de cable admite la solicitud de sha1s exactos, por lo que debe cubrirse. (Advertencia: solo funciona si el operador del servidor habilita uploadpack.allowReachableSHA1InWant, que github no tiene AFAICT)

    git-fetch permite obtener sha1 arbitrario, por lo que, como solución alternativa, puede ejecutar una recuperación después del clon recursivo mediante el uso de "actualización de submódulo git", ya que usará las recuperaciones después del clon inicial.

Prueba de TODO: allowReachableSHA1InWant.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Parece que no hay una manera simple de verificar un hash de confirmación HEAD separado para el submódulo, y tener usuarios intermedios git clone --recursiveque solo obtienen esa confirmación específica.
CMCDragonkai
3

¿Las ubicaciones canónicas para sus submódulos son remotas? Si es así, ¿estás de acuerdo con clonarlos una vez? En otras palabras, ¿desea los clones poco profundos solo porque sufre el ancho de banda desperdiciado de los (re) clones de submódulos frecuentes?

Si desea clones poco profundos para ahorrar espacio en disco local, la respuesta de Ryan Graham parece ser un buen camino a seguir. Clonar manualmente los repositorios para que sean poco profundos. Si cree que sería útil, adáptese git submodulepara soportarlo. Envíe un correo electrónico a la lista preguntándole (consejos para implementarlo, sugerencias sobre la interfaz, etc.). En mi opinión, la gente de allí apoya bastante a los posibles contribuyentes que desean mejorar Git de manera constructiva.

Si está de acuerdo con hacer un clon completo de cada submódulo (más las recuperaciones posteriores para mantenerlas actualizadas), puede intentar usar la --referenceopción de git submodule update(está en Git 1.6.4 y posterior) para referirse a los almacenes de objetos locales (p. Ej. haga --mirrorclones de los repositorios de submódulos canónicos, luego úselos --referenceen sus submódulos para apuntar a estos clones locales). Solo asegúrese de leer sobre git clone --reference/ git clone --sharedantes de usar --reference. El único problema probable con los espejos de referencia sería si alguna vez terminan obteniendo actualizaciones que no son de avance rápido (aunque podría habilitar los registros y expandir sus ventanas de vencimiento para ayudar a retener cualquier confirmación abandonada que pueda causar un problema). No deberías tener ningún problema mientras

  • no realiza ninguna confirmación de submódulo local, o
  • cualquier confirmación que quede pendiente de avance no rápido que los repositorios canónicos puedan publicar no son ancestros de sus confirmaciones de submódulo local, o
  • usted es diligente en mantener sus confirmaciones de submódulos locales reorganizadas además de cualquier avance no rápido que pueda publicarse en los repositorios de submódulos canónicos.

Si opta por algo como esto y existe la posibilidad de que pueda llevar a cabo confirmaciones de submódulos locales en sus árboles de trabajo, probablemente sea una buena idea crear un sistema automatizado que se asegure de que los objetos críticos a los que hacen referencia los submódulos desprotegidos no sean colgado en los repositorios espejo (y si encuentra alguno, cópielos en los repositorios que los necesiten).

Y, como git clonedice la página de manual, no lo use --referencesi no comprende 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

Alternativamente, en lugar de --reference, podría usar los clones espejo en combinación con la funcionalidad predeterminada de enlace directo de git cloneusar espejos locales como la fuente de sus submódulos. En nuevos clones de superproyectos, haga git submodule init, edite las URL de submódulo .git/configpara apuntar a los espejos locales, luego hagagit submodule update. Tendría que reclinar cualquier submódulo desprotegido existente para obtener los enlaces duros. Ahorraría ancho de banda al descargar solo una vez en los espejos y luego buscarlos localmente en los submódulos desprotegidos. El enlace duro ahorraría espacio en el disco (aunque las recuperaciones tenderían a acumularse y duplicarse en múltiples instancias de los almacenes de objetos de los submódulos desprotegidos; periódicamente podría reclinar los submódulos desprotegidos de los espejos para recuperar el ahorro de espacio en disco proporcionado por hardlinking).

Chris Johnsen
fuente
2

Creé una versión ligeramente diferente, para cuando no se está ejecutando a la última, lo que no hacen todos los proyectos. Las adiciones estándar de submódulos no funcionaron ni el script anterior. Así que agregué una búsqueda hash para la etiqueta de referencia, y si no tiene una, vuelve a clonar por completo.

#!/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 
Sfossen
fuente
2

Referencia a ¿Cómo clonar el repositorio git con una revisión / conjunto de cambios específico?

He escrito un script simple que no tiene ningún problema cuando su referencia de 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 buscará la versión referenciada del submódulo.

Es rápido, pero no puede confirmar su edición en el submódulo (debe recuperarlo antes de 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
Beeno Tung
fuente
1

El clon superficial de un submódulo es perfecto porque se capturan en una revisión / conjunto de cambios en particular. Es fácil descargar un archivo zip del sitio web, así que probé un script.

#!/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 borra el árbol de submódulos que permite que el script sea reutilizable.

git submodulerecupera el 40 char sha1 seguido de una ruta que corresponde a la misma en .gitmodules. Utilizo perl para concatenar esta información, delimitada por dos puntos, luego empleo la transformación de variables para separar los valores en myshay mysub.

Estas son las claves críticas porque necesitamos el sha1 para descargar y la ruta para correlacionar los urlingitmodules.

Dada una entrada típica de submódulo:

[submodule "label"]
    path = localpath
    url = https://github.com/repository.git

myurlteclas en path =luego mira 2 líneas después para obtener el valor. Es posible que este método no funcione de manera consistente y requiera refinamiento. La url grep elimina cualquier .gitreferencia de tipo restante haciendo coincidir la última /y cualquier cosa hasta a ..

mydires mysubmenos un final /nameque sería por el directorio que conduce al nombre del submódulo.

El siguiente es un wgetformato de URL de archivo zip descargable. Esto puede cambiar en el futuro.

Descomprima el archivo en el mydirque sería el subdirectorio especificado en la ruta del submódulo. La carpeta resultante será el último elemento de url- sha1.

Verifique si el subdirectorio especificado en la ruta del submódulo existe y elimínelo para permitir el cambio de nombre de la carpeta extraída.

mv cambie el nombre de la carpeta extraída que contiene nuestro sha1 a su ruta de submódulo correcta.

Eliminar el archivo zip descargado.

Submódulo init

Esto es más una prueba de concepto WIP en lugar de una solución. Cuando funciona, el resultado es un clon superficial de un submódulo en un conjunto de cambios especificado.

Si el repositorio vuelve a colocar un submódulo en una confirmación diferente, vuelva a ejecutar el script para actualizar.

La única vez que un script como este sería útil es para la construcción local no colaborativa de un proyecto fuente.

noabody
fuente