Git no iniciará / sincronizará / actualizará nuevos submódulos

113

Aquí está parte del contenido de mi .gitmodulesarchivo:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

Sin embargo, .git/configsolo contiene el primero:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

El segundo submódulo ( external/pyfacebook) fue agregado por otro desarrollador en una rama de funciones. He heredado el desarrollo ahora y he comprobado la rama de funciones. Sin embargo, Git no extraerá el submódulo por mí. He intentado:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • Eliminando todas las definiciones de submódulos .git/configy ejecutándose git submodule init. Solo copia el submódulo existente anteriormente e ignora el nuevo.
  • Ingresar nuevas definiciones de submódulo de forma .git/configmanual y en ejecución git submodule update. Solo los submódulos existentes anteriormente se molestan en actualizar.

en varias combinaciones, pero git simplemente no se actualizará en .git/configfunción del nuevo contenido de .gitmodules, ni creará la external/pyfacebookcarpeta y extraerá el contenido del submódulo.

¿Qué me estoy perdiendo? ¿Es .git/configrealmente necesaria la intervención manual (agregar una entrada de submódulo a mano ) y por qué?

Editar: la intervención manual no funciona. Agregar manualmente la nueva entrada de submódulo a .git/configno hace nada. El nuevo submódulo se ignora.

David Eyk
fuente
1
ejecutando 1.7.7.1 y teniendo el mismo problema: "git submodule sync" no actualiza .git / config después de un cambio a .gitmodules.
James Pritts
2
Este artículo es útil: chrisjean.com/git-submodules-adding-using-removing-and-updating
IgorGanapolsky

Respuestas:

35

¿Actualizó recientemente a la versión 1.7.0.4 de git? Lo hice y ahora tengo problemas similares ...

Editar: solucioné mi problema pero no tengo ni idea de dónde estaba el problema. Eliminé manualmente las entradas del submódulo de .git / config y .gitmodules y volví a agregar mis submódulos con los pasos ususales (git submodule add, etc.) ... Worksforme pero no agrega valor a este hilo.

Quickredfox
fuente
Estoy hasta 1.7.2 en este momento, pero creo que he tenido el problema desde al menos 1.6.x.
David Eyk
Y sí, ahora que lo pienso, terminé teniendo que hacer lo que usted describe (¡olvidé que esta pregunta aún estaba abierta!). Si no le importa pulir un poco su respuesta, la acepto.
David Eyk
9
Esta es una debilidad continua de git. Incluso svn es mejor con externos.
Peter DeWeese
3
Creo que también me encontré con esto (los mismos pasos parecen solucionarlo finalmente). Lo único que noté es que, después de agregarlo nuevamente, y luego comprometerme, el compromiso decía: crear modo 160000 lib / jruby-swing-helpers (¿eh?)
rogerdpack
1
Acerca del "modo de creación 160000", el libro de Pro Git dice lo siguiente: "Observe el modo 160000 para la entrada del rack. Es un modo especial en Git que básicamente significa que está grabando una confirmación como una entrada de directorio en lugar de un subdirectorio o un expediente." git-scm.com/book/en/Git-Tools-Submodules
Johann
92

Tuve este mismo problema: resultó que el archivo .gitmodules estaba comprometido, pero la confirmación del submódulo real (es decir, el registro del ID de confirmación del submódulo) no lo estaba.

Agregarlo manualmente pareció hacer el truco, por ejemplo:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(Incluso sin eliminar nada de .git / config o .gitmodules).

Luego confírmelo para registrar la identificación correctamente.

Agregando algunos comentarios adicionales a esta respuesta de trabajo: si la actualización del submódulo git init o la actualización del submódulo git no funciona, entonces, como se describe anteriormente, el submódulo git agregar url debería funcionar. Uno puede verificar esto por

 git config --list

y uno debería obtener una entrada del submódulo que desea extraer en el resultado del comando git config --list. Si hay una entrada de su submódulo en el resultado de la configuración, entonces ahora la actualización habitual del submódulo git --init debería extraer su submódulo. Para probar este paso, puede cambiar el nombre del submódulo manualmente y luego actualizar el submódulo.

 mv yourmodulename yourmodulename-temp
 git submodule update --init

