Wie kann ich einem Git-Repository ein leeres Verzeichnis hinzufügen?


4264

Wie kann ich einem Git-Repository ein leeres Verzeichnis (das keine Dateien enthält) hinzufügen?


16
Es ist zwar nicht nützlich, aber es gibt eine Möglichkeit, ein leeres (wirklich leeres) Verzeichnis in Ihr Repo zu hacken . checkoutBei aktuellen Git-Versionen ist dies jedoch nicht der Fall.
Zwei

335
@tiwo Ich bin nicht einverstanden, dass es nicht nützlich ist. Ihre Verzeichnishierarchie ist Teil Ihres Projekts und sollte daher versioniert werden.
JBentley

114
In meinem Fall möchte ich eine Verzeichnisstruktur für tmp-Dateien hinzufügen, nicht jedoch für die tmp-Dateien selbst. Auf diese Weise hat mein Tester die richtige Struktur (ansonsten gibt es Fehler), aber ich verstopfe meine Commits nicht mit tmp-Daten. Also ja, es ist nützlich für mich!
Adam Marshall

45
@AdamMarshall Ich denke, zwei sagten, dass der Hack nicht nützlich ist, da er beim Auschecken ignoriert wird. Tmp-Verzeichnisse klingen nach einer nützlichen Funktion für ein VCS.
Quantum7

31
Warum nicht die Prozedur, die die tmp-Dateien erstellt, auch das tmp-Verzeichnis erstellen?
RyPeck

Antworten:


4125

Eine andere Möglichkeit, ein Verzeichnis (fast) leer zu halten (im Repository), besteht darin, eine .gitignoreDatei in diesem Verzeichnis zu erstellen , die diese vier Zeilen enthält:

# Ignore everything in this directory
*
# Except this file
!.gitignore

Dann müssen Sie die Bestellung nicht so ausführen, wie Sie es in der Lösung von m104 tun müssen .

Dies bietet auch den Vorteil, dass Dateien in diesem Verzeichnis nicht als "nicht verfolgt" angezeigt werden, wenn Sie einen Git-Status ausführen.

Den Kommentar von @GreenAsJade dauerhaft machen:

Ich denke, es ist erwähnenswert, dass diese Lösung genau das tut, wonach die Frage gestellt wurde, aber vielleicht nicht das, wonach viele Leute, die sich diese Frage ansehen, gesucht haben. Diese Lösung garantiert, dass das Verzeichnis leer bleibt. Es heißt "Ich möchte wirklich nie, dass Dateien hier eingecheckt werden". Im Gegensatz zu "Ich habe hier noch keine Dateien zum Einchecken, aber ich brauche das Verzeichnis hier, Dateien kommen möglicherweise später".


25
Ich denke, die von @JohnMee vorgeschlagene README-Lösung sollte zusammen mit dieser verwendet werden. Die .gitignore-Datei enthält eine Erklärung, was wir von der Versionskontrolle fernhalten möchten, während die README-Datei den Zweck des Verzeichnisses erläutert, die beide sehr wichtige Informationen sind.
Pedromanoel

18
@pedromanoel Ich schreibe die Dokumentation, die Sie in READMEdie .gitignoreDatei einfügen würden (als Kommentare).
Carlos Campderrós

69
Finde den Unterschied 1: 1.) einen leeren Ordner, 2.) einen Ordner mit einer .gitignore-Datei. ;-)
Peter Perháč

6
Dies ist perfekt für Cache- Ordner.
duftend

10
Leider führt dies zu einem nicht leeren Verzeichnis, es hat eine einzige versteckte Datei.
Pedorro

1090

Das kannst du nicht. Siehe die Git-FAQ .

Derzeit erlaubt das Design des Git-Index (Staging-Bereich) nur das Auflisten von Dateien, und niemand, der kompetent genug ist, um die Änderung vorzunehmen, um leere Verzeichnisse zuzulassen, hat sich genug um diese Situation gekümmert, um Abhilfe zu schaffen.

Verzeichnisse werden automatisch hinzugefügt, wenn Dateien hinzugefügt werden. Das heißt, Verzeichnisse müssen niemals zum Repository hinzugefügt werden und werden nicht einzeln verfolgt.

Sie können " git add <dir>" sagen und es werden dort Dateien hinzugefügt.

Wenn Sie wirklich ein Verzeichnis benötigen, das an den Kassen vorhanden sein soll, sollten Sie eine Datei darin erstellen. .gitignore funktioniert gut für diesen Zweck; Sie können es leer lassen oder die Namen der Dateien eingeben, die voraussichtlich im Verzeichnis angezeigt werden.


67
Die Antwort unten ist VIEL besser. Die Tatsache, dass Git die Low-Level-Software nicht zulässt, ist mir weniger wichtig als die Art und Weise, wie Git tatsächlich verwendet wird, wenn ich ein leeres Verzeichnis benötige. Das Hinzufügen eines 2-Zeilen-Gitignore erscheint mir akzeptabel.
Amala

1
Nun, wenn man Dateien in ein neues Verzeichnis verschieben möchte, kann man dies nicht tun, git mvda Git sich darüber beschwert, dass das neue Verzeichnis nicht unter Versionskontrolle steht
lulalala

16
Für diese häufige Frage können Sie im gesamten Internet lesen: " Es ist unmöglich, Sie können nicht usw. ". Der .gitignoreTrick ist eine häufige Antwort und erfüllt viele Bedürfnisse. Es ist jedoch möglich , Git Track zu einem wirklich leeren Verzeichnis zu machen, siehe meine Antwort
ofavre

2
Obwohl je mehr ich darüber nachdenke, desto mehr fühlt sich an wie „SHA Hash - Wert des leeren String“, wenn es vorhanden ist , tatsächlich würde seine eine gut definierte Kennung für einen leeren Baum, es sei denn , es wäre unmöglich , zu sagen , ob das Objekt ein Baum oder ein Klecks.
Emil Lundberg

21
Ich habe viele Repos gesehen, die eine leere Datei verwenden, die .gitkeepzu diesem Zweck aufgerufen wurde.
Sukima

759

Erstellen Sie eine leere Datei mit dem Namen .gitkeepim Verzeichnis und fügen Sie diese hinzu.


58
Ich habe eine Antwort hinzugefügt , die zum Erstellen ermutigt .keep.
Acumenus

205
.gitkeepwurde von Git nicht verschrieben und wird die Leute dazu bringen, seine Bedeutung zu erraten, was sie zu Google-Suchanfragen führt, die sie hierher führen. Die .gitPräfixkonvention sollte für Dateien und Verzeichnisse reserviert sein, die Git selbst verwendet.
T-Mart

10
@ t-mart "Die .gitPräfixkonvention sollte reserviert werden ..." Warum? Fordert git diese Reservierung an?
Begrenzte Versöhnung

9
In diesem Fall wäre eine READMEoder ABOUTDatei genauso gut oder besser. Hinterlassen Sie eine Notiz für den nächsten Mann, so wie wir es alle vor URLs getan haben.
Dave

5
Funktioniert nicht, wenn Sie einen
Komponententest

436

