Wie kann ich verhindern, dass .gitignore in der Liste der nicht verfolgten Dateien angezeigt wird?


971

Ich habe gerade eine git initWurzel meines neuen Projekts erstellt.

Dann habe ich eine .gitignoreDatei erstellt.

Wenn ich jetzt tippegit status , wird die .gitignore- Datei in der Liste der nicht verfolgten Dateien angezeigt . Warum ist das so?


13
git add self && git commit -m "-1 for reverting existential depression" && git remote rm HEAD
Alastair

1
Kann ich den Ordner .git / ignorieren und in ".gitignore" ablegen?
Timo

2
Sie können einen globalen "Gitignore" in Ihrem Home-Ordner unter Linux erstellen und dort speichern: git config --global core.excludesfile ~ / .gitignore_global
Timo

14
Ich bin hierher gekommen, indem ich gesucht habe how to gitignore .gitinore fileund die Frage und die akzeptierte Antwort haben nichts mit dem Titel zu tun. Titel könnte verbessert werden.
m.rufca

6
Es gibt Anwendungsfälle zum Ignorieren von .gitignore. Für den Workflow meines Teams muss ich eine Reihe von Dateien für meine lokale Entwicklungsumgebung ändern, diese sollten jedoch nicht festgeschrieben werden. Der Workflow könnte durch eine bessere Architektur verbessert werden, liegt aber nicht in meiner Hand. In der Zwischenzeit ist es eine Verpflichtung, dass git auf diese Dateien achtet. Daher möchte ich sie gitignore, aber nur lokal, und ich möchte nicht riskieren, meinen .gitignore zu verpflichten, da er nicht mit dem Team geteilt werden sollte.
Mark

Antworten:


959

Die .gitignoreDatei sollte sich in Ihrem Repository befinden, also sollte sie tatsächlich hinzugefügt und festgeschrieben werden, wie vorgeschlagen git status. Es muss Teil des Repository-Baums sein, damit Änderungen daran zusammengeführt werden können und so weiter.

Fügen Sie es also Ihrem Repository hinzu, es sollte nicht gitignored werden.

Wenn Sie wirklich möchten, können Sie .gitignoreder .gitignoreDatei hinzufügen , wenn Sie nicht möchten, dass sie festgeschrieben wird. In diesem Fall ist es jedoch wahrscheinlich besser, die Ignorierdaten zu .git/info/excludeeiner speziellen lokalen Checkout-Datei hinzuzufügen, die genau wie .gitignore funktioniert, jedoch nicht im "Git-Status" angezeigt wird, da sie sich im .gitOrdner befindet.

Siehe auch https://help.github.com/articles/ignoring-files


17
Sollte dies nicht Teil der Metadaten des Repositorys sein und nicht eine nachverfolgte Datei?
Endolith

13
Die Repository-Metadaten sind lokal für das Repository. Wenn Sie Ihrem Repo einen Commit-Hook hinzufügen und jemand Ihr Repo klont, erhält er beispielsweise keinen Commit-Hook.
August Lilleaas

91
@wukong, wenn Sie in einem Team arbeiten, sollte nicht jeder die gleichen Dateien ignorieren? Aus diesem Grund wird die .gitignore-Datei zum Repository hinzugefügt. Niemand sagt, dass Sie es als Teil Ihres Projekts bereitstellen müssen.
Ryan Lundy

13
@endolith und wukong Es muss keine Datei in Ihrem Repo sein. Sie können Ihre Ignoriereinstellungen an vielen verschiedenen Stellen vornehmen. GitHub hat einen großartigen Artikel dazu help.github.com/ignore-files Sie können überall globale Ignoriereinstellungen vornehmen und in den .git-Metadaten für das Repo repospezifische Einstellungen vornehmen.
Boushley

6
@ deed02392 Wenn Sie diese Ignorierdateien verwenden, müssen Sie sicher beurteilen, was Sie in sie einfügen, aber sie haben immer noch einige großartige Verwendungsmöglichkeiten. Zum Beispiel benutze ich Vim und so habe ich in meinem globalen Gitignore * .swp-Dateien als ignoriert markiert. Auf diese Weise muss ich es nicht zu jedem meiner Projekte hinzufügen, und Leute, die vim nie verwenden, müssen sich darüber keine Sorgen machen.
Boushley

