Fai in modo che .gitignore ignori tutto tranne alcuni file


1701

Comprendo che un file .gitignore nasconde i file specificati dal controllo versione di Git. Ho un progetto (LaTeX) che genera molti file extra (.auth, .dvi, .pdf, log, ecc.) Mentre viene eseguito, ma non voglio che vengano tracciati.

Sono consapevole che potrei (forse dovrei) farlo in modo che tutti quei file vengano inseriti in una sottocartella separata nel progetto, poiché potrei quindi semplicemente ignorare la cartella.

Tuttavia, esiste un modo possibile per mantenere i file di output nella radice dell'albero del progetto e utilizzare .gitignore per ignorare tutto tranne i file che sto monitorando con Git? Qualcosa di simile a

# Ignore everything
*

# But not these files...
script.pl
template.latex
# etc...

12
Duplica di stackoverflow.com/q/9162919/321973 (so che è più recente, ma la risposta è più corretta). In realtà questa risposta è probabilmente la migliore
Tobias Kienzler,

Risposte:


2442

Un prefisso opzionale !che nega il modello; qualsiasi file corrispondente escluso da un modello precedente verrà nuovamente incluso. Se un modello negato corrisponde, questo sovrascriverà le origini dei modelli con precedenza inferiore.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# ...even if they are in subdirectories
!*/

# if the files to be tracked are in subdirectories
!*/a/b/file1.txt
!*/a/b/c/*

14
Sembra che anche questo "ignori" le sottocartelle, in modo tale che qualsiasi file chiamato "script.pl" in qualcosa di diverso dalla directory principale non venga trovato comunque. Sto usando questo ora (con * .pl) e tutti i file * .pl vengono ignorati anche se ce ne sono molti nelle sottodirectory sotto il file
.gitignore

38
@PandaWood Quel problema è stato sollevato qui (stackoverflow.com). È causato dalla prima espressione che corrisponde a tutto, comprese le directory, che non si può mai negare. Per risolvere, aggiungi (! * /), Che corrisponde a tutte le sottodirectory (ricorsivamente) nella directory corrente. Questo non aiuterà la risposta del genitore, che consiste nella whitelist di file specifici (se si trovano in sottodirectory, probabilmente vorrai specificare manualmente il percorso completo o utilizzare file .gitignore specifici della directory).
simont

40
Non sono riuscito a farlo funzionare. Sto ignorando una cartella (ad es. wp/) Ma non voglio ignorare alcuni file in profondità in quella cartella (ad es wp/path/to/some/location/*.). L'unico modo per farlo funzionare eragit add -f wp/path/to/some/location/*
trusktr,

13
@trusktr Usa l' !*/eccezione di simont
Tobias Kienzler,

7
Accidenti a quell'ultima regola: !*/fa tutta la differenza nei miei inutili tentativi di .gitignorefar funzionare un file per farlo funzionare. Grazie mille.
racl101,

628

Se si desidera ignorare l'intero contenuto di una directory tranne un file al suo interno, è possibile scrivere una coppia di regole per ciascuna directory nel percorso del file. Ad esempio .gitignore per ignorare la cartella pippo tranne che da pippo / pluto / paperino.xml

.gitignore

pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml

58
Risposta eccellente, ma vale la pena notare che chiunque si imbatterà più tardi in questo fooe nonfoo/* sono gli stessi. Perché questo funzioni, è necessario utilizzare per la cartella di basefoo/*
thislooksfun

20
@Mayank Pippo è Pippo in italiano mentre Paperino è Paperino e Plutone è lo stesso che in inglese. In passato erano una tripletta molto comune di nomi di variabili per la programmazione di campioni. È stato bello rileggerli .. :)
Ghidello,

Ciò che dice @thislooksfun è importante se si desidera "escludere una cartella tranne il file x".
Czechnology,

8
non funziona per me: node_modules / *! node_modules / bootstrap
SuperUberDuper

1
@simple_human Sarebbe vero se ignorasse tutto nella radice del repository, o se avesse file .gitignore di cui occuparsi, all'interno delle directory menzionate.
xZero

245

Si desidera utilizzare /*invece *o */nella maggior parte dei casi