Sie können jederzeit eine README-Datei in das Verzeichnis einfügen und erläutern, warum Sie dieses ansonsten leere Verzeichnis im Repository haben möchten.


39
+1, Guter Vorschlag, ein leeres Verzeichnis macht keinen Sinn, es sei denn, es wird in Zukunft verwendet. Erstellen Sie also eine README-Datei darin und schreiben Sie, wofür dieses Verzeichnis gedacht ist und welche Dateien in Zukunft dort abgelegt werden. Das löst beide Probleme.
Saeedgnu

63
@ilius Unsinn. Eine Verzeichnisstruktur mit leeren Verzeichnissen kann in vielen Situationen sehr wünschenswert sein (z. B. eine MVC-App, in der Sie ein Modellverzeichnis möchten, aber noch keine Modelle erstellen möchten, oder ein Verzeichnis mit freigegebenen Ansichten, dem Sie später freigegebene Ansichten hinzufügen möchten ). Darüber hinaus ist es übertrieben, eine README-Datei in jede dieser Dateien einzufügen, da es offensichtlich ist, wofür sie da sind, und es leicht zu vergessen ist, in jede einzelne eine README-Datei einzufügen. UND Sie müssen daran denken, die README-Datei zu entfernen, wenn Sie ihnen andere Dateien hinzufügen. Grundsätzlich sollte git auf jeden Fall leere Verzeichnisse zulassen.
Jez

20
@Jez: Ich bin anderer Meinung. Der Punkt ist, dass git entwickelt wurde, um den Quellcode zu steuern (und zu indizieren). Wichtig ist, dass die ID eines Commits ein Hash des Inhalts ist. Das heißt, es muss Inhalt haben. Sie benötigen nicht in jedem Teil des Baums eine README-Datei, sondern nur Blattknoten. Wenn Sie Orte haben, an denen Sie Code einfügen möchten, aber keinen Code, und Sie sich nicht einmal die Zeit nehmen, "Ort für Modelle" >> README zu wiederholen, dann haben Sie eine Idee, kein Commit. Es ist nicht von Interesse zu git. Die Aussage "Ich möchte, dass die laufende App leere XYZ-Verzeichnisse hat" ist ein Laufzeitproblem , kein Quellproblem. Behandeln Sie es mit Ihrem Installateur.
Joe Atzberger

6
@ JoeAtzberger Es ist eine fehlende Funktion, keine absichtliche Einschränkung. Aus den Git-FAQ: Derzeit erlaubt das Design des Git-Index (Staging-Bereich) nur das Auflisten von Dateien, und niemand, der kompetent genug ist, um die Änderung vorzunehmen, um leere Verzeichnisse zuzulassen, hat sich genug um diese Situation gekümmert, um Abhilfe zu schaffen.
jbo5112

7
@ jbo5112 Ja, der "spezielle Code", auf den Sie sich beziehen, ist der von mir erwähnte "Installer". Ihre Webapp-Installation muss bereits eine Datenbank, eine lokale Konfiguration, das Abrufen von Abhängigkeiten oder 100 andere Vorgänge erstellen, aber ein paar leere Verzeichnisse sind darüber hinaus? Versuchen Sie es mit Gradle, Passagier, Koch, einem primitiven Makefile usw. Es gibt keinen Sicherheitsunterschied zwischen dem Erstellen von Verzeichnissen und der anderen (möglicherweise weitaus komplizierteren / gefährlicheren) Arbeit beim Installieren einer App. Und wenn Sie wirklich keine Deps, Config, DB usw. und kein Installationsprogramm haben, verwenden Sie einfach die README. In keinem Fall müssen Sie beides tun.
Joe Atzberger

348
touch .keep

Unter Linux wird dadurch eine leere Datei mit dem Namen erstellt .keep. Für das, was es wert ist, ist dieser Name für Git agnostisch, während er .gitkeepfür Git spezifisch wäre. Zweitens sollte, wie ein anderer Benutzer bemerkt hat, die .gitPräfixkonvention für Dateien und Verzeichnisse reserviert sein, die Git selbst verwendet.

Alternativ kann das Verzeichnis , wie in einer anderen Antwort angegeben , stattdessen eine Beschreibung READMEoder eine README.mdDatei enthalten .

Dies setzt natürlich voraus, dass das Vorhandensein der Datei nicht dazu führt, dass Ihre Anwendung beschädigt wird.


1
Dies ist gut für ein anfängliches nacktes Verzeichnis, aber was ist, wenn es anfängt, sich mit Dateien zu füllen? Dann wird Git sie bemerken und sie als nicht verfolgte Dateien beanspruchen. Die hier ausgewählte Antwort funktioniert viel eleganter, damit man ein Verzeichnis führen und den Inhalt dann sicher ignorieren kann.
JakeGould

14
Die Frage und das vorherrschende allgemeine Anliegen betrifft das Hinzufügen eines leeren Verzeichnisses. Wenn es später eine residente Datei hat, löschen Sie die .keepDatei offensichtlich oder ignorieren Sie sie einfach. Wenn stattdessen die Dateien im Verzeichnis ignoriert werden sollen, ist das eine ganz andere Frage.
Acumenus

3
Es wurde vorgeschlagen, git clean -nd | sed s/'^Would remove '// | xargs -I{} touch "{}.keep"dies in allen nicht verfolgten leeren Verzeichnissen zu tun.
Acumenus

1
Diese Lösung gefällt mir nicht, es ist schwer zu erraten, was diese Datei bewirkt. Wenn Sie Dateien in Ihrer Entwicklungsumgebung generieren (z. B. Protokolle oder Bilder usw.), verhindert dies nicht, dass diese Dateien versioniert werden und in die Produktion gelangen, was nicht gut ist.
Danielrvt

1
Windows mag keine Dateien ohne Namen und erfordert spezielle Magie, um dies zu erreichen (auch bekannt als Bash-ähnliche Terminal-App oder gleichwertig).
EntangledLoops

303

Warum brauchen wir leere versionierte Ordner?

Das wichtigste zuerst:

Ein leeres Verzeichnis kann nicht Teil eines Baums unter dem Git-Versionsverwaltungssystem sein .

Es wird einfach nicht verfolgt. Es gibt jedoch Szenarien, in denen die "Versionierung" leerer Verzeichnisse sinnvoll sein kann, zum Beispiel:

  • Gerüstbau einer vordefinierten Ordnerstruktur , die jedem Benutzer / Mitwirkenden des Repositorys zur Verfügung steht; oder, als Spezialfall des oben genannten, Erstellen eines Ordners für temporäre Dateien , wie z. B. ein cache/oder logs/Verzeichnisse, in denen wir den Ordner aber .gitignoreseinen Inhalt bereitstellen möchten
  • Im Zusammenhang mit dem oben Gesagten funktionieren einige Projekte ohne einige Ordner nicht (was oft ein Hinweis auf ein schlecht gestaltetes Projekt ist, aber es ist ein häufiges reales Szenario, und möglicherweise können beispielsweise Berechtigungsprobleme behoben werden).

Einige empfohlene Problemumgehungen