282

Wenn Sie die Liste der ignorierten Dateien außerhalb Ihres Git-Baums speichern möchten, können Sie die Datei .git / info / exclude verwenden. Es wird nur auf Ihre Kaufabwicklung des Repos angewendet.


19
+1, dies ist ideal für Ignorierungen, die nicht projektbezogen sind, wie z. B. emacs * ~ Sicherungsdateien, .DS_Store von OS X usw.
August Lilleaas

38
@AugustLilleaas Ich persönlich bevorzuge es, diese Arten von {editor, platform} -spezifischen Dateien einzufügen, ~/.gitignoredamit sie für jedes Repository, an dem ich arbeite, ignoriert werden.
Michael Mior

22
Sobald eine Datei nachverfolgt wurde, können Sie die git update-index --assume-unchanged <file>Nachverfolgung von Änderungen beenden, ohne Ihr Repo zu ändern. Dies ist sehr nützlich bei großen gemeinsam genutzten Projekten, bei denen Sie lokale Änderungen vornehmen müssen, aber niemand anderes möchte, dass Ihre Inhalte für das Repo verwendet werden. Siehe blog.pagebakers.nl
Chris Esplin

6
@AugustLilleaas: Gitignore pro Benutzer ist für diesen Anwendungsfall besser.
Mechanische Schnecke

3
danke für diesen tipp, ich benutze git-svn, damit die anderen benutzer des svn repo auf dem server nicht genau wollen, dass .gitignore eingecheckt wird.
enorl76

74

Sie könnten tatsächlich eine Zeile .gitignorein Ihre .gitignoreDatei einfügen. Dies würde dazu führen, dass die .gitignoreDatei von git ignoriert wird. Ich halte das eigentlich nicht für eine gute Idee. Ich denke, die Ignorierdatei sollte versioniert und nachverfolgt werden. Ich werde dies nur der Vollständigkeit halber veröffentlichen.


7
Hat für mich gearbeitet! Version 1.5.6.5. Ich stimme auch 1800 INFORMATION zu, dass es keine gute Idee ist, aber ich denke, dass es in bestimmten Kontexten in Ordnung sein könnte (sagen wir, Sie verwenden ein git-svn-Repository und möchten nicht, dass git-ish-Dateien zu svn gehen). Die Ausschlussdatei ist wahrscheinlich besser.
J. Polfer

4
@ehsanul - Die Datei darf nicht verfolgt werden (Sie sollten sie nicht hinzugefügt oder festgeschrieben haben). Sie können es entfernen. Dies ist wahrscheinlich keine großartige Idee in einer Nur-Git-Umgebung, aber wenn Sie beispielsweise Git als intelligenten Client für ein Subversion-Repository verwenden (ohne dass der Rest weiß, <manisches Lachen>), ist ein solcher Trick großartig.
Tomasz Gandor

2
@IshanSrivastava Sie haben die Datei wahrscheinlich bereits verfolgt. Versuchen Sie zu laufengit rm --cached .gitignore
Gideon

51

Sie können auch eine globale Benutzer-Git- .gitignoreDatei haben, die automatisch auf alle Ihre Repos angewendet wird. Dies ist nützlich für IDE- und Editor-Dateien (z. B. swpund *~Dateien für Vim). Ändern Sie die Verzeichnispositionen entsprechend Ihrem Betriebssystem.

  1. Zu Ihrer ~/.gitconfigDatei hinzufügen:

    [core]
    excludesfile = /home/username/.gitignore
    
  2. Erstellen Sie eine ~/.gitignoreDatei mit Dateimustern, die ignoriert werden sollen.

  3. Speichern Sie Ihre Punktedateien in einem anderen Repo, damit Sie ein Backup haben (optional).

Jedes Mal, wenn Sie ein Repo kopieren, initiieren oder klonen, wird auch Ihre globale Gitignore-Datei verwendet.


6
Ich glaube, dies ist die beste Lösung für Situationen, in denen Ihre Editoren temporäre Dateien zurücklassen, z. B. *. Swp (VIM) und ._ * (TM), da es nicht sinnvoll wäre, diese Regeln kontinuierlich zu jedem Git-Repo hinzuzufügen. und andere Benutzer mit anderen IDEs zu zwingen, nach diesen Dateien zu suchen.
Thomas Hunter II

