Wie ignoriere ich Dateien in einem Verzeichnis in Git?

544

Wie lautet die richtige Syntax für die .gitignoreDatei, um Dateien in einem Verzeichnis zu ignorieren?

Wäre es

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*

oder

/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*

?

Chris McKnight
quelle
5
funktioniert die .gitignoredifferenzierbare zwischen Dateien und Verzeichnissen , dass es ignoriert? Bedeutet datavs zum Beispiel data/verschiedene Dinge?
Charlie Parker
6
@CharlieParker yes-ish: dataignoriert übereinstimmende Dateien und Verzeichnisse, data/ignoriert nur übereinstimmende Verzeichnisse.
Jox
Denken Sie immer daran, wenn Sie die Datei, die Sie ignorieren möchten, inszeniert oder festgeschrieben haben, gibt es keine Möglichkeit, sie zu ignorieren :( Nur meine 2 Cent, nachdem Sie gedacht haben, ich hätte mein Muster falsch verstanden und eine Viertelstunde verschwendet.
Adam
@Adam richtig, Sie müssten .gitignore aktualisieren und dann die Datei entfernen / git rm - zwischengespeichert.
Chris McKnight

Antworten:

374

MUSTERFORMAT

  • Eine leere Zeile entspricht keinen Dateien und kann daher als Trennzeichen für die Lesbarkeit dienen.

  • Eine Zeile, die mit beginnt, #dient als Kommentar.

  • Ein optionales Präfix, !das das Muster negiert. Alle übereinstimmenden Dateien, die von einem vorherigen Muster ausgeschlossen wurden, werden wieder aufgenommen. Wenn ein negiertes Muster übereinstimmt, überschreibt dies Musterquellen mit niedrigerer Priorität.

  • Wenn das Muster mit einem Schrägstrich endet, wird es zum Zweck der folgenden Beschreibung entfernt, es wird jedoch nur eine Übereinstimmung mit einem Verzeichnis gefunden. Mit anderen Worten, stimmt mit foo/einem Verzeichnis foound Pfaden darunter fooüberein, stimmt jedoch nicht mit einer regulären Datei oder einem symbolischen Link überein (dies stimmt mit der allgemeinen Funktionsweise von pathspec in git überein).

  • Wenn das Muster keinen Schrägstrich enthält /, behandelt git es als Shell-Glob-Muster und sucht nach einer Übereinstimmung mit dem Pfadnamen relativ zum Speicherort der .gitignoreDatei (relativ zur obersten Ebene des Arbeitsbaums, wenn nicht aus einer .gitignoreDatei).

  • Andernfalls behandelt git das Muster als Shell-Glob, der für den Verzehr fnmatch(3)mit dem FNM_PATHNAMEFlag geeignet ist : Platzhalter im Muster stimmen nicht mit einem /im Pfadnamen überein . Zum Beispiel Documentation/*.htmlpasst Documentation/git.htmlaber nicht Documentation/ppc/ppc.htmloder tools/perf/Documentation/perf.html.

  • Ein führender Schrägstrich entspricht dem Anfang des Pfadnamens. Zum Beispiel /*.cpasst cat-file.caber nicht mozilla-sha1/sha1.c.

Mehr finden Sie hier

git help gitignore
oder
man gitignore

Op De Cirkel
quelle
2
Wie kann ich eine Gitignore-Datei auf die oberste Ebene stellen und sie für jeden Ordner darunter verwenden? Vielen Dank.
Royi
104
-1 TL; DR und beantwortet die Frage kaum. Es geht um Verzeichnisse, nicht um Dateien, daher ist der fettgedruckte Abschnitt nur ein Teil der mentalen Gymnastik. @ Jefromi war direkter.
Bob Stein
Ich habe den Mann gelesen, und die Antwort von @ Jefromi ist besser - solange Sie auch die Warnung von @ jox lesen - und die von @ Luke Hutton ist möglicherweise nützlicher, um z. B. IDE-Projektdateien zu ignorieren.
WillC
1
Dies ist eigentlich ein Copy-Paste aus der Git-Dokumentation
mcont
1
Nicht sicher, ob (im Wesentlichen) das Einfügen einer manSeite oder eines offiziellen Dokuments das beste Format für SO ist ...
jdk1.0
183

Es wäre das erstere. Gehen Sie auch nach Erweiterungen anstatt nach Ordnerstruktur.

Dh meine Beispiel-C # -Entwicklungs-Ignorierdatei:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

Aktualisieren

Ich dachte, ich würde ein Update aus den Kommentaren unten bereitstellen. Obwohl die Frage des OP nicht direkt beantwortet wird, finden Sie im Folgenden weitere Beispiele für die .gitignoreSyntax.

Community-Wiki (wird ständig aktualisiert):

.gitignore für Visual Studio-Projekte und -Lösungen

Weitere Beispiele mit spezifischem Sprachgebrauch finden Sie hier (dank Chris McKnights Kommentar):

https://github.com/github/gitignore

Luke Hutton
quelle
5
@ Stallman, das ist der range. So passt es *.Objauch *.obj.
Norbert
131

Pfade, die Schrägstriche enthalten, werden als relativ zu dem Verzeichnis angesehen, das die .gitignore-Datei enthält - normalerweise die oberste Ebene Ihres Repositorys. Sie können sie jedoch auch in Unterverzeichnissen ablegen.

Da die Pfade in allen von Ihnen angegebenen Beispielen Schrägstriche enthalten, sind die beiden Versionen identisch. Das einzige Mal, dass Sie einen führenden Schrägstrich einfügen müssen, ist, wenn noch keiner im Pfad vorhanden ist. Verwenden Sie beispielsweise, um foo nur auf der obersten Ebene des Repositorys zu ignorieren /foo. Durch einfaches Schreiben wird fooalles, was als foo bezeichnet wird, irgendwo im Repository ignoriert.

Ihre Platzhalter sind ebenfalls überflüssig. Wenn Sie ein gesamtes Verzeichnis ignorieren möchten, benennen Sie es einfach:

lib/model/om

Der einzige Grund, Platzhalter so zu verwenden, wie Sie es haben, ist, wenn Sie beabsichtigen, anschließend etwas im Verzeichnis zu ignorieren:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo
Cascabel
quelle
5
Bessere Erklärung als akzeptierte Antwort auf diese Frage
eerrzz
78

Ein führender Schrägstrich gibt an, dass der Ignoriereintrag nur für das Verzeichnis gültig sein soll, in dem sich die Gitignore-Datei befindet. Wenn Sie angeben *.o, werden alle .o-Dateien in diesem Verzeichnis und alle Unterverzeichnisse /*.oignoriert , während sie in diesem Verzeichnis einfach ignoriert werden, während sie wiederum /foo/*.onur in /foo/*.o ignoriert werden.

jørgensen
quelle
34

Wenn Sie eine Gitignore-Datei auf der obersten Ebene ablegen und für jeden Ordner darunter verwenden möchten, verwenden Sie sie /**/.

Um beispielsweise alle *.mapDateien in einem /src/main/Ordner und Unterordnern zu ignorieren, verwenden Sie:

/src/main/**/*.map
petrsyn
quelle
Ich musste das tun. Ich bin mir nicht sicher, warum du zwei brauchst **. Einer war genug für mich.
Novocaine
8
** stimmt auch mit Dateien in Unterverzeichnissen
überein
Vielen Dank für die Info @petrsyn
Novocaine
30

Beide Beispiele in der Frage sind tatsächlich sehr schlechte Beispiele, die zu Datenverlust führen können!

Mein Rat: Niemals /*an Verzeichnisse in .gitignore-Dateien anhängen , es sei denn, Sie haben einen guten Grund!

Ein guter Grund wäre zum Beispiel, was Jefromi schrieb: "Wenn Sie beabsichtigen, später etwas im Verzeichnis zu ignorieren" .

Der Grund, warum dies sonst nicht getan werden sollte, ist, dass das Anhängen /*an Verzeichnisse einerseits so funktioniert, dass alle Inhalte des Verzeichnisses ordnungsgemäß ignoriert werden, andererseits aber eine gefährliche Nebenwirkung hat:

Wenn Sie in Ihrem Repository ausführen git stash -u(um verfolgte und nicht verfolgte Dateien vorübergehend zu speichern) oder git clean -df(um nicht verfolgte, aber ignorierte Dateien zu löschen), werden alle Verzeichnisse, die mit einem angehängten ignoriert /*werden, irreversibel gelöscht !

Einige Hintergrundinformationen

Ich musste das auf die harte Tour lernen. Jemand in meinem Team hat /*an einige Verzeichnisse in unserem .gitignore angehängt. Im Laufe der Zeit hatte ich Gelegenheiten, in denen bestimmte Verzeichnisse plötzlich verschwanden. Verzeichnisse mit Gigabyte lokaler Daten, die von unserer Anwendung benötigt werden. Niemand konnte es erklären und ich musste immer alle Daten erneut herunterladen. Nach einer Weile bekam ich eine Vorstellung, dass es damit zu tun haben könnte git stash. Eines Tages wollte ich mein lokales Repo bereinigen (während ignorierte Dateien beibehalten wurden) und ich benutzte git clean -dfund wieder waren meine Daten weg. Diesmal hatte ich genug und untersuchte das Problem. Ich habe endlich herausgefunden, dass der Grund der angehängte ist /*.

Ich gehe davon aus, dass directory/*dies irgendwie dadurch erklärt werden kann, dass alle Inhalte des Verzeichnisses ignoriert werden, nicht jedoch das Verzeichnis selbst. Daher wird es weder als verfolgt betrachtet noch ignoriert, wenn Dinge gelöscht werden. Auch wenn git statusund git status --ignoredein etwas anderes Bild darauf geben.

Wie zu reproduzieren

Hier erfahren Sie, wie Sie das Verhalten reproduzieren. Ich benutze derzeit Git 2.8.4.

Ein Verzeichnis localdata/mit einer Dummy-Datei ( important.dat) wird in einem lokalen Git-Repository erstellt und der Inhalt wird durch Einfügen /localdata/*in die .gitignoreDatei ignoriert . Wenn jetzt einer der beiden genannten Git-Befehle ausgeführt wird, geht das Verzeichnis (unerwartet) verloren.

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

Wenn Sie eine git status --ignoredhier machen, erhalten Sie:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

Jetzt entweder tun

git stash -u
git stash pop

oder

git clean -df

In beiden Fällen ist das angeblich ignorierte Verzeichnis localdataverschwunden!

Ich bin mir nicht sicher, ob dies als Fehler angesehen werden kann, aber ich denke, es ist zumindest eine Funktion, die niemand braucht.

Ich werde das der Git-Entwicklungsliste melden und sehen, was sie darüber denken.

jox
quelle
15

Es wäre:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

oder möglicherweise sogar:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

Für den Fall, dass filterund formdie einzigen Verzeichnisse in lib sind, die ein baseUnterverzeichnis haben, das ignoriert werden muss (sehen Sie es als Beispiel dafür, was Sie mit den Sternchen tun können).

aefxx
quelle
14

Der erste. Diese Dateipfade sind relativ zu Ihrer Gitignore-Datei.

Unixmonkey
quelle
2
Dies gilt nur für Muster, die einen Schrägstrich enthalten. Ein einzelner Verzeichnisname wie "mydir" ignoriert auch Verzeichnisse (und Dateien), die sich in Unterordnern in beliebiger Tiefe befinden. Wenn Sie nur einen Schrägstrich voranstellen, wird er relativ zu der Stelle, an der sich Ihre .gitignore-Datei befindet.
Jox
4

Ich unterhalte einen GUI- und CLI-basierten Dienst, mit dem Sie .gitignoreunter https://www.gitignore.io ganz einfach Vorlagen erstellen können .

Sie können entweder die gewünschten Vorlagen in das Suchfeld eingeben oder den Befehlszeilenalias installieren und ausführen

$ gi swift,osx

Joe
quelle
0

Eine Beispiel- Gitignore- Datei kann für ein Android Studio-Projekt wie folgt aussehen

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle
Shirish Herwade
quelle