Viele Benutzer schlagen vor:

  1. Platzieren einer READMEDatei oder einer anderen Datei mit einem bestimmten Inhalt, um das Verzeichnis nicht leer zu machen, oder
  2. Erstellen einer .gitignoreDatei mit einer Art "umgekehrter Logik" (dh um alle Dateien einzuschließen), die am Ende dem gleichen Zweck von Ansatz 1 dient.

Obwohl beide Lösungen sicherlich funktionieren, finde ich sie unvereinbar mit einem sinnvollen Ansatz zur Git-Versionierung.

  • Warum sollten Sie gefälschte Dateien oder READMEs einfügen, die Sie vielleicht nicht wirklich in Ihr Projekt aufnehmen möchten?
  • Warum Gebrauch .gitignoreetwas (zu tun zu halten Dateien) , die genau das Gegenteil von dem , was es bedeutet , für ( mit Ausnahme von Dateien), auch wenn es möglich ist?

.gitkeep Ansatz

Verwenden Sie eine leere Datei, die aufgerufen .gitkeepwird, um das Vorhandensein des Ordners im Versionsverwaltungssystem zu erzwingen.

Obwohl es kein so großer Unterschied zu sein scheint:

  • Sie verwenden eine Datei, die nur dazu dient , den Ordner zu behalten. Sie geben dort keine Informationen ein, die Sie nicht einfügen möchten.

    Zum Beispiel sollten Sie READMEs auch als READMEs mit nützlichen Informationen verwenden, nicht als Entschuldigung, um den Ordner zu behalten.

    Die Trennung von Bedenken ist immer eine gute Sache, und Sie können immer noch eine hinzufügen .gitignore, um unerwünschte Dateien zu ignorieren.

  • Durch die Benennung .gitkeepwird anhand des Dateinamens selbst (und auch gegenüber anderen Entwicklern , was für ein freigegebenes Projekt und einen der Hauptzwecke eines Git-Repositorys gut ist) klar und unkompliziert, dass es sich um diese Datei handelt

    • Eine Datei, die nichts mit dem Code zu tun hat (aufgrund des führenden Punkts und des Namens)
    • Eine Datei, die eindeutig mit Git zusammenhängt
    • Sein Zweck ( behalten ) ist klar angegeben und konsistent und semantisch entgegengesetzt in seiner Bedeutung zu ignorieren

Annahme

Ich habe den .gitkeepAnsatz sehr wichtiger Frameworks wie Laravel , Angular-CLI gesehen .


8
Sie haben einen Gedanken verpasst - was ist der Grund dafür, einen Ordner zu behalten (z. B. / logs, / tmp, / uploads)? Ja, um den Ordner leer zu halten. :) Wenn Sie also einen Ordner leer halten möchten, müssen Sie die darin enthaltenen Dateien ignorieren.
Roman

14
@ RomanAllenstein: nicht unbedingt. Es kann sein, dass Sie ein Repo mit einer bestimmten Struktur erstellen, das später gefüllt werden kann. Diese Dateien werden dem Repo hinzugefügt, sobald sie erstellt wurden, und es ist ärgerlich, mit dem Löschen oder Bearbeiten von Gitignore-Dateien zu beginnen (und gefährlich, da Sie wahrscheinlich nicht einmal bemerken, dass sie nicht verfolgt werden: Git ignoriert sie )
blueFast

45
@Behnam: Ich werde die Abstimmung ablehnen, aber meine Forschung zum SO-Meta zeigt keine Bedenken hinsichtlich ausführlicher Antworten, solange sie genügend Details und Klarheit bieten, um für jeden Leser (und jede Fähigkeitsstufe) nützlich zu sein. Trotzdem bin ich sehr offen für Kritik und danke, dass Sie den Grund öffentlich erklärt haben. Ich nehme das sehr positiv.
Cranio

4
Wenn Sie Ihre Antwort so bearbeiten, dass sie .gitkeepdurch einen anderen Dateinamen ohne Git-Präfix ersetzt wird, erhalten Sie meine positive Bewertung. Ich denke, dies ist die beste und informativste Antwort. Grund: Ich denke, ".git *" sollte für git-vorgeschriebene Dateien reserviert werden, während dies nur ein Platzhalter ist. Meine erste Vermutung, als ich sah, dass zum Beispiel eine ".gitkeep" -Datei automatisch ignoriert wird (das wäre eine nette Funktion), aber das ist nicht der Fall, oder?
Johnny

5
Ich frage mich, warum es den Leuten so schwer fällt zu verstehen, warum man git "leere" Ordner hinzufügen möchte. Du musst irgendwo anfangen, oder? Normalerweise beginnen Sie also mit Ihrer Projektordnerstruktur und leider ist zu Beginn des Projekts noch nichts vorhanden. Sobald Ihr Projekt-Repo abgeschlossen ist, können Teamarbeiter klonen und mit der Arbeit an der gleichen Struktur beginnen.
BitTickler

127

Wie in anderen Antworten beschrieben, kann Git keine leeren Verzeichnisse in seinem Staging-Bereich darstellen. (Siehe die Git-FAQ .) Wenn ein Verzeichnis für Ihre Zwecke jedoch leer genug ist, wenn es nur eine .gitignoreDatei enthält , können Sie .gitignoreDateien in leeren Verzeichnissen nur über Folgendes erstellen :

find . -type d -empty -exec touch {}/.gitignore \;

21
Sie können das .git-Verzeichnis ignorieren: find . -name .git -prune -o -type d -empty -exec touch {}/.gitignore \;
steffen

3
Eine einfachere Variante für die meisten Situationen istfind * -type d -empty -exec touch {}/.gitignore \;
Akhan

2
Da OS X in fast jeder Direktive eine .DS_Store-Datei erstellt, funktioniert dies dort nicht. Die einzige (GEFÄHRLICHE!) Problemumgehung, die ich gefunden habe, bestand darin, alle .DS_Store-Dateien zuerst über zu löschen find . -name .DS_Store -exec rm {} \;und dann die bevorzugte Variante aus dieser Antwort zu verwenden. Stellen Sie sicher, dass Sie dies nur im richtigen Ordner ausführen!
Zerweck

1
Kennt jemand eine Möglichkeit, dies in Windows über die Befehlszeile zu tun? Ich habe hier in Ruby und Python einige Lösungen gesehen, aber ich hätte gerne eine Barebone-Lösung, wenn sie verwaltet werden kann.
Mig82

1
@akhan Das Hinzufügen von etwas zu .gitignorehat keinen Einfluss auf die -emptyFlagge des findBefehls. In meinem Kommentar geht es darum, die .DS_StoreDateien in einem Verzeichnisbaum zu entfernen , damit das -emptyFlag angewendet werden kann.
Zerweck

68

Andy Lester ist richtig, aber wenn Ihr Verzeichnis muss nur leer sein, und nicht leer leer, können Sie eine leere setzen .gitignoreDatei dort als Behelfslösung.

Abgesehen davon ist dies ein Implementierungsproblem, kein grundlegendes Problem beim Entwurf des Git-Speichers. Wie schon oft auf der Git-Mailingliste erwähnt, ist der Grund dafür, dass dies nicht implementiert wurde, dass sich niemand genug darum gekümmert hat, einen Patch dafür einzureichen, und nicht, dass dies nicht möglich oder nicht möglich war.