L'uso *è valido, ma funziona in modo ricorsivo. Non esaminerà le directory da allora in poi. Le persone consigliano di utilizzare !*/nuovamente la whitelist delle directory, ma in realtà è meglio inserire nella blacklist la cartella di livello più alto/*

# Blacklist files/folders in same directory as the .gitignore file
/*

# Whitelist some files
!.gitignore
!README.md

# Ignore all files named .DS_Store or ending with .log
**/.DS_Store
**.log

# Whitelist folder/a/b1/ and folder/a/b2/
# trailing "/" is optional for folders, may match file though.
# "/" is NOT optional when followed by a *
!folder/
folder/*
!folder/a/
folder/a/*
!folder/a/b1/
!folder/a/b2/
!folder/a/file.txt

# Adding to the above, this also works...
!/folder/a/deeply
/folder/a/deeply/*
!/folder/a/deeply/nested
/folder/a/deeply/nested/*
!/folder/a/deeply/nested/subfolder

Il codice di cui sopra sarebbe ignorare tutti i file ad eccezione di .gitignore, README.md, folder/a/file.txt, folder/a/b1/ed folder/a/b2/e tutto quanto contenuto in quegli ultimi due cartelle. (E .DS_Storee*.log i file sarebbero stati ignorati in queste cartelle.)

Ovviamente potrei fare eg !/foldero !/.gitignoretroppo.

Ulteriori informazioni: http://git-scm.com/docs/gitignore


3
Molto intelligente, grazie. IMO, questo è il modo migliore per farlo per i siti WordPress con il numero minimo di regole di inclusione. Inoltre, eventuali nuovi plug-in, temi o aggiornamenti WP non vengono rimossi o aggiunti senza la tua esplicita autorizzazione. Quando utilizzo GitHub Desktop trovo che i .DS_Storefile non vengano ignorati, ma tramite riga di comando questo non è un problema. Per ovviare a questo ho dovuto spostare **/.DS_Storetutte le altre regole di seguito.
Jibran,

7
Il mio evidenziatore di sintassi interiore sta avendo una strana reazione al titolo del tuo post.
Ha iniziato il

3
Gracias! puoi anche inserire nella whitelist un file in una cartella ..! /some/folder/file.txt
PodTech.io

Fantastico, usare / * invece di * risolto tutti i miei problemi quando le risposte sopra non lo facevano. La mia unica domanda ora è qual è la differenza tra! / Cartella e! / Cartella / *? Se uso la cartella! / Senza il *, continua comunque a rilevare le modifiche a tutti i file nella cartella.
dallin

1
@dallin non c'è differenza. Uno autorizza una cartella e l'altro autorizza i figli di quella cartella, il che fa la stessa cosa. L'unico problema è una cartella o un genitore di file deve essere whitelist prima di poter essere nella lista bianca, quindi non si può fare /*allora !/nested/folder/*(o equivalente !/nested/folder) senza fare !/nested/o !/nestedprima! (e probabilmente /nested/*nel mezzo). Un trucco da ricordare è che se stai inserendo nella whitelist una sottocartella profondamente annidata, devi annerire i bambini in ogni sottocartella e quelle liste nere finiranno con la "stella a stella" ...
Ryan Taylor,

75

Un po 'più specifico:

Esempio: ignora tutto in webroot/cache- ma continua webroot/cache/.htaccess.

Notare la barra (/) dopo la cachecartella:

NON RIESCE

webroot/cache*
!webroot/cache/.htaccess

LAVORI