1
Dies funktioniert hervorragend bei Ignorieren, die nicht in einen Zweig verschoben werden sollten. Ersetzen Sie 'Benutzername' natürlich durch Ihren tatsächlichen Benutzernamen und fügen Sie .gitconfig keinen zweiten Abschnitt [core] hinzu, falls Sie bereits einen haben. Platzieren Sie einfach die Ausschlussdatei-Zeile unter Ihrem vorhandenen Abschnitt [core].
Schmirgel

47

Wenn jemand .gitignoreIhrem Repo bereits ein hinzugefügt hat , Sie jedoch einige Änderungen daran vornehmen und diese Änderungen ignorieren möchten, gehen Sie wie folgt vor:

git update-index --assume-unchanged .gitignore

Quelle .


5
Schlechte Idee, es gibt einen Grund .git/info/excludes.
Arrowmaster

6
Ich nehme an, es gibt auch einen Grund --assume-unchanged. Warum ist einer besser als der andere?
Leif Gruenwoldt

9
Und übrigens .git/info/excludesfunktioniert nicht, wenn die Datei bereits verfolgt wird.
Leif Gruenwoldt

Dies hat mir wirklich bei einem .gitignore geholfen, der bereits festgeschrieben war und für den ich keine Änderungen vornehmen wollte. Ich verwende git 1.7.4.1 unter Ubuntu 11.04-Repos und die Hilfeseiten fügen dies im Update-Index hinzu. "Diese Option kann auch als grober Mechanismus auf Dateiebene verwendet werden, um nicht festgeschriebene Änderungen in nachverfolgten Dateien zu ignorieren (ähnlich wie .gitignore für nicht nachverfolgte Dateien). Git schlägt (ordnungsgemäß) fehl, falls diese Datei im Index geändert werden muss zB beim Zusammenführen in einem Commit. Wenn also die angenommene, nicht verfolgte Datei vorgelagert geändert wird, müssen Sie die Situation manuell behandeln. "
YonahW

Ich stimme für diese Antwort, da Sie diese Aktion im Allgemeinen für Ihren Master-Repo-Ausgangszustand benötigen und die Vorteile der Git-Funktionalität beibehalten. Es gibt keinen guten Grund, diese Datei (Punkt) zu ignorieren
Lazaros Kosmidis

37

Nachdem Sie die .gitignoreDatei hinzugefügt und festgeschrieben haben, wird sie nicht mehr in der Liste "Nicht verfolgte Dateien" angezeigt.

git add .gitignore
git commit -m "add .gitignore file"
git status

20

Nur für den Fall, dass jemand anderes den gleichen Schmerz hat, den wir hatten. Wir wollten eine bereits festgeschriebene Datei ausschließen.

Dieser Beitrag war viel nützlicher: zu spät mit .git / info / exclude arbeiten

Um eine Datei zu ignorieren, müssen Sie den Befehl git remove verwenden. Siehe git rm ( http://www.kernel.org/pub/software/scm/git/docs/git-rm.html ).

Sie testen es, indem Sie gehen

git rm --dry-run *.log
(Wenn Sie sagen, Sie wollten alle Protokolldateien ausschließen)

Dadurch wird ausgegeben, was ausgeschlossen wäre, wenn Sie es ausführen würden .

dann

Sie führen es, indem Sie gehen

git rm *.log
(oder welchen Dateinamen Pfad / Ausdruck Sie möchten)

Fügen Sie *.logdann Ihrer .gitignoreDatei eine Zeile hinzu .


4
Natürlich möchten Sie möglicherweise die entsprechenden Muster (z. B. * .log) zu Ihrem .gitignore hinzufügen, damit sie Ihre nicht überladen, git statuswenn sie in Zukunft angezeigt werden.
Patrick O'Leary

2
Obwohl mein Problem nicht mit dem des OP zusammenhängt: Vielen Dank, dass Sie mich wissen ließen, dass ich RM verwenden müsste, um mein Repo zu "bereinigen", nachdem ich Änderungen an .gitignore vorgenommen habe (wenn Dateien bereits bearbeitet wurden). Noob-Fehler Ich weiß, aber dies war der erste Ort, an dem ich persönlich jemanden gesehen habe, der das erwähnt.
Mike

Danke für die Rückmeldung. Ja, deshalb habe ich es geschrieben, nachdem ich hierher gekommen war und dann den langen Weg gegangen war, um das auch herauszufinden, dachte ich, es wäre gut, es aufzuschreiben. :)
Evolve