4
Genau das habe ich gesagt. Beide Absätze werden im Ausschnitt der von mir geposteten FAQ behandelt.
Andy Lester

1
Ich denke, die Seite ist unterbewertet und nützlich zu wissen - sie kann behoben werden. Erwarten Sie sie nur nicht so schnell, wenn es in den meisten Fällen eine so einfache Problemumgehung gibt.
wnoise

Entschuldigung, ich habe den letzten Absatz nicht gelesen, und obwohl ich den ersten Absatz gelesen habe, bin ich mir nicht sicher, warum ich diese Informationen wiederholt habe.
Aristoteles Pagaltzis

2
Natürlich dient diese zusätzliche Antwort dazu, auf die Tatsache hinzuweisen.
Michael Johnson

Ich habe mir hier einen Fall angesehen, in dem der Build heruntergefallen ist, wenn das Verzeichnis nicht existiert und standardmäßig leer ist, aber nicht leer sein muss. Das Erstellen eines .gitignore macht das Richtige.
Joshua

33

Die Methode zur Erstellung von Ruby on Rails- Protokollordnern:

mkdir log && touch log/.gitkeep && git add log/.gitkeep

Jetzt wird das Protokollverzeichnis in den Baum aufgenommen. Es ist sehr nützlich bei der Bereitstellung, sodass Sie keine Routine schreiben müssen, um Protokollverzeichnisse zu erstellen.

Die Protokolldateien können durch Ausgabe von,

echo log/dev.log >> .gitignore

aber das wusstest du wahrscheinlich.


23
Was hat das mit Ruby on Rails zu tun?
Quolonel Fragen


30

Git verfolgt keine leeren Verzeichnisse. Weitere Erklärungen finden Sie in den Git-FAQ . Die vorgeschlagene Problemumgehung besteht darin, eine .gitignoreDatei in das leere Verzeichnis zu stellen. Ich mag diese Lösung nicht, weil sie .gitignoredurch die Unix-Konvention "versteckt" ist. Es gibt auch keine Erklärung, warum die Verzeichnisse leer sind.

Ich schlage vor, eine README-Datei in das leere Verzeichnis zu legen, um zu erklären, warum das Verzeichnis leer ist und warum es in Git verfolgt werden muss. Mit der README-Datei ist das Verzeichnis für Git nicht mehr leer.

Die eigentliche Frage ist, warum Sie das leere Verzeichnis in Git benötigen? Normalerweise haben Sie eine Art Build-Skript, das das leere Verzeichnis vor dem Kompilieren / Ausführen erstellen kann. Wenn nicht, dann mach eins. Das ist eine weitaus bessere Lösung, als leere Verzeichnisse in git zu setzen.

Sie haben also einen Grund, warum Sie ein leeres Verzeichnis in git benötigen. Tragen Sie diesen Grund in die README-Datei ein. Auf diese Weise wissen andere Entwickler (und zukünftige Sie), warum das leere Verzeichnis vorhanden sein muss. Sie wissen auch, dass Sie das leere Verzeichnis entfernen können, wenn das Problem, das das leere Verzeichnis erfordert, behoben wurde.


Verwenden Sie den folgenden Befehl, um jedes leere Verzeichnis aufzulisten:

find -name .git -prune -o -type d -empty -print

So erstellen Sie Platzhalter-READMEs in jedem leeren Verzeichnis:

find -name .git -prune -o -type d -empty -exec sh -c \
  "echo this directory needs to be empty because reasons > {}/README.emptydir" \;

Um alles im Verzeichnis außer der README-Datei zu ignorieren, fügen Sie die folgenden Zeilen in Ihr Verzeichnis ein .gitignore:

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

Alternativ können Sie einfach jede README-Datei vom Ignorieren ausschließen:

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir

So listen Sie jede README-Datei auf, nachdem sie bereits erstellt wurde:

find -name README.emptydir

28

WARNUNG: Wie sich herausstellt, funktioniert diese Optimierung nicht wirklich. Entschuldigen Sie die Unannehmlichkeiten.

Originaler Beitrag unten:

Ich habe beim Spielen mit Git-Interna eine Lösung gefunden!

  1. Angenommen, Sie befinden sich in Ihrem Repository.
  2. Erstellen Sie Ihr leeres Verzeichnis:

    $ mkdir path/to/empty-folder
    
  3. Fügen Sie es mit einem Installationsbefehl und dem leeren Baum SHA-1 zum Index hinzu :

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    

    Geben Sie den Befehl ein und geben Sie die zweite Zeile ein. Drücken Sie Enterund dann Ctrl+, Dum Ihre Eingabe zu beenden. Hinweis: Das Format ist Modus [SPACE] Typ [SPACE] SHA-1hash [TAB] -Pfad (die Registerkarte ist wichtig, die Antwortformatierung behält sie nicht bei).

  4. Das ist es! Ihr leerer Ordner befindet sich in Ihrem Index. Alles was Sie tun müssen, ist ein Commit.

Diese Lösung ist kurz und funktioniert anscheinend gut ( siehe BEARBEITEN! ), Aber es ist nicht so einfach, sich daran zu erinnern ...

Der leere Baum SHA-1 kann gefunden werden, indem ein neues leeres Git-Repository erstellt cdund ausgegeben wird git write-tree, das den leeren Baum SHA-1 ausgibt.

BEARBEITEN:

Ich benutze diese Lösung, seit ich sie gefunden habe. Es scheint genauso zu funktionieren wie das Erstellen eines Submoduls, außer dass nirgendwo ein Modul definiert ist. Dies führt zu Fehlern bei der Ausgabe git submodule init|update. Das Problem ist, dass git update-indexdas 040000 treeTeil neu geschrieben wird 160000 commit.

Darüber hinaus wird jede Datei, die unter diesem Pfad abgelegt wird, von Git nie bemerkt, da sie glaubt, zu einem anderen Repository zu gehören. Das ist böse, da es leicht übersehen werden kann!

Wenn Sie jedoch noch keine Git-Submodule in Ihrem Repository verwenden (und dies auch nicht tun) und der "leere" Ordner leer bleibt, oder wenn Sie möchten, dass Git von seiner Existenz erfährt und seinen Inhalt ignoriert, können Sie fortfahren diese Optimierung. Der übliche Weg mit Submodulen erfordert mehr Schritte als diese Optimierung.


Ist es dann nach dem Einfügen des leeren Ordners in den Index und dem Festschreiben git svn dcommitmit dem gewünschten Ergebnis möglich?
Begrenzte Versöhnung

2
Es ist unwahrscheinlich, dass diese Optimierung mit einem anderen Tool funktioniert. Wie in der Warnung und in der Bearbeitung angegeben, rate ich davon ab, es zu verwenden, es sei denn, es handelt sich um einen recht eingeschränkten Fall.
ofavre

1
Und deshalb ist es natürlich kontraindiziert, mit den Git-Interna herumzuspielen.
Casey

@abhisekp Wie ist das überhaupt möglich?
PyRulez

