Git diff dice che il sottoprogetto è sporco


227

Ho appena eseguito un git diff e sto ottenendo il seguente output per tutti i miei circa 10 sottomoduli

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

Cosa significa questo? Come lo aggiusto?

Risposte:


268

Come menzionato nel post sul blog di Mark Longair, spiega Git Submodules ,

Le versioni 1.7.0 e successive di git contengono un fastidioso cambiamento nel comportamento del sottomodulo git.
I sottomoduli sono ora considerati sporchi se presentano file modificati o non tracciati , mentre in precedenza lo sarebbe solo se HEAD nel sottomodulo indicava un commit errato.

Il significato del segno più ( +) nell'output del sottomodulo git è cambiato e la prima volta che ci si imbatte in questo ci vuole un po 'di tempo per capire cosa non va, ad esempio guardando attraverso i log delle modifiche o usando git bisect su git .git per trovare il cambiamento. Sarebbe stato molto più gentile per gli utenti introdurre un simbolo diverso per "nella versione specificata, ma sporco".

Puoi risolverlo:

  • commettere o annullare le modifiche / evoluzioni all'interno di ciascuno dei tuoi sottomoduli, prima di tornare al repository principale (dove il diff non dovrebbe più segnalare file "sporchi"). Annullare tutte le modifiche al sottomodulo solo cdnella directory principale del sottomodulo e procederegit checkout .

    dotnetCarpenter commenta che puoi fare un:git submodule foreach --recursive git checkout .

  • o aggiungi --ignore-submodulesal tuo git diff, per ignorare temporaneamente quei sottomoduli "sporchi".

Novità nella versione 1.7.2 di Git

Come commenta Noam di seguito , questa domanda menziona che, dalla versione 1.7.2 di git, puoi ignorare i sottomoduli sporchi con:

git status --ignore-submodules=dirty

2
Anche una buona cosa da sapere: puoi ancora eseguire git commit -asenza doverti preoccupare di aggiungere queste modifiche. Sebbene siano contrassegnati con Min primo piano, non finiranno nel tuo commit.
gitaarik,

1
Per me, ho dovuto andare in ogni sottomodulo sporco ed eseguire git clean -id.
PIL2,

1
@ GDP2 che puoi indossare in una riga, con git submodule foreach --recursive git clean -id(da testare prima in un repository di backup;))
VonC

1
Nel caso continuassi a vederlo inspiegabilmente, ciò che stava accadendo era che avevo file non tracciati che non erano nel sottomodulo .gitignore. Aggiungendoli lì o al mio elenco globale di ignorare le cose riparate.
Ben

21

Anche la rimozione del sottomodulo e quindi l'esecuzione git submodule inite git submodule updateovviamente farà il trucco, ma potrebbe non essere sempre appropriato o possibile.


1
Questo ha funzionato per me quando ho convertito alcune cartelle esistenti in sottomoduli e poi ho estratto un altro computer che aveva ancora le vecchie cartelle.
Roger Lipscombe,

18

Per ignorare tutti i file non tracciati in qualsiasi sottomodulo, utilizzare il comando seguente per ignorare tali modifiche.

git config --global diff.ignoreSubmodules dirty

Aggiungerà la seguente opzione di configurazione al tuo git config locale:

[diff]
  ignoreSubmodules = dirty

Ulteriori informazioni sono disponibili qui


16

EDIT : questa risposta (e la maggior parte delle altre) è obsoleta; vedi invece la risposta di Devpool .


Inizialmente, non c'erano opzioni di configurazione per rendere " git diff --ignore-submodules" e " git status --ignore-submodules" il default globale (ma vedi anche Impostazione dei flag git default sui comandi ). Un'alternativa è impostare ignoreun'opzione di configurazione predefinita su ogni singolo sottomodulo che si desidera ignorare (per entrambi git diffe git status), nel .git/configfile (solo locale) o .gitmodules(sarà verificato da git). Per esempio:

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

ignore = untrackedignorare solo i file non tracciati, ignore = dirtyignorare anche i file modificati e ignore = allignorare anche i commit. Apparentemente non c'è modo di jolly per tutti i sottomoduli.


13

Questo è il caso perché il puntatore che hai per il sottomodulo non è quello che è effettivamente nella directory del sottomodulo. Per risolvere questo problema, è necessario eseguire git submodule updatenuovamente:


9
git submodule foreach --recursive git checkout .

Questo non ha funzionato per me, ma mi ha fornito un elenco di file (nel mio caso solo uno) che erano stati modificati nel sottomodulo (senza che io facessi nulla lì).

Quindi ho potuto passare al sottomodulo e lo stato git mi ha mostrato che il mio HEAD era staccato -> git checkout master, git status per vedere ancora una volta il file modificato, git checkout> nomefile <, git pull e tutto di nuovo bene.


9

Ho finito per rimuovere la directory del sottomodulo e inizializzarla di nuovo

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

4
Preferirei capire cosa è successo, ma questa è stata anche l'unica cosa che ha funzionato per me ...
smilebomb,

6

Un sottomodulo può essere contrassegnato come sporco se le impostazioni di modalità file sono abilitate e sono state modificate le autorizzazioni dei file nella sottostruttura del sottomodulo.

Per disabilitare la modalità file in un sottomodulo, è possibile modificare /.git/modules/path/to/your/submodule/config e aggiungere

[core]
  filemode = false

Se vuoi ignorare tutti gli stati sporchi, puoi impostare la ignore = dirtyproprietà nel file /.gitmodules , ma penso che sia meglio disabilitare solo la modalità file.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.