Git diff dice que el subproyecto está sucio

227

Acabo de ejecutar un git diff y obtengo el siguiente resultado para todos mis aproximadamente 10 submódulos

diff --git a/.vim/bundle/bufexplorer b/.vim/bundle/bufexplorer
--- a/.vim/bundle/bufexplorer
+++ b/.vim/bundle/bufexplorer
@@ -1 +1 @@
-Subproject commit 8c75e65b647238febd0257658b150f717a136359
+Subproject commit 8c75e65b647238febd0257658b150f717a136359-dirty

¿Qué significa esto? ¿Cómo lo soluciono?

mrwooster
fuente

Respuestas:

268

Como se menciona en la publicación del blog de Mark Longair, Git Submodules Explained ,

Las versiones 1.7.0 y posteriores de git contienen un cambio molesto en el comportamiento del submódulo git.
Los submódulos ahora se consideran sucios si tienen archivos modificados o archivos no rastreados , mientras que anteriormente solo sería el caso si HEAD en el submódulo señalaba la confirmación incorrecta.

El significado del signo más ( +) en la salida del submódulo git ha cambiado, y la primera vez que te encuentras con esto toma un poco de tiempo descubrir qué está mal, por ejemplo, mirando a través de registros de cambios o usando git bisect en git .git para encontrar el cambio. Hubiera sido mucho más amable para los usuarios introducir un símbolo diferente para "en la versión especificada, pero sucio".

Puedes arreglarlo de la siguiente manera:

  • ya sea confirmando o deshaciendo los cambios / evoluciones dentro de cada uno de sus submódulos, antes de volver al repositorio principal (donde el diff ya no debería reportar archivos "sucios"). Para deshacer todos los cambios en su submódulo solo cden el directorio raíz de su submódulo y hacergit checkout .

    dotnetCarpenter comenta que puedes hacer:git submodule foreach --recursive git checkout .

  • o agregue --ignore-submodulesa su git diff, para ignorar temporalmente esos submódulos "sucios".

Nuevo en Git versión 1.7.2

Como Noam comenta a continuación , esta pregunta menciona que, desde la versión 1.7.2 de git, puede ignorar los submódulos sucios con:

git status --ignore-submodules=dirty
VonC
fuente
2
También es bueno saberlo: aún puede ejecutar git commit -asin tener que preocuparse de agregar estos cambios. Aunque están marcados Men el frente, no terminarán en tu commit.
gitaarik
1
Para mí, tuve que entrar en cada submódulo sucio y correr git clean -id.
GDP2
1
@ GDP2, que puede usar en una línea, con git submodule foreach --recursive git clean -id(para probar primero en un repositorio de respaldo;))
VonC
1
El caso que seguí viendo esto inexplicablemente, lo que estaba sucediendo era que tenía archivos sin seguimiento que no estaban en el submódulo .gitignore. Agregarlos allí o a mi lista global de ignorados solucionó cosas.
Ben
21

También eliminar el submódulo y luego ejecutarlo git submodule inity git submodule updateobviamente hará el truco, pero puede que no siempre sea apropiado o posible.

usuario1178907
fuente
1
Esto funcionó para mí cuando convertí algunas carpetas existentes en submódulos y luego tiré a otra máquina que todavía tenía las carpetas antiguas.
Roger Lipscombe el
18

Para ignorar todos los archivos no rastreados en cualquier submódulo, use el siguiente comando para ignorar esos cambios.

git config --global diff.ignoreSubmodules dirty

Agregará la siguiente opción de configuración a su configuración local de git:

[diff]
  ignoreSubmodules = dirty

Puede encontrar más información aquí.

Devpool
fuente
16

EDITAR : Esta respuesta (y la mayoría de las otras) son obsoletas; ver la respuesta de Devpool en su lugar .


Originalmente, no había opciones de configuración para hacer " git diff --ignore-submodules" y " git status --ignore-submodules" el valor predeterminado global (pero vea también Establecer indicadores predeterminados de git en los comandos ). Una alternativa es establecer un valor predeterminadoignore opción de configuración en cada submódulo individual que desee ignorar (para ambos git diffy git status), ya sea en el .git/configarchivo (solo local) o .gitmodules(será versionado por git). Por ejemplo:

[submodule "foobar"]
    url = [email protected]:foo/bar.git
    ignore = untracked

ignore = untracked para ignorar solo los archivos no rastreados, ignore = dirty ignorar también los archivos modificados e ignore = allignorar también los commits. Aparentemente no hay forma de comodín para todos los submódulos.

Ralph Versteegen
fuente
13

Este es el caso porque el puntero que tiene para el submódulo no es el que está realmente en el directorio de submódulos. Para solucionar esto, debe ejecutar git submodule updatenuevamente:

Robin Ren
fuente
9
git submodule foreach --recursive git checkout .

Esto no funcionó, pero me dio una lista de archivos (en mi caso, solo uno) que habían sido modificados en el submódulo (sin que yo hiciera nada allí).

Entonces pude ir al submódulo y el estado de git me mostró que mi CABEZA estaba desconectada -> git checkout master, git status para ver el archivo modificado una vez más, git checkout> filename <, git pull y todo bien nuevamente.

Solo un poco
fuente
9

Terminé eliminando el directorio de submódulos e inicializándolo nuevamente

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update
Szymon Wygnański
fuente
44
Yo prefiero entender lo que pasó, pero esto también era el único que funcionó para mí ...
smilebomb
6

Un submódulo puede marcarse como sucio si la configuración del modo de archivo está habilitada y usted cambió los permisos de archivo en submódulo subárbol.

Para deshabilitar el modo de archivo en un submódulo, puede editar /.git/modules/path/to/your/submodule/config y agregar

[core]
  filemode = false

Si desea ignorar todos los estados sucios, puede establecer la ignore = dirtypropiedad en el archivo /.gitmodules , pero creo que es mejor deshabilitar solo el modo de archivo.

Dryobs
fuente