1
@ PyRulez Nun, in der Software-Welt ist nichts unmöglich. : D Eigentlich bin ich der Antwort gefolgt.
Abhisekp

21

Angenommen, Sie benötigen ein leeres Verzeichnis mit dem Namen tmp :

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp

Mit anderen Worten, Sie müssen die .gitignore-Datei zum Index hinzufügen, bevor Sie Git anweisen können, sie (und alles andere im leeren Verzeichnis) zu ignorieren.


11
Zwei Dinge: Sie könnten einfach "echo '*'> tmp / .gitignore" anstatt zu berühren, und "git commit -m" schreibt keine Änderungen fest, die nach dem Hinzufügen der Dateien zum Index vorgenommen wurden.
Christoffer Hammarström

6
Wenn Sie dies nur tun, erhalten echo bla > fileSie keine, file: File existsda >die Datei überschrieben wird, wenn sie bereits vorhanden ist, oder eine neue erstellt wird, wenn sie nicht vorhanden ist.
Psyrendust

3
/bin/shkulturelle Annahme! * Wenn "hier" ist cshund die Variable noclobbergesetzt ist, erhalten Sie in der Tat file: File exists. Wenn jemand "Ich verstehe das" sagt, gehe nicht davon aus, dass er ein Idiot ist, und antworte "Nein, tust du nicht". * c2.com/cgi/wiki?AmericanCulturalAssumption
clacke

1
@clacke Wenn sich jemand entscheidet, eine andere Shell als alle anderen zu verwenden, sollte er dies ausdrücklich angeben, wenn er auf Probleme stößt. Anders als bei der Nationalität hat jeder die freie Wahl der Muschel.
Selten

2
@SeldomNeedy Vielleicht suchen sie Hilfe, weil sie nicht einmal wissen, dass sie eine andere Shell verwenden als alle anderen.
Clacke

20

Vielleicht scheint das Hinzufügen eines leeren Verzeichnisses der Weg des geringsten Widerstands zu sein, da Sie Skripte haben, die erwarten, dass dieses Verzeichnis existiert (möglicherweise weil es ein Ziel für generierte Binärdateien ist). Ein anderer Ansatz wäre, Ihre Skripte zu ändern, um das Verzeichnis nach Bedarf zu erstellen .

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed

In diesem Beispiel können Sie einen (fehlerhaften) symbolischen Link zum Verzeichnis einchecken, damit Sie ohne das Präfix ".generated" darauf zugreifen können (dies ist jedoch optional).

ln -sf .generated/bin bin
git add bin

Wenn Sie Ihren Quellbaum bereinigen möchten, können Sie einfach:

rm -rf .generated ## this should be in a "clean" script or in a makefile

Wenn Sie den oft vorgeschlagenen Ansatz wählen, einen fast leeren Ordner einzuchecken, haben Sie die geringe Komplexität, den Inhalt zu löschen, ohne auch die Datei ".gitignore" zu löschen.

Sie können alle generierten Dateien ignorieren, indem Sie Ihrem root .gitignore Folgendes hinzufügen:

.generated

1
Hinweis: Der von mir vorgeschlagene symbolische Link ist bei einer sauberen Kaufabwicklung "defekt", da das .generatedVerzeichnis anfangs nicht vorhanden ist. Es wird nicht mehr kaputt sein, wenn Sie Ihren Build machen.
Nobar

2
Ich stimme zu, dass dies in einigen Fällen eine sehr gute Idee ist, aber in anderen Fällen (z. B. beim Verteilen eines Projekts, bei dem Sie ein ansonsten leeres Skelett mit Ordnern wie models / und views / haben) möchten Sie, dass der Benutzer diese Verzeichnisse eher zur Hand hat als manuell lesen zu müssen, lesen Sie die Dokumente, und es könnte ein bisschen viel erwarten, dass sie nach dem Klonen des Repos eine Art Installationsskript ausführen. Ich denke, diese Antwort in Kombination mit der README-Antwort von @ john-mee sollte die meisten, wenn nicht alle Fälle abdecken.
Moopet

14

Ich habe das Problem auch mit leeren Verzeichnissen konfrontiert. Das Problem bei der Verwendung von Platzhalterdateien besteht darin, dass Sie sie erstellen und löschen müssen, wenn sie nicht mehr benötigt werden (da später Unterverzeichnisse oder Dateien hinzugefügt wurden. Bei großen Quellbäumen kann die Verwaltung dieser Platzhalterdateien umständlich und fehlerhaft sein anfällig.

Aus diesem Grund habe ich beschlossen, ein Open-Source-Tool zu schreiben, mit dem das Erstellen / Löschen solcher Platzhalterdateien automatisch verwaltet werden kann. Es wurde für die .NET-Plattform geschrieben und läuft unter Mono (.NET für Linux) und Windows.

Schauen Sie sich einfach Folgendes an: http://code.google.com/p/markemptydirs


14

Ich mag die Antworten von @ Artur79 und @mjs, daher habe ich eine Kombination aus beiden verwendet und sie zu einem Standard für unsere Projekte gemacht.

find . -type d -empty -exec touch {}/.gitkeep \;

Allerdings arbeiten nur eine Handvoll unserer Entwickler unter Mac oder Linux. Viel Arbeit unter Windows und ich konnte keinen vergleichbaren einfachen Einzeiler finden, um dasselbe dort zu erreichen. Einige hatten das Glück, Cygwin aus anderen Gründen installiert zu haben , aber Cygwin nur dafür zu verschreiben, schien übertrieben.

Bearbeiten Sie für eine bessere Lösung

Da die meisten unserer Entwickler Ant bereits installiert haben, dachte ich zuerst daran, eine Ant-Build-Datei zusammenzustellen, um dies unabhängig von der Plattform zu erreichen. Dies kann noch gefunden werden werden

Später dachte ich jedoch , es wäre besser, daraus einen kleinen Dienstprogrammbefehl zu machen, also habe ich ihn mit Python neu erstellt und hier im PyPI veröffentlicht . Sie können es installieren, indem Sie einfach Folgendes ausführen:

pip3 install gitkeep2

Sie können damit .gitkeepDateien rekursiv erstellen und entfernen sowie Nachrichten hinzufügen, damit Ihre Kollegen verstehen, warum diese Verzeichnisse wichtig sind. Dieses letzte Bit ist ein Bonus. Ich dachte, es wäre schön, wenn die .gitkeepDateien sich selbst dokumentieren könnten.

$ gitkeep --help
Usage: gitkeep [OPTIONS] PATH

  Add a .gitkeep file to a directory in order to push them into a Git repo
  even if they're empty.

  Read more about why this is necessary at: https://git.wiki.kernel.org/inde
  x.php/Git_FAQ#Can_I_add_empty_directories.3F

Options:
  -r, --recursive     Add or remove the .gitkeep files recursively for all
                      sub-directories in the specified path.
  -l, --let-go        Remove the .gitkeep files from the specified path.
  -e, --empty         Create empty .gitkeep files. This will ignore any
                      message provided
  -m, --message TEXT  A message to be included in the .gitkeep file, ideally
                      used to explain why it's important to push the specified
                      directory to source control even if it's empty.
  -v, --verbose       Print out everything.
  --help              Show this message and exit.

Ich hoffe, Sie finden es nützlich.


13

Sie können und werden es leider nie können. Dies ist eine Entscheidung, die Linus Torvald selbst getroffen hat. Er weiß, was gut für uns ist.

Irgendwo da draußen, wo ich einmal gelesen habe, wird geschimpft.

Ich habe Re: Empty-Verzeichnisse gefunden , aber vielleicht gibt es noch eines.

Sie müssen mit den Problemumgehungen leben ... leider.


1
Ich weiß, dass Sie dies als Beispiel für ein schlechtes Argument gepostet haben, aber ich schätze den Link, da es sich tatsächlich um ein gut begründetes Argument gegen die Verfolgung von Verzeichnissen handelt. ;-)
Clacke