webroot/cache/*
!webroot/cache/.htaccess

Se stai usando VS Code, fai attenzione a non leggere male il colore del file dopo averlo applicato a una cartella con .gitkeep perché il nome della cartella diventerà verde ma il file .gitkeep diventerà grigio proprio come tutti gli altri file ignorati; .gitkeep sembrerà ignorato ma dovresti vedere che c'è una 'U' sul lato destro, a indicare che è stata rilevata
OzzyTheGiant


28

Per ignorare alcuni file in una directory, devi farlo nell'ordine corretto :

Ad esempio, ignora tutto nella cartella "applicazione" tranne index.php e la cartella "config" presta attenzione all'ordine .

Devi prima negare ciò che vuoi.

NON RIESCE

application/*

!application/config/*

!application/index.php

LAVORI

!application/config/*

!application/index.php

application/*


38
Sbagliato. Neghi dopo il "ignora tutto".
Carlos,

2
Non farti ingannare git statusper verificare se le tue modifiche .gitignorefunzionano come previsto
Philippe Rathé,

10
Se git statusnon ti dirà cosa sta guardando e cosa viene ignorato, come puoi sapere se funziona?
Kris,

1
@kris Cancella prima la cache git. Esegui prima un "git rm --cached *", quindi puoi fare un "git add --all", quindi uno "stato git" ti mostrerà tutte le nuove modifiche di gitignore.
Mark McCorkle,

20

È possibile utilizzare git config status.showUntrackedFiles noe tutti i file non tracciati verranno nascosti da te. Vedi man git-configper i dettagli.


Questo è fantastico se vuoi solo impegnare alcuni file su molti!
Josh M.

16

Per escludere la cartella da .gitignore, è possibile eseguire le seguenti operazioni.

!app/

app/*
!app/bower_components/

app/bower_components/*
!app/bower_components/highcharts/

Ciò ignorerà tutti i file / sottocartelle all'interno ad bower_componentseccezione di /highcharts.


14

Ci sono un sacco di domande simili su questo, quindi posterò quello che ho scritto prima:

L'unico modo per farlo funzionare sulla mia macchina era farlo in questo modo:

# Ignore all directories, and all sub-directories, and it's contents:
*/*

#Now ignore all files in the current directory 
#(This fails to ignore files without a ".", for example 
#'file.txt' works, but 
#'file' doesn't):
*.*

#Only Include these specific directories and subdirectories and files if you wish:
!wordpress/somefile.jpg
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*

Nota come devi consentire esplicitamente il contenuto per ogni livello che desideri includere. Quindi, se ho sottodirectory 5 temi profondi, devo ancora precisarlo.

Questo è dal commento di @ Yarin qui: https://stackoverflow.com/a/5250314/1696153

Questi erano argomenti utili:

Ho anche provato

*
*/*
**/**

e **/wp-content/themes/**

o /wp-content/themes/**/*

Niente di tutto ciò ha funzionato neanche per me. Molte tracce ed errori!


2
Questo è l'unico metodo che funziona per includere esclusivamente determinate estensioni di file. Ancora meglio, rende la grande arte ASCII: gist.github.com/Wolfgange3311999/91c671f5e4d3c56cf5a1
Matthew D. Scholefield,

10

Ho avuto un problema con la sottocartella.

Non funziona:

