Spiega quale regola gitignore sta ignorando il mio file


310

C'è un modo per capire perché alcuni file vengono ignorati da git (ovvero quale regola in un .gitignorefile sta causando l'ignoramento del file)?

Immagina di avere questo (o uno scenario molto più complesso, con centinaia di cartelle e decine di .gitignorefile:

/
-.gitignore
-folder/
    -.gitignore
    -subfolder/
              -.gitignore
              -file.txt

Se git add folder/subfolder/file.txteseguo git, potrei lamentarmi del fatto che è stato ignorato:

The following paths are ignored by one of your .gitignore files:
folder/subfolder/file.txt
Use -f if you really want to add them.

C'è un modo per sapere quale tra tutti i possibili .gitignoreha una regola per ignorare questo file e mostrare anche la regola? Piace:

The following paths are ignored by your folder/.gitignore file (line 12: *.txt)
folder/subfolder/file.txt
Use -f if you really want to add them.

O semplicemente:

$ git why-is-ignored folder/subfolder/file.txt
folder/.gitignore:12:*.txt

4
Nota: git check-ignorepresto (git1.8.5 / 1.9) avrà --no-indexun'opzione. Vedi la mia risposta qui sotto
VonC

Nota: GIT_TRACE_EXCLUDE=1 git statuspresto sarà un ulteriore modo per eseguire il debug delle .gitignoreregole. Vedi la mia risposta modificata di seguito
VonC

Post di blog rilevante: danielcompton.net/2016/04/21/… .
krlmlr,

Risposte:


643
git check-ignore -v filename

Vedi la pagina man per maggiori dettagli.

Segue la risposta originale:

git al momento non fornisce nulla di simile. Ma dopo aver visto la tua domanda ho cercato su Google e ho scoperto che nel 2009 questa funzione era stata richiesta e parzialmente implementata . Dopo aver letto il thread, mi sono reso conto che non sarebbe stato troppo lavoro per farlo correttamente, quindi ho iniziato a lavorare su una patch e spero di averlo finito nel prossimo giorno o due. Aggiornerò questa risposta quando sarà pronta.

AGGIORNAMENTO: Wow, è stato molto più difficile di quanto mi aspettassi. Le viscere del gittrattamento da escludere sono piuttosto criptiche. Comunque, ecco una serie quasi terminata di commit che si applicano alla mastersuccursale a monte di oggi . La suite di test è completa al 99%, ma non ho ancora finito di gestire l' --stdinopzione. Spero di riuscire a farlo questo fine settimana, quindi inviare le mie patch alla mailing list di git.

Nel frattempo, accolgo con favore i test da chiunque sia in grado di farlo - basta clonare dal mio gitfork , controllare il check-ignoreramo e compilarlo normalmente.

AGGIORNAMENTO 2: è fatto! L'ultima versione è su github come sopra, e ho inviato le serie di patch alla mailing list di git per la revisione tra pari. Vediamo cosa pensano ...

AGGIORNAMENTO 3: Dopo diversi mesi di hacking / recensioni di patch / discussioni / attese, sono lieto di poter dire che questa funzione ha ora raggiunto il masterramo di git e sarà disponibile nella prossima versione (1.8.2, prevista 8 ° Marzo 2013). Ecco la check-ignorepagina del manuale . Accidenti, è stato molto più lavoro di quanto mi aspettassi!

AGGIORNAMENTO 4: Se sei interessato alla storia completa di come questa risposta si è evoluta e la funzionalità è stata implementata, dai un'occhiata all'episodio n. 32 del podcast di GitMinutes .


2
Sto usando 1.8.2 e git check-ignorenon faccio nulla.
zakdances,

3
@yourfriendzak Senza ombra di dubbio, git check-ignoreè presente e funziona in 1.8.2. Se il comportamento non è quello che ti aspetti, ti suggerisco di (ri) leggere la pagina del manuale e, se non lo è ancora, ti preghiamo di inviare una segnalazione di bug corretta sulla mailing list di git. Solo dire che non fa nulla non è molto utile. Mi aspetto che tu l'abbia probabilmente eseguito su un file non ignorato e mi aspetti erroneamente un po 'di output (anche se probabilmente aggiungerò il supporto per --show-unmatchedla --verbosemodalità di output in futuro).
Adam Spires,

1
@AdamSpiers hai ragione. Avrei dovuto specificare che quando eseguo il comando, non viene stampato nulla. Nessun messaggio di errore, nessun messaggio di successo, nessuna informazione. Viene visualizzato solo il successivo prompt vuoto. Quindi, ho ragione di ritenere che in determinate circostanze si prevede un comportamento "senza output"?
zakdances,

1
@AdamSpiers grazie mille per questo! Dopo 3 giorni di indagine, mi hai appena aiutato a rintracciare la causa di un build fallito a causa di un file ignorato a livello globale in .gitignore_global! Non sapevo nemmeno che fosse una cosa!
BenBtg,

3
Non capita tutti i giorni di vedere uno sviluppatore Stack Overflow apportare così tante modifiche per implementare una funzione di sviluppo. Wow e rispetto.
user3613932

18

Aggiornamento git 2.8 (marzo 2016):

GIT_TRACE_EXCLUDE=1 git status

Vedi " Un modo per convalidare il .gitignorefile "

Ciò è complementare a quanto git check-ignore -vdescritto di seguito.


Risposta originale: settembre 2013 (git 1.8.2, quindi 1.8.5+):

git check-ignoremigliora di nuovo in git 1.8.5 / 1.9 (Q4 2013) :

" git check-ignore" segue la stessa regola di " git add" e " git status" in quanto il meccanismo ignora / exclude non ha effetto sui percorsi già tracciati.
Con l' --no-indexopzione " ", può essere utilizzato per diagnosticare quali percorsi che avrebbero dovuto essere ignorati siano stati erroneamente aggiunti all'indice .

Vedi commit 8231fa6 da https://github.com/flashydave :

check-ignoreattualmente mostra come le .gitignoreregole tratteranno i percorsi non tracciati. I percorsi tracciati non generano output utili.
Ciò impedisce il debug del motivo per cui un percorso è stato tracciato in modo imprevisto, a meno che quel percorso non venga prima rimosso dall'indice con git rm --cached <path>.

L'opzione --no-indexindica al comando di ignorare il controllo per il percorso che si trova nell'indice e quindi consente anche il controllo dei percorsi tracciati.

Sebbene questo comportamento si discosti dalle caratteristiche git adde il git statussuo caso d'uso non è suscettibile di causare confusione da parte dell'utente.

Gli script di test sono aumentati per verificare questa opzione rispetto agli ignori standard per garantire un comportamento corretto.


--no-index::

Non guardare nell'indice quando si eseguono i controlli.
Questo può essere usato:

  • per eseguire il debug del motivo per cui un percorso è stato tracciato da eg git add .e non è stato ignorato dalle regole come previsto dall'utente o
  • quando si sviluppano modelli che includono la negazione per abbinare un percorso precedentemente aggiunto git add -f.

4

Non riesco a trovare nulla nella pagina man ma ecco uno script veloce e sporco che controllerà il tuo file in ogni directory principale per vedere se può essere aggiunto da git. Eseguilo nella directory contenente il file del problema come:

test-add.sh STOP_DIR FILENAME

dove si STOP_DIRtrova la directory di livello superiore del progetto Git ed FILENAMEè il nome del file del problema (senza percorso). Crea un file vuoto con lo stesso nome ad ogni livello della gerarchia (se non esiste) e prova git add -na vedere se può essere aggiunto (ripulisce dopo se stesso). Emette qualcosa del tipo:

FAILED:    /dir/1/2/3
SUCCEEDED: /dir/1/2

Il copione:

#!/usr/bin/env bash
TOP=$1
FILE=$2
DIR=`pwd`
while : ; do
  TMPFILE=1
  F=$DIR/$FILE
  if [ ! -f $F ]; then
    touch $F
    TMPFILE=0
  fi
  git add -n $F >/dev/null 2>&1
  if [ $? = 0 ]; then
    echo "SUCCEEDED: $DIR"
  else
    echo "FAILED:    $DIR"
  fi
  if [ $TMPFILE = 0 ]; then
    rm $F
  fi
  DIR=${DIR%/*}
  if [ "$DIR" \< "$TOP" ]; then
    break
  fi
done 

1

Per aggiungere alla risposta principale dell'utilizzo git check-ignore -v filename(grazie a BTW) ho scoperto che il mio file .gitignore stava bloccando tutto perché c'era una nuova riga dopo un carattere jolly, quindi avevo:

* .sublime-project

come esempio. Ho appena rimosso la nuova riga e voilà! È stato risolto.

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.