1
Diese Antwort scheint inkonsistent zu sein, da Linus Torvald im nächsten Beitrag zum referenzierten Thread erwartet, dass sie die Verzeichnisverfolgung hinzufügen müssen: markmail.org/message/libip4vpvvxhyqbl . Tatsächlich sagt er, er würde "Patches begrüßen, die [Unterstützung für die Verfolgung leerer Verzeichnisse hinzufügen]"
Patrick M

Patrick, er benutzt dort auch das Wort "idiotisch". Ich vermute, dass sein Wortlaut die Leute hier in diesem Thread anspricht und ich gehe davon aus, dass er nicht selbst etwas "Idiotisches" in Git implementieren wird.
user2334883

10

Wenn Sie beim Hinzufügen einer .gitignoreDatei eine beliebige Menge an Inhalten einfügen (die Git ignorieren soll), möchten Sie möglicherweise eine einzelne Zeile mit nur einem Sternchen *hinzufügen, um sicherzustellen, dass Sie den ignorierten Inhalt nicht versehentlich hinzufügen .


9

Es gibt keine Möglichkeit, Git dazu zu bringen, Verzeichnisse zu verfolgen. Die einzige Lösung besteht darin, eine Platzhalterdatei innerhalb des Verzeichnisses hinzuzufügen, das Git verfolgen soll.

Die Datei kann benannt werden und alles enthalten, was Sie wollen, aber die meisten Leute verwenden eine leere Datei mit dem Namen .gitkeep(obwohl einige Leute den VCS-Agnostiker bevorzugen .keep).

Das Präfix . markiert es als versteckte Datei.

Eine andere Idee wäre, eine READMEDatei hinzuzufügen , in der erklärt wird, wofür das Verzeichnis verwendet wird.


8

Wie bereits erwähnt, ist es nicht möglich, leere Verzeichnisse hinzuzufügen. Hier ist jedoch ein Einzeiler, der allen Verzeichnissen leere Gitignore-Dateien hinzufügt.

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

Ich habe dies für einen einfachen Zugriff in ein Rakefile gesteckt.


6
Ich würde lieber verwendenfind . -type d -empty -print0 | xargs --null bash -c 'for a; do { echo "*"; echo "!.gitignore"; } >>"$a/.gitignore"; done' --
Tino

8

Die Lösung von Jamie Flournoy funktioniert hervorragend. Hier ist eine etwas verbesserte Version, um Folgendes beizubehalten .htaccess:

# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

Mit dieser Lösung können Sie beispielsweise einen leeren Ordner festschreiben /log, /tmpoder /cacheder Ordner bleibt leer.


2
Er möchte ein leeres Verzeichnis und keine Datei behalten.
gvsrepins

2
Und ich habe erwähnt, dass es auch den .htaccess behalten wird. Beispiel: Wenn eine Software ein Verzeichnis für Protokolldateien (wie Oxid Eshop) hat, das nicht über das Web zugänglich sein soll, befindet sich im Verzeichnis ein .htaccess. Wenn Sie den oben genannten .gitignore in den Ordner legen, wird der .htaccess nicht festgeschrieben und der Ordner ist über das Web zugänglich.
Roman

Wenn Sie eine .htaccess-Datei haben, die der Versionskontrolle unterliegt, haben Sie bereits das Verzeichnis, das sie enthält, unter der Versionskontrolle. Damit ist das Problem bereits gelöst - die .gitignore-Datei wird irrelevant.
Ponkadoodle

1
@Wallacoloo Bezogen auf die Frage, ob Sie Recht haben, ist die Datei dennoch nützlich. Ich werde sie für ein solches Upload-Verzeichnis verwenden, in dem Dateien durch .htaccess geschützt werden sollen. Entgegen der Erklärung der Römer wird die .htaccess-Datei festgeschrieben, da sie von der Ignorierregel ausgeschlossen wird. [alter Thread, ich weiß]
David

7

Ich erstelle immer eine Funktion, um nach meiner gewünschten Ordnerstruktur zu suchen und sie für mich innerhalb des Projekts zu erstellen. Dies umgeht dieses Problem, da die leeren Ordner vom Proxy in Git gespeichert werden.

function check_page_custom_folder_structure () {
    if (!is_dir(TEMPLATEPATH."/page-customs"))
        mkdir(TEMPLATEPATH."/page-customs");    
    if (!is_dir(TEMPLATEPATH."/page-customs/css"))
        mkdir(TEMPLATEPATH."/page-customs/css");
    if (!is_dir(TEMPLATEPATH."/page-customs/js"))
        mkdir(TEMPLATEPATH."/page-customs/js");
}

Dies ist in PHP, aber ich bin sicher, dass die meisten Sprachen die gleiche Funktionalität unterstützen. Da die Erstellung der Ordner von der Anwendung übernommen wird, sind die Ordner immer vorhanden.


2
Nur damit wir alle auf einer Seite sind, mache ich das nicht mehr. Es ist Zeitverschwendung. Die .gitkeepKonvention ist eine viel bessere Praxis.
Mild Fuzz

Ich kann nicht sehen, wie das Zeitverschwendung sein kann. Wenn Ihr TEMPLATEPATH offensichtlich dynamisch ist, können Sie die .gitkeep-Lösung nicht verwenden. Und selbst bei einer nicht dynamischen Ordnerstruktur sollten Sie etwas mehr hinzufügen, anstatt die sehr gute Lösung zum Überprüfen von Verzeichnissen zu entfernen, z. B. nach Berechtigungen zu suchen und die Dateien zu ändern. Das Hinzufügen einer Möglichkeit zum Markieren von Verzeichnissen in einem globalen .gitignore wäre perfekt für mich. So etwas wie #keep / path / to / dir
Jochen Schultz

7

Hier ist ein Hack, aber es ist lustig, dass es funktioniert (Git 2.2.1). Ähnlich wie @Teka vorgeschlagen, aber leichter zu merken:

  • Fügen Sie jedem Repository ein Submodul hinzu ( git submodule add path_to_repo)
  • Dadurch werden ein Ordner und eine Datei hinzugefügt .submodules. Übernehmen Sie eine Änderung.
  • .submodulesDatei löschen und Änderung übernehmen.

Jetzt haben Sie ein Verzeichnis, das beim Auschecken des Commits erstellt wird. Interessant ist jedoch, dass Sie beim Betrachten des Inhalts des Baumobjekts dieser Datei Folgendes erhalten:

