Quando usare la barra iniziale in gitignore


108

Sto cercando di capire più chiaramente la .gitignoresintassi, e in particolare per quanto riguarda https://github.com/github/gitignore gitignores.

Vedo che la barra iniziale viene utilizzata per abbinare solo i nomi di percorso relativi alla posizione del .gitignorefile (da http://git-scm.com/docs/gitignore ):

Una barra iniziale corrisponde all'inizio del nome del percorso. Ad esempio, "/*.c" corrisponde a "cat-file.c" ma non a "mozilla-sha1 / sha1.c".

Ma cosa succede quando rimuovo la barra principale? Per quanto ho capito, ci sono due casi:

  1. Se il pattern non contiene una barra (o contiene solo una barra finale, il che significa che deve corrispondere a una directory), la ricerca viene eseguita all'interno dell'intero albero delle directory. Ad esempio, il modello dir/corrisponderà <root>/dir, <root>/a/dir, <root>/a/b/c/.../dir, ecc, dove <root>è la posizione del .gitignorefile.
  2. Se il modello contiene una barra, che non si trova nella posizione finale (non è l'ultimo carattere), viene trovata solo la corrispondenza con i nomi di percorso relativi alla .gitignoreposizione del file.

Questi sono gli esempi che ho fatto per verificare questo comportamento:

# Directory structure:
<root>
├─ dir/
│   └─ test
├─ src/
│   ├─ dir/
│   │   └─ test
test file is there only because Git does not track empty directories.

Primo test:

# .gitignore
dir/

# git status
nothing to commit

Quindi Git ignora entrambe le dirdirectory. Ciò è coerente con il caso numero 1: il pattern non ha barre (eccetto quello finale), quindi Git sta guardando l'intero albero delle directory, ignorando tutto ciò che corrisponde al pattern.

Secondo test:

# .gitignore
/dir/

# git status
Untracked files:
    src/

In questo caso, Git ignora solo la dirdirectory direttamente sotto la directory root, grazie alla barra iniziale nel pattern.

Terza prova:

# .gitignore
dir/*

# git status
Untracked files:
    src/

Questo è coerente con il caso numero 2: il pattern ha una barra al suo interno, quindi è considerato come un percorso a partire dalla directory root.

Adesso è il momento della vera domanda. Consideriamo questo file gitignore : quando ignorano la directory downloader/, ad esempio, non stanno effettivamente ignorando ogni singola downloaderdirectory trovata nell'intero albero delle directory? Questo è ciò che sono spinto a pensare da quello che ho visto prima sul funzionamento di Git.

Quindi, se mi capita di avere un modulo personalizzato con una downloaderdirectory al suo interno, verrà ignorato inaspettatamente così come quello normale nella radice di Magento? Questa è una domanda un po 'retorica perché in realtà mi è già successo, producendo un bug davvero difficile da trovare.

Quindi, nel .gitignorefile Magento (a cui mi riferisco solo a titolo di esempio, btw) molti modelli contengono barre, quindi sono abbinati correttamente ai nomi di percorso che iniziano dalla radice, ma ci sono alcuni casi, come downloader/o errors/quello , se non sbaglio, sono potenzialmente pericolosi e che dovrebbero probabilmente essere modificati in /downloader/e /errors/.

Come domanda più generale, dovrei sempre usare la barra iniziale per i modelli che non contengono barre (eccetto quella finale) quando voglio selezionare un percorso esplicitamente a partire da root, e non usarlo per modelli contenenti barre, o dovrei usa sempre la barra principale per chiarezza? Cosa ne pensi?

Grazie per la lettura e scusa per il lungo post.


8
Ottima domanda e spiegazione davvero bella, anche a me ha dato fastidio e la tua ricerca mi ha chiarito le cose. Dopo aver letto questo, direi che è buona norma iniziare sempre i percorsi con barra se dovessero partire da root, rende l'intenzione più ovvia.
Martinsos

4
Grazie :) Sono d'accordo con la tua nota sull'uso delle barre per rendere le intenzioni più esplicite.
swahnee

8
Questo dovrebbe far parte della documentazione .gitignore. Molto più facile da capire!
rmorrin

Mi piacerebbe vedere questo fantastico post suddiviso in sezioni di domande e risposte ...
Barett

Risposte:


25

Volevo solo riassumere per un possibile riferimento futuro rapido: la barra principale fissa la corrispondenza alla radice. Pertanto, nell'esempio seguente, senza la barra, il carattere jolly escluderebbe anche tutto all'interno di foo perché prenderebbe *e si sposterebbe in modo ricorsivo lungo l'albero. Tuttavia, con /*, esclude tutto tranne la cartella pippo e il suo contenuto:

$ cat .gitignore
/*
!/foo

24

Hai risposto completamente alla tua domanda. Se guardi più da vicino il repository github / gitignore, vedrai che la maggior parte dei file usa regole incoerenti su come vengono scritti i pattern; è molto probabile che la maggior parte sia stata fornita da persone che non si sono preoccupate di leggere la documentazione né di provare le cose come hai fatto tu.

Quindi, se questo aiuta: hai ragione, sii fiducioso.

Se vedi errori in progetti di collaborazione come questo, non esitare a contribuire con le tue conoscenze. C'è anche qualche precedente se hai bisogno di rafforzare ulteriormente la tua fiducia.

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.