/custom/*
!/custom/config/foo.yml.dist

Lavori:

/custom/config/*
!/custom/config/foo.yml.dist

9

Ho provato tutte le risposte come indicato sopra, ma nessuna ha funzionato per me. Dopo aver letto la documentazione di gitignore ( qui ) ho scoperto che se si esclude prima una cartella che i nomi dei file nella sottocartella non vengono indicizzati. Quindi, se in seguito si utilizza il punto esclamativo per includere un file, questo non viene trovato nell'indice e quindi non viene incluso nel client Git.

Questo era il modo di trovare la soluzione. Ho iniziato con l'aggiunta di eccezioni per tutte le sottocartelle nel mio albero delle cartelle per farlo funzionare, il che è un lavoro infernale. Successivamente sono stato in grado di compattare la configurazione dettagliata con la configurazione seguente, il che è un po 'contrario alla documentazione.

.Gitignore funzionante:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' subfolder
/Pro/3rdparty/*
!Pro/3rdparty/domain/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

Di conseguenza, vedo nel mio client git che solo i due file all'interno della cartella Pro / 3rdparty / domain / modulename / sono stati messi in scena per il prossimo commit, ed era esattamente quello che stavo cercando.

E se devi inserire nella whitelist diverse sottocartelle della stessa cartella, raggruppa le righe del punto esclamativo sotto l'istruzione exclude in questo modo:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' & 'hosting' subfolders
/Pro/3rdparty/*
!Pro/3rdparty/domain/
!Pro/3rdparty/hosting/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

# Ignore the 'hosting' folder, except for the 'modulename' subfolder
Pro/3rdparty/hosting/*
!Pro/3rdparty/hosting/modulename/

Altrimenti non funzionerà come previsto.


Finalmente una risposta che ha funzionato. Mi chiedo quando capirò come funziona .gitignore
David

8

Questo è ciò che ha funzionato per me, volevo impegnare un solo plug-in Cordova nel repository:

...
plugins/*
!plugins/cordova-plugin-app-customization

8

So di essere in ritardo per la festa, ma ecco la mia risposta.

Come ha detto @Joakim, per ignorare un file, puoi usare qualcosa come sotto.

# Ignore everything
*

# But not these files...
!.gitignore
!someFile.txt

ma se il file si trova nelle directory nidificate, è un po 'difficile scrivere manualmente le regole.

Ad esempio, se vogliamo saltare tutti i file in un gitprogetto, ma non in a.txtcui si trova aDir/anotherDir/someOtherDir/aDir/bDir/cDir. Quindi, la nostra .gitignoresarà qualcosa del genere

# Skip all files
*

# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Quanto sopra indicato .gitignore file salterà tutte le directory e i file tranne!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Come avrai notato, è difficile definire quelle regole.

Per risolvere questo ostacolo, ho creato una semplice applicazione console chiamata git-do-not-ignore che genererà le regole per te. Ho ospitato il progetto in github con istruzioni dettagliate.

Esempio di utilizzo

java -jar git-do-not-ignore.jar "aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt"

Produzione

!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

C'è anche una semplice versione web disponibile qui

Grazie.


7

Ho Jquery e Angular da pergolato. Bower li ha installati

/public_html/bower_components/jquery/dist/bunch-of-jquery-files
/public_html/bower_components/jquery/src/bunch-of-jquery-source-files
/public_html/bower_components/angular/angular-files

Il jquery ridotto a icona è all'interno della distdirectory e angolare è all'interno della angulardirectory. Avevo solo bisogno di eseguire il commit di file minimizzati su github. Qualche manomissione di .gitignore e questo è ciò che sono riuscito a evocare ...

/public_html/bower_components/jquery/*
!public_html/bower_components/jquery/dist
/public_html/bower_components/jquery/dist/*
!public_html/bower_components/jquery/dist/jquery.min.js
/public_html/bower_components/angular/*
!public_html/bower_components/angular/angular.min.js

Spero che qualcuno possa trovarlo utile.


7

Ecco come l'ho fatto:

# Ignore everything
*

# Whitelist anything that's a directory
!*/

# Whitelist some files
!.gitignore

# Whitelist this folder and everything inside of it
!wordpress/wp-content/themes/my-theme/**

# Ignore this folder inside that folder
wordpress/wp-content/themes/my-theme/node_modules

# Ignore this file recursively
**/.DS_Store

Utilizzalo gig status -uper visualizzare i singoli file in directory non tracciate ricorsivamente - con git statusvedresti solo le cartelle, che potrebbero indurti a pensare che tutto al loro interno è stato rintracciato


5

Soluzione semplice se è necessario ignorare tutto tranne pochi file e poche cartelle principali :