Schwerwiegend: Kein gültiger Objektname b64338b90b4209263b50244d18278c0999867193

Ich würde es jedoch nicht empfehlen, es zu verwenden, da es in zukünftigen Versionen von Git möglicherweise nicht mehr funktioniert. Dadurch kann Ihr Repository beschädigt werden.


Das funktioniert tatsächlich, aber ich denke, es verwirrt IntelliJ ...: |
Rogerdpack

Ich habe eine bessere Lösung basierend darauf erstellt, die diese Nachteile nicht hat: stackoverflow.com/a/58543445/277882
ntninja

7

Viele haben diese Frage bereits beantwortet. Fügen Sie hier einfach eine PowerShell-Version hinzu.

Suchen Sie alle leeren Ordner im Verzeichnis

Fügen Sie dort eine leere Gitkeep-Datei hinzu

Get-ChildItem 'Path to your Folder' -Recurse -Directory | Where-Object {[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0} | ForEach-Object { New-Item ($_.FullName + "\.gitkeep") -ItemType file}

Nice.‌‌ ༼ ༼ ͡☉ ͜ʖ ͡☉
FiringSquadWitness

6

Wenn Sie einen Ordner hinzufügen möchten, der viele vorübergehende Daten in mehreren semantischen Verzeichnissen enthält, besteht ein Ansatz darin, Ihrem Stammverzeichnis .gitignore Folgendes hinzuzufügen ...

/app/data/**/*.* !/app/data/**/*.md

Dann können Sie beschreibende README.md-Dateien (oder leere Dateien, spielt keine Rolle, solange Sie sie wie *.mdin diesem Fall eindeutig als Ziel festlegen können ) in jedem Verzeichnis festschreiben, um sicherzustellen, dass alle Verzeichnisse Teil des Repos bleiben, außer dem Dateien (mit Erweiterungen) werden ignoriert. EINSCHRÄNKUNG: .In den Verzeichnisnamen sind keine zulässig!

Sie können alle diese Verzeichnisse mit XML- / Bilddateien oder was auch immer füllen und weitere Verzeichnisse unter hinzufügen /app/data/ Laufe der Zeit wenn sich der Speicherbedarf für Ihre App entwickelt (wobei die README.md-Dateien dazu dienen, eine Beschreibung der einzelnen Speicherverzeichnisse einzubrennen genau).

Sie müssen Ihr Verzeichnis nicht weiter ändern .gitignoreoder dezentralisieren, indem Sie .gitignorefür jedes neue Verzeichnis ein neues erstellen . Wahrscheinlich nicht die klügste Lösung, aber in Bezug auf Gitignore knapp und funktioniert immer für mich. Schön und einfach! ;)

Geben Sie hier die Bildbeschreibung ein


6

Eine einfache Möglichkeit, dies zu tun, besteht darin .gitkeep, dem Verzeichnis, das Sie (derzeit) leer halten möchten, eine Datei hinzuzufügen .

Weitere Informationen finden Sie in dieser SOF-Antwort . Dies erklärt auch, warum manche Leute die konkurrierende Konvention des Hinzufügens einer Gitignore-Datei (wie in vielen Antworten hier angegeben) verwirrend finden.


4

Hinzufügen einer weiteren Option zum Kampf.

Angenommen, Sie möchten ein Verzeichnis hinzufügen, gitdas für alle damit verbundenen Zwecke gitleer bleibt und dessen Inhalt niemals nachverfolgt wird, .gitignorewie dies hier mehrfach vorgeschlagen wurde, reicht aus.

Das Format ist wie erwähnt:

*
!.gitignore

Wenn Sie dies nun auf einen Schlag über die Befehlszeile tun möchten, können Sie in dem Verzeichnis, das Sie hinzufügen möchten, Folgendes ausführen:

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore

Ich selbst habe ein Shell-Skript, mit dem ich das mache. Benennen Sie das Skript nach Ihren Wünschen und fügen Sie es entweder irgendwo in Ihren Include-Pfad ein oder verweisen Sie direkt darauf:

#!/bin/bash

dir=''

if [ "$1" != "" ]; then
    dir="$1/"
fi

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore

Mit dieser Option können Sie sie entweder in dem Verzeichnis ausführen, das Sie hinzufügen möchten, oder auf das Verzeichnis als ersten und einzigen Parameter verweisen:

$ ignore_dir ./some/directory

Eine weitere Option (in Reaktion auf einen Kommentar von @GreenAsJade), wenn Sie einen leeren Ordner verfolgen mögen , dass MAY verfolgt Dateien in der Zukunft enthält, wird aber jetzt leer sein, können Sie die ommit *aus der .gitignoreDatei, und prüfen Sie, dass in. Grundsätzlich heißt es in der Datei nur: "Ignoriere mich nicht ", aber ansonsten ist das Verzeichnis leer und wird nachverfolgt.

Ihre .gitignoreDatei würde folgendermaßen aussehen:

!.gitignore

Das war's, checken Sie das ein und Sie haben ein leeres, aber nachverfolgtes Verzeichnis, in dem Sie Dateien zu einem späteren Zeitpunkt nachverfolgen können.

Der Grund, warum ich vorschlage, diese eine Zeile in der Datei beizubehalten, ist, dass sie den .gitignoreZweck angibt. Andernfalls könnte jemand auf der ganzen Linie daran denken, es zu entfernen. Es kann hilfreich sein, wenn Sie einen Kommentar über der Zeile platzieren.


4

Manchmal muss man sich mit schlecht geschriebenen Bibliotheken oder Software auseinandersetzen, die ein "echtes" leeres und vorhandenes Verzeichnis benötigen. Setzen Sie eine einfache .gitignoreoder .keepkönnte sie brechen und einen Fehler verursachen. Folgendes könnte in diesen Fällen helfen, aber keine Garantie ...

Erstellen Sie zuerst das benötigte Verzeichnis:

mkdir empty

Dann fügen Sie diesem Verzeichnis einen fehlerhaften symbolischen Link hinzu (aber in jedem anderen Fall als dem oben beschriebenen Anwendungsfall verwenden Sie bitte einen READMEmit einer Erklärung):

ln -s .this.directory empty/.keep

Um Dateien in diesem Verzeichnis zu ignorieren, können Sie sie in Ihrem Stammverzeichnis hinzufügen .gitignore:

echo "/empty" >> .gitignore

Verwenden Sie einen Parameter, um die ignorierte Datei hinzuzufügen:

git add -f empty/.keep

Nach dem Commit haben Sie einen fehlerhaften symbolischen Link in Ihrem Index und git erstellt das Verzeichnis. Der fehlerhafte Link hat einige Vorteile, da es sich nicht um eine reguläre Datei handelt und auf keine reguläre Datei verweist. Es passt also sogar zu dem Teil der Frage "(der keine Dateien enthält)", nicht durch die Absicht, sondern durch die Bedeutung, denke ich:

find empty -type f