Para saber si tiene cambios locales en el submódulo, se puede ver a través de git status -u (si desea ver cambios en el submódulo) o git status --ignore-submodules (si no desea ver los cambios en el submódulo).

Dave James Miller
fuente
Lo que es external/pyfacebookpara?
IgorGanapolsky
2
@IgorGanapolsky Esa es la ruta de destino para su submódulo.
Yuhua
Esto me ayudó, ¡muchas gracias! Solo podría agregar que si la ruta de destino ya existe (lo que hizo por mí como resultado de probar otros comandos), se recibe el siguiente mensaje que aumenta la confusión:'your/local/path' already exists and is not a valid git repo
Michael Ambrus
1
una línea para leer las entradas en "git config --list":git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
Puggan Se
64

git versión 2.7.4. Este comando actualiza el código local git submodule update --init --force --remote

Palik
fuente
20
Sin hacer nada por mi
Carlo Wood
1
con respecto a git-submodule [documentación) ( git-scm.com/docs/git-submodule#git-submodule---remote ), el comando antes mencionado debería actualizar la rama local de los submódulos.
palik
1
@palik ¡eres genial!
Denis Trofimov
1
Puede actualizar un módulo individual con git submodule update --init --force --remote <module-name>.
Adam Faryna
15

Tuve el mismo problema, cuando git ignora inity updateordena, y no hace nada.

COMO ARREGLAR

  1. Su carpeta de submódulo debe estar comprometida en git repo
  2. No debería estar en .gitignore

Si se cumplen esos requisitos, funcionará. De lo contrario, todos los comandos se ejecutarán sin ningún mensaje ni resultado.

Si hiciste todo eso y todavía no funciona:

  1. Agregar submódulo manualmente, p. Ej. git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. confirmar y enviar todos los archivos, .gitmodulesy la carpeta del módulo (tenga en cuenta que el contenido de la carpeta no se confirmará)
  5. suelta tu repositorio de git local
  6. clonar uno nuevo
  7. asegúrese de que .git/configtodavía no tenga submódulos
  8. Ahora, git submodule inity verá un mensaje de que el módulo registró
  9. git submodule update - buscará el módulo
  10. Ahora mire .git/configy encontrará el submódulo registrado
Alex Ivasyuv
fuente
1
Creo que la ruta a los submódulos PUEDE estar en .gitignore. Al menos lo hice funcionar siguiendo la respuesta de @DaveJamesMiller. Nada más funcionó para mí.
gebbissimo
7

Parece haber mucha confusión aquí (también) en las respuestas.

git submodule initno está destinado a generar cosas mágicamente en .git / config (desde .gitmodules). Tiene la intención de configurar algo en un subdirectorio completamente vacío después de clonar el proyecto principal, o extraer una confirmación que agrega un submódulo que no existía previamente.

En otras palabras, sigue un git cloneproyecto que tiene submódulos (que sabrá por el hecho de que el clon extrajo un archivo .gitmodules) por un git submodule update --init --recursive.

Usted no sigue git submodule add ...con una git submodule init(o git submodule update --init), que no se supone que funciona. De hecho, el complemento ya actualizará el .git / config apropiado si las cosas funcionan.

EDITAR

Si alguien más agregó un submódulo git que no existía anteriormente, y usted realiza una git pullde esas confirmaciones, entonces el directorio de ese submódulo estará completamente vacío (cuando ejecute git submodule statusel hash del nuevo submódulo debería ser visible pero tendrá un -frente de it.) En este caso, debe seguir su git pulltambién con un git submodule update --init(más --recursivecuando es un submódulo dentro de un submódulo) para obtener el submódulo nuevo, previamente no existente, verificado; al igual que después de un clon inicial de un proyecto con submódulos (donde obviamente tampoco tenía esos submódulos antes).

Carlo Wood
fuente
1
Eso es interesante, porque git help submoduledice esto sobre init: "init: Inicializa los submódulos registrados en el índice (que fueron agregados y comprometidos en otro lugar) copiando los nombres de los submódulos y las URL de .gitmodules a .git / config". ¿Entonces parece que debería hacer exactamente lo que dices que no hace ...? ¿Es hora de actualizar la documentación de git?
Brad
@brad No creo haber dicho eso, pero agregué una aclaración para ese caso específico. Gracias.
Carlo Wood
@CarloWood ¿alguna idea de por qué los escritores de submódulos de git decidieron que --initdebería ser necesario obtener nuevos submódulos (en lugar de tomarlos automáticamente update)? Parece que la actualización de su repositorio debería tomar todo lo necesario a menos que destruya los datos. Con --initesto, te obliga a saber que se podrían haber creado nuevos submódulos, o simplemente emitir siempre un --initcada vez, en cuyo caso, nuevamente, parecería que debería estar habilitado por defecto.
Catskul
@Catskul Obviamente, no tengo idea de por qué los escritores de los submódulos de git decidieron algo, pero supongo que "actualizar" está reservado para actualizar algo que ya existe, y "init" se usa para crear algo (localmente) nuevo. Debajo del capó, los dos son probablemente lo suficientemente diferentes como para justificar un comando diferente.
Carlo Wood
6

Tuve el mismo problema, pero ninguna de las soluciones anteriores ayudó. Las entradas en .gitmodules y en .git / config eran correctas pero el comando git submodules update --init --recursiveno hacía nada. También eliminé el directorio del submódulo y lo ejecuté git submodules update --init --recursivey recuperé el directorio del submódulo, pero con exactamente la misma confirmación que antes.

Encontré la respuesta en esta página . El comando es:git submodule update --remote

masterop
fuente
2
Esta también fue la solución correcta para mí. Estaba corriendo en git submodule updatelugar de git submodule update --remote.
Andrew Medlin
5

Como git submodule initpor arte de magia, pero hoy corrí seguido de git submodule syncseguido de git submodule updatey comenzó a tirar de mis submódulos ... ¿Magia? ¡Quizás! Esta es realmente una de las experiencias más molestas con Git ...

Rasca eso. De hecho, lo hice funcionar git submodule update --init --recursive. Espero que esto ayude.

PD: asegúrate de estar en el directorio raíz de git, no en el del submódulo.

Levi Figueira
fuente
7
No, esto no hace absolutamente nada por mí.
IgorGanapolsky
@IgorGanapolsky Edité la respuesta anterior con lo que funcionó para mí. ¡Déjame saber si funciona!
Levi Figueira
Probé tus nuevos comandos, pero tampoco hicieron nada.
IgorGanapolsky
5

Pensar que la configuración manual .gitmoduleses suficiente es INCORRECTO

Mi local git version 2.22.0al momento de escribir este artículo.

Entonces llegué a este hilo preguntándome por qué no estaba git submodule initfuncionando; Configuré el .gitmodulesarchivo y procedí a hacer git submodule init...

IMPORTANTE

  1. git submodule add company/project.git includes/projectes necesario (al agregar el módulo por primera vez), esto:

    • agregar config a .git/config
    • actualizar el .gitmodulesarchivo
    • rastrear la ubicación del submódulo ( includes/projecten este ejemplo).
  2. usted debe entonces git commitdespués de haber agregado el submódulo, esto va a cometer .gitmodulesy la ubicación sub-módulo de seguimiento.

Cuando el proyecto se clona nuevamente, tendrá .gitmodulesy el directorio de submódulos vacío (por ejemplo, includes/projecten este ejemplo). En este punto, .git/configtodavía no tiene la configuración del submódulo, hasta que git submodule initse ejecuta, y recuerde que esto solo funciona porque .gitmodulesY includes/projectse rastrean en el repositorio principal de git.

También para referencia ver:

farinspace
fuente
3

Yo tuve el mismo problema.

.gitmodulestenía el submódulo, pero después de un git submodule initcomando no estaba en .git/config.

Resulta que el desarrollador que agregó el submódulo también agregó el directorio del submódulo al .gitignorearchivo. Eso no funciona.

joseph.hainline
fuente
2

Al igual que tú, descubrí que la sincronización del submódulo git no hace lo que esperas que haga. Solo después de hacer un explícito de git submodule addnuevo cambia la URL de un submódulo.

Entonces, puse este script en ~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

Y también uso la misma lógica en algunos scripts de implementación de git posteriores a la recepción.

Todo lo que necesito hacer ahora es editar .gitmodules, luego ejecutar este script y finalmente funciona como pensé que git submodule syncse suponía que debía hacerlo.

fridh
fuente
Esto parece suceder solo en algunos repositorios ... posiblemente debido a algún error en Git. No me ha sucedido en repositorios recién creados durante mucho tiempo, pero hace mucho tiempo, solía suceder todo el tiempo en ciertos
repositorios
2

Tuve el mismo problema hoy y me di cuenta de que porque escribí git submodule initentonces tenía esas líneas en mi .git/config:

[submodule]
   active = .

Eliminé eso y escribí:

git submodule update --init --remote

Y todo volvió a la normalidad, mi submódulo se actualizó en su subdirectorio como de costumbre.

Eric Jeker
fuente
2

El problema para mí es que el desarrollador anterior del repositorio había comprometido la submodules/thingcarpeta como una carpeta normal, lo que significa que cuando intenté ejecutarlo git submodule add ..., fallaría con:, 'submodules/thing' already exists in the indexpero intentar actualizar el submódulo también fallaría porque vio que la ruta no funcionaba contener un submódulo.

Para solucionarlo, tuve que eliminar la submodules/thingcarpeta, confirmar la eliminación y luego ejecutar el git submodule addcomando para volver a agregarla correctamente:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing
Venryx
fuente
1

Cuando vi esto hoy, un desarrollador había movido parte del árbol a un nuevo subdirectorio y parece que su cliente git no registró las reglas del subproyecto actualizadas en el árbol, en su lugar, solo fueron destruidas, dejando la .gitmodulesreferencia a ambas obsoletas. ubicaciones y subproyectos que ya no existían en el árbol actual.

Agregando los submódulos nuevamente y comparando los shas de confirmación del submódulo con los encontrados en git show $breaking_commit_sha(busque líneas que coincidan con regexp ^-Subproject) para ajustar las cosas arregladas según sea necesario.

Phil P
fuente
1

Eliminar el directorio del submódulo y su contenido (carpeta "external / pyfacebook") si existe antes git submodule add ...podría solucionar problemas.

atahan
fuente
1
Este fue el problema para mí. Alguien había comprometido la carpeta "submodule" como una carpeta normal, lo que significa que cuando intenté ejecutar "git submodule add ...", fallaría con: "'vendor / mobx-state-tree' ya existe en el índice" , aunque intentar actualizar el submódulo también fallaría porque vio que la ruta no contenía un submódulo). Para solucionarlo, tuve que eliminar la carpeta, confirmar la eliminación y luego ejecutar el comando git add para volver a agregarla correctamente.
Venryx
1

