Git diff dit que le sous-projet est sale


227

Je viens de lancer un diff git et j'obtiens la sortie suivante pour tous mes 10 sous-modules environ

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'est-ce que ça veut dire? Comment je le répare?

Réponses:


268

Comme mentionné dans le blog de Mark Longair, Git Submodules Explained ,

Les versions 1.7.0 et ultérieures de git contiennent un changement gênant dans le comportement du sous-module git.
Les sous-modules sont désormais considérés comme sales s'ils contiennent des fichiers modifiés ou des fichiers non suivis , alors qu'auparavant, cela ne serait le cas que si HEAD dans le sous-module pointait vers le mauvais commit.

La signification du signe plus ( +) dans la sortie du sous-module git a changé, et la première fois que vous rencontrez cela, cela prend un peu de temps pour comprendre ce qui ne va pas, par exemple en regardant dans les journaux des modifications ou en utilisant git bissect sur git .git pour trouver le changement. Il aurait été beaucoup plus aimable pour les utilisateurs d'introduire un symbole différent pour «à la version spécifiée, mais sale».

Vous pouvez le réparer en:

  • soit en validant ou en annulant les changements / évolutions dans chacun de vos sous-modules, avant de retourner au référentiel parent (où le diff ne devrait plus signaler les fichiers "sales"). Pour annuler toutes les modifications de votre sous-module juste cddans le répertoire racine de votre sous-module et faitesgit checkout .

    dotnetCarpenter commente que vous pouvez faire:git submodule foreach --recursive git checkout .

  • ou ajouter --ignore-submodulesà votre git diff, pour ignorer temporairement ces sous-modules "sales".

Nouveau dans Git version 1.7.2

Comme le commente Noam ci - dessous , cette question mentionne que, depuis la version 1.7.2 de git, vous pouvez ignorer les sous-modules sales avec:

git status --ignore-submodules=dirty

2
Aussi une bonne chose à savoir: vous pouvez toujours exécuter git commit -asans avoir à vous soucier d'ajouter ces modifications. Bien qu'ils soient marqués Mà l'avant, ils ne se retrouveront pas dans votre commit.
gitaarik

1
Pour moi, je devais entrer dans chaque sous-module sale et courir git clean -id.
GDP2

1
@ GDP2 Que vous pouvez mettre en ligne, avec git submodule foreach --recursive git clean -id(à tester d'abord dans un
référentiel de

1
Le cas où je n'arrêtais pas de voir cela inexplicablement, ce qui se passait était que j'avais des fichiers non suivis qui n'étaient pas dans le sous-module .gitignore . Les ajouter là-bas ou à ma liste globale d'ignorer les choses fixes.
Ben

21

Retirer également le sous-module, puis l'exécuter git submodule initet git submodule updatefera évidemment l'affaire, mais peut ne pas toujours être approprié ou possible.


1
Cela a fonctionné pour moi lorsque j'ai converti certains dossiers existants en sous-modules, puis je me suis installé sur une autre machine qui contenait toujours les anciens dossiers.
Roger Lipscombe du

18

Pour ignorer tous les fichiers non suivis dans n'importe quel sous-module, utilisez la commande suivante pour ignorer ces modifications.

git config --global diff.ignoreSubmodules dirty

Il ajoutera l'option de configuration suivante à votre configuration git locale:

[diff]
  ignoreSubmodules = dirty

De plus amples informations peuvent être trouvées ici


16

EDIT : Cette réponse (et la plupart des autres) sont obsolètes; voir la réponse de Devpool à la place .


À l'origine, il n'y avait pas d'options de configuration pour faire de " git diff --ignore-submodules" et " git status --ignore-submodules" la valeur par défaut globale (mais voir aussi Définition des indicateurs par défaut de git sur les commandes ). Une alternative est de définir une option de ignoreconfiguration par défaut sur chaque sous-module individuel que vous souhaitez ignorer (pour les deux git diffet git status), soit dans le .git/configfichier (local uniquement) ou .gitmodules(sera versionné par git). Par exemple:

[submodule "foobar"]
    url = git@bitbucket.org:foo/bar.git
    ignore = untracked

ignore = untrackedignorer uniquement les fichiers non suivis, ignore = dirtyignorer également les fichiers modifiés et ignore = allignorer également les validations. Il n'y a apparemment aucun moyen de le joker pour tous les sous-modules.


13

C'est le cas, car le pointeur que vous avez pour le sous-module n'est pas ce qui se trouve réellement dans le répertoire du sous-module. Pour résoudre ce problème, vous devez réexécuter git submodule update:


9
git submodule foreach --recursive git checkout .

Cela n'a pas fait l'affaire pour moi mais cela m'a donné une liste de fichiers (dans mon cas un seul) qui avaient été modifiés dans le sous-module (sans que j'y fasse quoi que ce soit).

Je pouvais donc me diriger vers le sous-module et l'état git m'a montré que ma tête était détachée -> git checkout master, git status pour voir à nouveau le fichier modifié, git checkout> filename <, git pull et tout va bien à nouveau.


9

J'ai fini par supprimer le répertoire du sous-module et l'initialiser à nouveau

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update

4
Je préfère comprendre ce qui s'est passé, mais c'est aussi la seule chose qui a fonctionné pour moi ...
smilebomb

6

Un sous-module peut être marqué comme sale si les paramètres de mode de fichier sont activés et que vous avez modifié les autorisations de fichier dans la sous-arborescence du sous-module.

Pour désactiver le mode de fichier dans un sous-module, vous pouvez modifier /.git/modules/path/to/your/submodule/config et ajouter

[core]
  filemode = false

Si vous voulez ignorer tous les états sales, vous pouvez soit définir la ignore = dirtypropriété dans le fichier /.gitmodules , mais je pense qu'il est préférable de désactiver uniquement le mode de fichier.


1

Dans mon cas, je n'étais pas sûr de ce qui avait causé cela, mais je savais que je voulais juste que les sous-modules soient réinitialisés à leur dernière validation à distance et en aient fini avec. Cela impliquait de combiner les réponses de quelques questions différentes ici:

git submodule update --recursive --remote --init

Sources:

Comment puis-je rétablir mes modifications dans un sous-module git?

Un moyen facile de tirer le dernier de tous les sous-modules git

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.