Dieser Befehl zeigt ein leeres Ergebnis an, da in diesem Verzeichnis keine Dateien vorhanden sind. Daher sehen die meisten Anwendungen, die alle Dateien in einem Verzeichnis abrufen, diesen Link normalerweise nicht, zumindest wenn sie eine "Datei vorhanden" oder eine "lesbar" haben. Selbst einige Skripte finden dort keine Dateien:

$ php -r "var_export(glob('empty/.*'));"
array (
  0 => 'empty/.',
  1 => 'empty/..',
)

Ich empfehle jedoch dringend, diese Lösung nur unter besonderen Umständen zu verwenden. Ein READMEin ein leeres Verzeichnis geschriebenes Gut ist normalerweise eine bessere Lösung. (Und ich weiß nicht, ob dies mit einem Windows-Dateisystem funktioniert ...)


4

Beim Lesen der Antworten von @ofavre und @ stanislav-bashkyrtsev unter Verwendung defekter GIT-Submodulreferenzen zum Erstellen der GIT-Verzeichnisse bin ich überrascht, dass noch niemand diese einfache Änderung der Idee vorgeschlagen hat, das Ganze vernünftig und sicher zu machen:

Anstatt ein gefälschtes Submodul in GIT zu hacken , fügen Sie einfach ein leeres echtes hinzu .

Geben Sie Folgendes ein: https://gitlab.com/empty-repo/empty.git

Ein GIT-Repository mit genau einem Commit:

commit e84d7b81f0033399e325b8037ed2b801a5c994e0
Author: Nobody <none>
Date: Thu Jan 1 00:00:00 1970 +0000

Keine Nachricht, keine festgeschriebenen Dateien.

Verwendungszweck

So fügen Sie Ihrem GIT-Repo ein leeres Verzeichnis hinzu:

git submodule add https://gitlab.com/empty-repo/empty.git path/to/dir

So konvertieren Sie alle vorhandenen leeren Verzeichnisse in Submodule:

find . -type d -empty -delete -exec git submodule add -f https://gitlab.com/empty-repo/empty.git \{\} \;

Git speichert den neuesten Commit-Hash beim Erstellen der Submodul-Referenz, sodass Sie sich keine Sorgen machen müssen, dass ich (oder GitLab) diesen zum Einfügen schädlicher Dateien verwende. Leider fand ich keinen Weg zu Kraft , die ID begehen wird während der Prüfung verwendet wird , so dass Sie manuell , dass die Referenz haben werden überprüfen ID begehen ist e84d7b81f0033399e325b8037ed2b801a5c994e0mitgit submodule status nach dem Hinzufügen des Repo.

Noch keine native Lösung, aber die beste wahrscheinlich wir ohne jemanden bekommen ihre Hände haben kann wirklich , wirklich in der GIT-Codebasis schmutzig wird.

Anhang: Neuerstellung dieses Commits

Sie sollten in der Lage sein, genau dieses Commit neu zu erstellen, indem Sie (in einem leeren Verzeichnis) Folgendes verwenden:

# Initialize new GIT repository
git init

# Set author data (don't set it as part of the `git commit` command or your default data will be stored as “commit author”)
git config --local user.name "Nobody"
git config --local user.email "none"

# Set both the commit and the author date to the start of the Unix epoch (this cannot be done using `git commit` directly)
export GIT_AUTHOR_DATE="Thu Jan 1 00:00:00 1970 +0000"
export GIT_COMMITTER_DATE="Thu Jan 1 00:00:00 1970 +0000"

# Add root commit
git commit --allow-empty --allow-empty-message --no-edit

Das Erstellen reproduzierbarer GIT-Commits ist überraschend schwierig…


3

Das kannst du nicht. Dies ist eine absichtliche Entwurfsentscheidung der Git-Betreuer. Grundsätzlich besteht der Zweck eines Quellcode-Verwaltungssystems wie Git darin, den Quellcode zu verwalten, und leere Verzeichnisse sind kein Quellcode. Git wird auch oft als Content-Tracker bezeichnet. Auch hier sind leere Verzeichnisse nicht inhaltlich (im Gegenteil), sodass sie nicht nachverfolgt werden.


60
Ich bestreite diese Ansicht. Struktur ist Inhalt, und alles, was Sie benennen, trägt zum Inhalt bei.
ThomasH

20
Eine leere Datei ist weder Quellcode noch Inhalt. Es ist nur ein Name. Dennoch wird Git gerne leere Dateien verfolgen. Ich glaube nicht, dass es eine absichtliche Designentscheidung war, Git dazu zu bringen, sich zu weigern, leere Verzeichnisse aufzuspüren. Ich denke, das Verfolgen leerer Verzeichnisse ist eine Funktion, die in 99% der Fälle einfach nicht benötigt wird. Sie haben sich also nicht die Mühe gemacht, die zusätzliche Arbeit zu erledigen, die erforderlich ist, damit es richtig funktioniert. Git kann es tun, wenn jemand die Funktion dringend genug haben möchte, um sie zu implementieren. Ich bezweifle, dass die Git-Betreuer gegen einen solchen Patch sind, wenn er richtig gemacht würde.
Dan Moulding

1
@TobyAllen hier ist der aktualisierte FAQ-Link Die beste Antwort ist auch, was von den FAQ mit genaueren Anweisungen empfohlen wird.
Daniel Da Cunha

3
Es ist eine fehlende Funktion (und niedrige Priorität), keine absichtliche Einschränkung. Aus den Git-FAQ: Derzeit erlaubt das Design des Git-Index (Staging-Bereich) nur das Auflisten von Dateien, und niemand, der kompetent genug ist, um die Änderung vorzunehmen, um leere Verzeichnisse zuzulassen, hat sich genug um diese Situation gekümmert, um Abhilfe zu schaffen.
jbo5112

Stimme nicht wirklich zu. Ich kann verschiedene Gründe finden, warum ich einen leeren Ordner verfolgen möchte. Zum Beispiel entwickle ich ein sehr leichtes PHP MVC-Framework für meine Projekte. Ich habe bestimmte Ordner zum Platzieren von Modellen, Ansichten usw. Wenn ich eine neue Site basierend auf meinem Framework erstelle, sind diese Ordner leer, da standardmäßig keine Modelle oder Ansichten vorhanden sind. Der Ordner muss jedoch vorhanden sein, sonst hat mein Framework gewonnen funktioniert nicht!
Gladen

2

Sie können diesen Code als create_readme.php speichern und den PHP- Code aus dem Stammverzeichnis Ihres Git-Projekts ausführen.

> php create_readme.php

Es werden README-Dateien zu allen Verzeichnissen hinzugefügt, die leer sind, sodass diese Verzeichnisse dann dem Index hinzugefügt werden.

<?php
    $path = realpath('.');
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),       RecursiveIteratorIterator::SELF_FIRST);
    foreach($objects as $name => $object){
        if ( is_dir($name) && ! is_empty_folder($name) ){
            echo "$name\n" ;
            exec("touch ".$name."/"."README");
        }
    }

    function is_empty_folder($folder) {
        $files = opendir($folder);
        while ($file = readdir($files)) {
            if ($file != '.' && $file != '..')
                return true; // Not empty
            }
        }
?>

Dann mach

git commit -m "message"
git push
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.