/*
!.gitignore
!showMe.txt
!my_visible_dir

La magia è in /*(come descritto sopra) ignora tutto nella cartella (root) MA NON ricorsivamente.


4

Ho anche avuto alcuni problemi con la negazione di singoli file. Sono stato in grado di impegnarli, ma il mio IDE (IntelliJ) si è sempre lamentato dei file ignorati, che vengono monitorati.

git ls-files -i --exclude-from .gitignore

Visualizzati i due file, che ho escluso in questo modo:

public/
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

Alla fine, questo ha funzionato per me:

public/*
!public/typo3conf/
public/typo3conf/*
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

La chiave era prima la negazione della cartella typo3conf/ .

Inoltre, sembra che l'ordine delle dichiarazioni non abbia importanza . Invece, è necessario annullare esplicitamente tutte le sottocartelle, prima di poter negare singoli file in esso.

La cartella !public/typo3conf/e il contenuto della cartella public/typo3conf/*sono due cose diverse per .gitignore.

Ottimo filo! Questo problema mi ha disturbato per un po ';)


3

Finora niente ha funzionato per me perché stavo cercando di aggiungere un barattolo dalla libreria.

Questo non ha funzionato:

build/*
!build/libs/*
!build/libs/
!build/libs/myjarfile.jar 

Questo ha funzionato:

build/*
!build/libs

3

Ho funzionato

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib

2

Aveva il problema simile a OP ma nessuna delle 10 risposte più votate funzionava davvero .
Alla fine ho scoperto quanto segue

Sintassi errata:

*
!bin/script.sh

Sintassi corretta:

*
!bin
!bin/script.sh

Spiegazione dalla pagina man di gitignore :

Un prefisso facoltativo "!" che nega il modello; qualsiasi file corrispondente escluso da un modello precedente verrà nuovamente incluso. Non è possibile includere nuovamente un file se viene esclusa una directory padre di quel file . Git non elenca le directory escluse per motivi di prestazioni, quindi eventuali pattern su file contenuti non hanno alcun effetto, indipendentemente da dove siano definiti.

Esempio esteso:

$ albero.

.
├── .gitignore
└── bin
    ├── ignore.txt
    └── sub
        └── folder
            └── path
                ├── other.sh
                └── script.sh

$ cat .gitignore

*
!.gitignore
!bin
!bin/sub
!bin/sub/folder
!bin/sub/folder/path
!bin/sub/folder/path/script.sh

$ git status --untracked-files --ignored

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        bin/sub/folder/path/script.sh

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        bin/ignore.txt
        bin/sub/folder/path/other.sh

nothing added to commit but untracked files present (use "git add" to track)

1

nocciolo

# Ignore everything
*

# But not these files...
!script.pl
!template.latex

E probabilmente includono:

!.gitignore

Riferimento

Da https://git-scm.com/docs/gitignore :

Un prefisso opzionale " !" che nega il modello; qualsiasi file corrispondente escluso da un modello precedente verrà nuovamente incluso. Non è possibile includere nuovamente un file se viene esclusa una directory padre di quel file. Git non elenca le directory escluse per motivi di prestazioni, quindi eventuali pattern su file contenuti non hanno alcun effetto, indipendentemente da dove siano definiti. Metti una barra rovesciata (" \") davanti al primo " !" per i modelli che iniziano con un " !" letterale , ad esempio " \!important!.txt".

...

Esempio per escludere tutto tranne una directory specifica foo/bar(notare il /*- senza la barra, il carattere jolly escluderebbe anche tutto all'interno foo/bar):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

0

Mi sembra di aver trovato qualcosa che ha funzionato per me, che nessun altro ha menzionato.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# And if you want to include a sub-directory and all sub-directory and files under it, but not all sub-directories
!subdir/
!subdir/**/*

Fondamentalmente, sembra negare che una sottodirectory venga ignorata, devi avere due voci, una per la sottodirectory stessa !subdir/e poi un'altra che si espande in tutti i file e le cartelle sottostanti!subdir/**/*

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.