16

Natürlich wird die .gitignore-Datei im Status angezeigt, da sie nicht verfolgt wird und git sie als leckere neue Datei zum Essen ansieht!

Da .gitignore jedoch eine nicht verfolgte Datei ist, ist es ein Kandidat, der von git ignoriert wird, wenn Sie ihn in .gitignore einfügen!

Die Antwort ist also einfach: Fügen Sie einfach die Zeile hinzu:

.gitignore # Ignore the hand that feeds!

zu Ihrer .gitignore-Datei!

Und im Gegensatz zu August Antwort, würde ich sagen , dass es nicht , dass die .gitignore Datei sollte in Ihrem Repository sein. Es kommt einfach vor, dass es sein kann , was oft bequem ist. Und es ist wahrscheinlich wahr, dass dies der Grund ist, warum .gitignore als Alternative zu .git / info / exclude erstellt wurde, das nicht die Option hat, vom Repository verfolgt zu werden. In jedem Fall liegt es ganz bei Ihnen, wie Sie Ihre .gitignore-Datei verwenden.

Weitere Informationen finden Sie auf der Manpage zu gitignore (5) auf kernel.org.


15

Die Idee ist, projektspezifische Dateien in die .gitignoreDatei einzufügen und (wie bereits erwähnt) dem Repository hinzuzufügen. Zum Beispiel .pycund .oDateien, Protokolle, die die Testsuite erstellt, einige Fixtures usw.

Für Dateien, die Ihr eigenes Setup erstellt, die jedoch nicht unbedingt für jeden Benutzer .swpangezeigt werden (wie Dateien, wenn Sie vim verwenden, versteckte ecplise-Verzeichnisse und dergleichen), sollten Sie .git/info/exclude(wie bereits erwähnt) verwenden.


14

Zunächst sollten Sie, wie viele andere bereits sagten, .gitignorevon Git verfolgt werden (und sollten daher nicht ignoriert werden). Lassen Sie mich erklären, warum.

(TL; DR: Festschreiben der .gitignoreDatei und Verwenden einer globalen.gitignore Datei, um Dateien zu ignorieren, die von Ihrer IDE oder Ihrem Betriebssystem erstellt wurden.)

Git ist, wie Sie wahrscheinlich bereits wissen, ein verteiltes Versionskontrollsystem . Dies bedeutet, dass Sie zwischen verschiedenen Versionen wechseln können (auch wenn die Entwicklung in verschiedene Branchen unterteilt ist) und dass mehrere Entwickler an demselben Projekt arbeiten können.

Obwohl das Verfolgen Ihrer Daten .gitignoreauch Vorteile bietet, wenn Sie zwischen Snapshots wechseln, ist der wichtigste Grund für das Festschreiben, dass Sie die Datei für andere Entwickler freigeben möchten, die an demselben Projekt arbeiten. Durch das Festschreiben der Datei in Git erhalten andere Mitwirkende die .gitignoreDatei automatisch, wenn sie das Repository klonen, sodass sie sich nicht um das versehentliche Festschreiben einer Datei kümmern müssen, die nicht festgeschrieben werden sollte (z. B. Protokolldateien, Cache-Verzeichnisse, Datenbankanmeldeinformationen) , usw.). Und wenn das Projekt irgendwann .gitignoreaktualisiert wird, können sie diese Änderungen einfach übernehmen, anstatt die Datei manuell bearbeiten zu müssen.

