Was ist der Unterschied zwischen Git, das Verzeichnis und Verzeichnis / * ignoriert?

108

Ich bin verwirrt darüber, wie man den Inhalt eines Verzeichnisses in git richtig ignoriert.

Angenommen, ich habe die folgende Verzeichnisstruktur:

my_project  
     |--www  
         |--1.txt  
         |--2.txt
     |--.gitignore

Was ist der Unterschied zwischen diesem:

www

Und das?

www/*

Der Grund, warum ich diese Frage stelle, ist: Wenn in git ein Verzeichnis leer ist, wird git ein solches leeres Verzeichnis nicht in das Repository aufnehmen. Also habe ich die Lösung ausprobiert, bei der eine zusätzliche Gitkeep-Datei unter dem Verzeichnis hinzugefügt wird, damit sie nicht leer ist. Als ich diese Lösung ausprobiert habe, schreibe ich in der .gitignore-Datei wie folgt:

www
!*.gitkeep

Es funktioniert nicht (Ich beabsichtige, alle Inhalte unter www zu ignorieren, aber das Verzeichnis beizubehalten). Aber wenn ich folgendes versuche:

www/* 
!*.gitkeep

Dann funktioniert es! Ich denke, es muss einige Unterschiede zwischen den beiden Ansätzen geben.

Aaron Shen
quelle
Ein einfacher Unterschied zwischen binund bin/besteht darin, dass erstere Dateien oder Ordner ignorieren, letztere nur Ordner. Ich kenne den Unterschied nicht mitbin/*
Colonel Panic

Antworten:

203

Im moment gibt es Unterschiede zwischen www, www/und www/*.

Grundsätzlich finden Sie in der Dokumentation und in meinen eigenen Tests wwweine Übereinstimmung mit einer Datei oder einem Verzeichnis, die www/nur mit einem Verzeichnis www/*übereinstimmt , während Verzeichnisse und Dateien darin übereinstimmen www.

Ich werde nur auf die Unterschiede zwischen www/und www/*hier eingehen, da die Unterschiede zwischen wwwund www/offensichtlich sind.

Denn www/git ignoriert das Verzeichnis wwwselbst, was bedeutet, dass git nicht einmal hineinschaut. Aber für www/*git überprüft git alle Dateien / Ordner im Inneren wwwund ignoriert sie alle mit dem Muster *. Es scheint zu den gleichen Ergebnissen zu führen, da git einen leeren Ordner nicht verfolgt, wwwwenn alle untergeordneten Dateien / Ordner ignoriert werden. Und in der Tat werden die Ergebnisse für den Fall von OP mit www/oder für sich www/*allein keinen Unterschied machen . Aber es macht Unterschiede, wenn es mit anderen Regeln kombiniert wird.

Was ist zum Beispiel, wenn wir www/1.txtalle anderen nur einschließen, aber ignorieren wollen www?

Folgendes .gitignorewird nicht funktionieren.

www/
!www/1.txt

Während das Folgende .gitignorefunktioniert, warum?

www/*
!www/1.txt

Bei ersteren ignoriert git das Verzeichnis einfach wwwund schaut nicht einmal hinein, um es www/1.txterneut einzuschließen. Die erste Regel schließt das übergeordnete Verzeichnis aus, wwwjedoch nicht www/1.txt, und www/1.txtkann daher nicht " wieder aufgenommen " werden.

Bei letzterem ignoriert git jedoch zuerst alle Dateien / Ordner unter wwwund schließt dann wieder eine davon ein www/1.txt.

In diesem Beispiel können die folgenden Zeilen in der Dokumentation hilfreich sein:

Ein optionales Präfix "!" was das Muster negiert; Alle übereinstimmenden Dateien, die von einem vorherigen Muster ausgeschlossen wurden, werden wieder aufgenommen. Es ist nicht möglich, eine Datei erneut einzuschließen, wenn ein übergeordnetes Verzeichnis dieser Datei ausgeschlossen ist.

Landys
quelle
Glaubst du das nicht www/1.txtund www/würdest dann das Gleiche tun wie beim zweiten Ansatz ...
Naveed Butt
8

Ich analysiere nur die Dokumentation, und soweit ich das beurteilen kann, unterscheiden sie sich nur in fortgeschritteneren Mustern, z

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

Ich habe Test der oben und wenn Sie ersetzen !/foomit !/foo/*, man bekommt in der Tat ein anderes Ergebnis.

Hinweis

foo

Schließt jede Datei aus foo, aber

foo/

schließt nur Verzeichnisse mit dem Namen foo aus.

Djechlin
quelle
3

Abgesehen von den perfekten Antworten, die Sie bereits erhalten haben, sollten Sie beachten, dass Sie sie .gitignoreüberall in Ihrem Projekt haben können, einschließlich Unterordnern.

So möchten , wenn Sie alle Dateien in ignorieren www, aber whant der wwwOrdner versioniert werden, anstatt einen leeren verwenden .gitkeep, .dummyoder was auch immer nennen Sie sich entscheiden, warum nicht nutzen .gitignorees, zu sagen , alle Dateien zu ignorieren?

/
|- .gitignore   (a)
\- www
    |- .gitignore   (b)
    |- 1.jpg
    \- 2.jpg

Im Stammverzeichnis .gitignore(a) sagen Sie nichts über den wwwOrdner oder dessen Inhalt.

In www/.gitignore(b) geben Sie Folgendes ein:

# ignore all files in this folder except this .gitignore
*
!.gitignore

Auf diese Weise sieht alles besser organisiert aus (zumindest für mich).

Carlos Campderrós
quelle
1

Um alles in einem Verzeichnis außer Punktedateien zu ignorieren, können Sie das folgende Glob-Muster in Ihrem Verzeichnis verwenden .gitignore:

www/[^.]*

Sie brauchen also kein Extra .gitignore, sondern fügen einfach eine .keepDatei zu Ihrem wwwVerzeichnis hinzu.

Koen.
quelle