Tuve un problema similar con un submódulo. Simplemente no quería ser clonado / extraído / actualizado / lo que sea.

Al intentar volver a agregar el submódulo usando git submodule add [email protected] destination, obtuve el siguiente resultado:

A git directory for 'destination' is found locally with remote(s):
  origin        [email protected]
If you want to reuse this local git directory instead of cloning again from
  [email protected]
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

Entonces, intenté hacer cumplir el comando add :
git submodule add --force [email protected] destination

Eso funcionó en mi caso.

Arvid
fuente
0

Para el registro:
creé el mismo problema agregando un repositorio vacío como submódulo. En este caso, no había ningún hash de referencia disponible para el submódulo, lo que provocó el error descrito por el póster original.

Forzar la adición del repositorio después de haberse comprometido a resolver el problema (como en la publicación de Arvids)
git submodule add --force [email protected] destination

Bagazo
fuente
0
  • Quite el submódulo de su .git/config
  • Ejecutar git submodule initcomando
  • Vaya a su directorio de submódulo y ejecute git pull origin master

Debería funcionar ahora

Masoud Darvishian
fuente
0

Solo comparto lo que funcionó para mí:

git clone --recurse-submodules <repository path>

Esto clona el repositorio remoto que ya incluye los submódulos. Esto significa que no necesitará ejecutar git submodule update o init después de la clonación.

Anne Kariny Silva Freitas
fuente
0

El siguiente comando de sincronización resolvió el problema:

git submodule sync
Nishant Chauhan
fuente