Natürlich gibt es einige Dateien und Ordner, die Sie ignorieren möchten, die jedoch spezifisch für Sie sind und nicht für andere Entwickler gelten. Diese sollten jedoch nicht im Projekt enthalten sein .gitignore. Es gibt zwei weitere Stellen, an denen Sie Dateien und Ordner ignorieren können:

  • Dateien und Ordner, die von Ihrem Betriebssystem oder Ihrer IDE erstellt wurden, sollten global.gitignore abgelegt werden . Der Vorteil ist, dass dies .gitignoreauf alle Repositorys auf Ihrem Computer angewendet wird, sodass Sie dies nicht für jedes Repository wiederholen müssen. Und es wird nicht mit anderen Entwicklern geteilt, da diese möglicherweise ein anderes Betriebssystem und / oder eine andere IDE verwenden.
  • Dateien, die weder zum Projekt .gitignorenoch zum globalen gehören .gitignore, können mithilfe expliziter Repository-Ausschlüsse inyour_project_directory/.git/info/exclude ignoriert werden . Diese Datei wird nicht für andere Entwickler freigegeben und ist spezifisch für dieses einzelne Repository

Schöne Erwähnung für global.gitignore
Gruber

Ich denke, dass nach der Ersteinrichtung die .gitignore-Datei ignoriert werden sollte, damit es keine versehentlichen Änderungen gibt. Es bedeutet nicht, dass es nicht mehr geändert werden kann, aber es ist in gewisser Weise vor Unfällen geschützt. Unfälle in dieser Datei können Verwirrung stiften oder sogar einige Arbeiten gefährden. Daher sollte auch das "Versiegeln" (sich selbst ignorieren) in Betracht gezogen werden.
Sasa

@Sasa .gitignorefunktioniert nur zum Ignorieren von Dateien, die noch nicht von Git verfolgt werden. Das Hinzufügen einer bereits verfolgten Datei .gitignoreverhindert nicht, dass Sie Änderungen an dieser Datei vornehmen. Selbst wenn dies möglich wäre, wie würden Sie die Änderung .gitignorefestschreiben, wenn Git angewiesen wird, sich selbst zu ignorieren?
Nic Wortel

@Nic - Ich habe die ausführliche Erklärung zu meinem Standpunkt in der separaten Antwort @ am Ende dieses Threads übergeben.
Sasa

12

Achten Sie auf das folgende "Problem" Manchmal möchten Sie Verzeichnisse hinzufügen, aber keine Dateien in diesen Verzeichnissen. Die einfache Lösung besteht darin, einen Gitignore mit folgendem Inhalt zu erstellen:

*

Dies funktioniert einwandfrei, bis Sie feststellen, dass das Verzeichnis nicht hinzugefügt wurde (wie erwartet zu Ihrem Repository. Der Grund dafür ist, dass der .gitignore ebenfalls ignoriert wird und das Verzeichnis daher leer ist. Daher sollten Sie so etwas tun ::

*
!.gitignore

9

Dies scheint nur für Ihr aktuelles Verzeichnis zu funktionieren, um Gitalle Dateien aus dem Repository zu ignorieren.

Aktualisieren Sie diese Datei

.git/info/exclude 

mit Ihrem Platzhalter oder Dateinamen

*pyc
*swp
*~

5

Wenn Sie .gitignore bereits eingecheckt haben und Änderungen daran ignorieren möchten, lesen Sie diese Antwort :

Versuchen Sie es mit diesem Befehl:

git update-index --assume-unchanged FILENAME_TO_IGNORE

Verwenden Sie zum Umkehren (falls Sie jemals Änderungen daran vornehmen möchten):

git update-index --no-assume-unchanged

UPDATE :

So listen Sie "unveränderte" Dateien im aktuellen Verzeichnis auf:

git ls-files -v | grep -E "^[a-z]"

Da die -vOption Kleinbuchstaben für "unveränderte" Dateien verwendet.


4

In meinem Fall möchte ich eine vorhandene Datei ausschließen. Nur das Ändern von .gitignore funktioniert nicht. Ich habe diese Schritte befolgt:

git rm --cached dirToFile/file.php
vim .gitignore
git commit -a

Auf diese Weise habe ich die Datei, die ich ausschließen wollte, aus dem Cache entfernt und nachdem ich sie zu .gitignore hinzugefügt habe .


beste Lösung für mich. Sie können auch git add verwenden. an zweiter Stelle, nach diesem Git Commit -m "Fixing .gitignore"
Brainray

3

Navigieren Sie zum Basisverzeichnis Ihres Git-Repos und führen Sie den folgenden Befehl aus:

echo '\\.*' >> .gitignore

Alle Punktedateien werden ignoriert, einschließlich des lästigen .DS_Store, wenn Sie auf einem Mac arbeiten.


4
Das würde ich nicht tun. Möglicherweise benötigen Sie Punktdateien. Stattdessen würde ich einfach .gitignore und .DS_Store buchstäblich hinzufügen.
Edward Falk

2

Es ist durchaus möglich, dass ein Endbenutzer möchte, dass Git die Datei ".gitignore" ignoriert, nur weil die von Eclipse erstellten IDE-spezifischen Ordner wahrscheinlich nicht mit NetBeans oder einer anderen IDE identisch sind. Um die IDE des Quellcodes antagonistisch zu halten, ist es einfach, ein benutzerdefiniertes Git zu ignorieren, das nicht für das gesamte Team freigegeben ist, da einzelne Entwickler möglicherweise unterschiedliche IDEs verwenden.


1

.gitignoregeht es darum, andere Dateien zu ignorieren . Bei git geht es um Dateien, also geht es darum, Dateien zu ignorieren. Da git jedoch Dateien bearbeitet, muss diese Datei als Mechanismus zum Auflisten der anderen Dateinamen vorhanden sein.

Wenn es genannt .the_list_of_ignored_fileswürde, könnte es etwas offensichtlicher sein.

Eine Analogie ist eine Liste von Aufgaben, die Sie NICHT ausführen möchten. Wenn Sie sie nicht irgendwo auflisten, handelt es sich um eine Art Aufgabenliste, von der Sie nichts wissen.


1

Ich denke, dass es Situationen gibt, in denen das Ignorieren des .gitignore sehr nützlich ist. Zum Beispiel, wenn mehrere Teams oder ein großes Team an derselben Codebasis arbeiten. In diesem Fall müssen Sie bestimmte Konventionen haben. Eine dieser Konventionen betrifft das, was beim Git Repo ignoriert wird. In der Regel werden von IDE oder Betriebssystem erstellte Dateien und Verzeichnisse, einige generierte Protokolle usw. ignoriert.

Es gibt jedoch eine Kraft, die dazu neigt, unkonventionelle Änderungen an der .gitignoreDatei vorzunehmen . Die .gitignoreDatei kann von einer verantwortungslosen Person, aus Versehen, von einem verwendeten Werkzeug oder in einem anderen Fall weiter geändert werden.

Um dem entgegenzuwirken, können wir wie folgt vorgehen:

  1. Der anfängliche .gitignore sollte die Konvention in Team (en) widerspiegeln.
  2. Nach dem Push sollte der .gitignore durch Hinzufügen eines .gitignore-Eintrags gesichert werden und diese Änderung erneut übertragen werden. Die .gitignoreDatei wird auf diese Weise " versiegelt ".

Die " versiegelte " .gitignoreDatei kann nur lokal geändert werden, ohne dass diese Änderungen an andere Mitglieder des Teams weitergegeben werden. Wenn jedoch eine Änderung im gesamten Team weitgehend vereinbart ist, ist es möglich, sie zu "entsiegeln", zu ändern und dann erneut zu "versiegeln". Das kann nicht versehentlich gemacht werden, nur absichtlich.

Leider können Sie nicht zu 100% vor der Dummheit geschützt werden, aber auf diese Weise haben Sie alles getan, um zu verhindern, dass dumme Dinge passieren.

Wenn Sie ein relativ kleines Team mit sehr guten Fachleuten haben, wäre dies nicht wichtig, aber selbst diese Leute würden es begrüßen, wenn sie sich weniger Sorgen machen müssten.

Die Verwendung .git/info/excludeist cool, wenn Sie nichts an den Infrastruktureinstellungen ändern können, sondern nur Ihre eigenen a ** abdecken, um keinen Fehler zu machen.

Unter dem Gesichtspunkt, was richtig und was falsch ist, stimme ich dafür, dass .gitignore in die .gitignoreDatei aufgenommen wird, damit jeder die Freiheit hat, vor Ort zu tun, was er will, aber nicht in andere einzudringen.


0

Ich fand, dass der beste Ort, um ein Ignorieren der lästigen .DS_StoreDateien einzurichten, in der .git/info/excludeDatei ist.

IntelliJ scheint dies automatisch zu tun, wenn Sie ein Git-Repository darin einrichten.


1
Die globale Ignorierdatei des Benutzers ist ein besserer Ort, um .DS_Store
Max Nanasy
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.