Gits magische Dateien
(nesbitt.io)- Git steuert sein Verhalten über bestimmte Dateien im Repository; diese sind keine Konfigurationen innerhalb von
.git/, sondern versionierte Dateien, die zusammen mit dem Code mitwandern .gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmapusw. sind jeweils für das Ausschließen von Dateien aus dem Tracking, die Definition von Attributen, LFS-Konfiguration, Submodul-Verwaltung und die Zusammenführung von Autoreninformationen zuständig.git-blame-ignore-revsund.gitmessagebieten das Ignorieren von Code-Formatierungs-Commits bzw. Vorlagen für Commit-Nachrichten und verbessern so die Qualität der Zusammenarbeit- GitHub, GitLab, Gitea usw. erweitern Funktionen wie CI/CD und die Zuweisung von Reviewern über plattformspezifische Konfigurationsordner wie
.github/,.gitlab/,.gitea/ - Diese Struktur reicht über Git hinaus auch in EditorConfig, Docker und Tools zur Sprachversionsverwaltung hinein und bildet so ein Ökosystem automatischer Konfiguration auf Basis von Dotfiles
Wichtige magische Dateien von Git
- Git erkennt verschiedene spezielle Dateien wie
.gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmap, um das Verhalten des Repositorys zu steuern- Diese Dateien sind keine internen Einstellungen in
.git/, sondern versionierte und gemeinsam genutzte Konfigurationsbestandteile, die bei der Zusammenarbeit ein einheitliches Verhalten sicherstellen
- Diese Dateien sind keine internen Einstellungen in
.gitignore
- Definiert Dateimuster, die Git nicht verfolgen soll
- Unterstützt Wildcards (
*.log), Verzeichnisse (dist/) und Negationen (!important.log) - Wird in der Reihenfolge
.gitignore,.git/info/exclude, globale Konfiguration (~/.config/git/ignore) angewendet
- Unterstützt Wildcards (
- Bereits verfolgte Dateien werden auch nach dem Hinzufügen zu
.gitignoreweiter verfolgt und können mitgit rm --cachedentfernt werden - GitHub, GitLab, Gitea usw. erlauben es, Dateien, die zu ignorierten Mustern passen, trotzdem ohne Warnung zu committen
- GitHub stellt sprachspezifische
.gitignore-Vorlagen im offiziellen Repository bereit
.gitattributes
- Steuert pro Datei Filter, Diff, Merge, Zeilenenden und Spracherkennung
- Zum Beispiel:
*.psd filter=lfs,*.png binary,*.sh text eol=lf
- Zum Beispiel:
textnormalisiert Zeilenenden,binarydeaktiviert Diff/Merge,merge=oursbehält bei Konflikten die lokale Version bei- GitHub Linguist liest
.gitattributes, um Sprachstatistiken auszuschließen, generierten Code einzuklappen und Dokumentation auszunehmen - Erkennt außerdem
.gitattributespro Verzeichnis sowie.git/info/attributes
.lfsconfig
- Speichert Git-LFS-Konfiguration gemeinsam mit dem Repository
- Konfigurierbar sind z. B. die URL des LFS-Servers und die Anzahl von Transfer-Wiederholungen
- Beispiel:
[lfs] url = https://lfs.example.com/repo [lfs "transfer"] maxretries = 3
- In
.gitattributeswerden die per LFS zu behandelnden Dateien festgelegt, während.lfsconfigDetails wie den Serverstandort übernimmt - Um Dateien aus bestehenden Commits nach LFS zu migrieren, ist der Befehl
git lfs migrateerforderlich
.gitmodules
- Speichert Konfigurationsinformationen für Submodule
- Enthält Pfad, URL und Branch-Informationen jedes Moduls
- Beispiel:
[submodule "vendor/lib"] path = vendor/lib url = https://github.com/example/lib.git branch = main
- Wird bei
git submodule adderstellt und beigit submodule updatereferenziert - Bei
git clonewerden Submodule nicht automatisch geholt; dafür ist die Option--recurse-submodulesnötig - Nachteile sind unter anderem fehlendes Tracking von Versionsbereichen und die Erzeugung verschachtelter
.git-Verzeichnisse
.mailmap
- Dient der zentralen Zusammenführung von Autorennamen und E-Mail-Adressen
- Beispiel:
Jane Developer <[email protected]> <[email protected]>
- Beispiel:
- In
git log,git shortlog,git blameusw. werden die zusammengeführten Namen angezeigt - Das Beitragsdiagramm von GitHub berücksichtigt mailmap nicht
- Der Speicherort kann über
.mailmapoder die Einstellungmailmap.filefestgelegt werden
.git-blame-ignore-revs
- Legt eine Liste von Commits fest, die
git blameignorieren soll- Schließt bedeutungsarme Änderungen wie Formatter-Läufe oder angewendete Lint-Regeln aus
- Beispiel:
# Ran prettier on entire codebase a1b2c3d4e5f6g7h8i9j0...
- Aktivierung mit
git config blame.ignoreRevsFile .git-blame-ignore-revs - GitHub, GitLab (15.4+) und Gitea erkennen die Datei automatisch
- Wenn die Datei fehlt, kann es zu Fehlern kommen; daher wird empfohlen, eine leere Datei beizubehalten
.gitmessage
- Definiert eine Vorlage für Commit-Nachrichten
- Beispiel:
# <type>: <subject> # # Types: feat, fix, docs, style, refactor, test, chore
- Beispiel:
- Muss mit
git config commit.template .gitmessagekonfiguriert werden - Nach dem Klonen ist eine manuelle Einrichtung nötig; manche Teams automatisieren das mit husky o. Ä.
- Als Alternativen können
commit-msg-Hook oderprepare-commit-msg-Hook verwendet werden
Plattformbezogene Erweiterungsordner
- GitHub, GitLab, Gitea, Forgejo, Bitbucket usw. verwenden eigene Konfigurationsordner
.github/,.gitlab/,.gitea/,.forgejo/,.bitbucket/
- Sie enthalten CI/CD-Workflows, Vorlagen für Issues und PRs, CODEOWNERS-Dateien usw.
- Forgejo verwendet Fallbacks in der Reihenfolge
.forgejo/ → .gitea/ → .github/, Gitea in der Reihenfolge.gitea/ → .github/ - SourceHut verwendet
.build.ymloder.builds/*.yml
Weitere konventionelle Dateien
- .gitkeep: Da Git keine leeren Verzeichnisse verfolgt, wird diese Datei als Platzhalter verwendet, um Verzeichnisse beizubehalten
- .gitconfig: Kann projektbezogene Git-Konfigurationsbeispiele bereitstellen, wird aber nicht automatisch geladen
- .gitsigners: Verwaltet die Liste von GPG-/SSH-Signaturschlüsseln und kann über
gpg.ssh.allowedSignersFileangegeben werden - .gitreview: Konfigurationsdatei für den Gerrit-Code-Review-Server
- Beispiel:
[gerrit] host=review.opendev.org port=29418 project=openstack/nova.git defaultbranch=master
- Beispiel:
- .gitlint: Definiert Lint-Regeln für Commit-Nachrichten
- Beispiel:
[general] ignore=body-is-missing [title-max-length] line-length=72
- Beispiel:
- .jj/: Statusverzeichnis von Jujutsu, einem Git-kompatiblen VCS, das neben
.git/existieren kann
Das Dotfile-Ökosystem über Git hinaus
- .editorconfig: Sorgt für einen konsistenten Code-Stil über verschiedene Editoren hinweg
- Definiert Einrückung, Zeilenenden, Kodierung, Entfernen von Leerraum usw.
- Unterstützt von wichtigen Editoren wie VS Code, Vim und Emacs
- .ruby-version, .node-version, .python-version: Werden von Tools zur Sprachversionsverwaltung (rbenv, nodenv, pyenv usw.) gelesen und lösen automatische Umschaltung aus
- .tool-versions: Mehrsprachige Versionsverwaltungsdatei von asdf
- .dockerignore: Legt fest, welche Dateien beim Docker-Build ausgeschlossen werden
- Verwendet dieselbe Muster-Syntax wie
.gitignore, verbessert die Build-Geschwindigkeit und schließt Geheimnisse aus
- Verwendet dieselbe Muster-Syntax wie
Was bei der Entwicklung von Git-integrierten Tools zu beachten ist
- Tools, die mit Git-Repositories arbeiten, sollten die folgenden Dateien unbedingt erkennen
.gitignore: Anwenden von Ignoriermustern bei der Dateisuche.gitattributes: Unterscheidung zwischen Binär- und generierten Dateien.mailmap: Einheitliche Anzeige von Autoreninformationen.gitmodules: Behandlung von Submodulen
- Das Format von Git-Konfigurationsdateien folgt der Struktur
[section "subsection"] key = valueund kann mit dem Befehlgit configgelesen und geschrieben werden - Die meisten Git-Bibliotheken für verschiedene Programmiersprachen bieten Funktionen zum Parsen dieses Formats
2 Kommentare
gitmessagekannte ich noch nicht, das werde ich ausprobieren.Hacker-News-Kommentare
.gitignorerespektieren und ignorierte Dateien daher in der Web-UI nicht anzeigen, aber das scheint eine falsche Erklärung zu sein.Tatsächlich werden sie nicht angezeigt, weil die ignorierten Dateien nicht im Repository enthalten sind. Wenn eine Datei bereits committet wurde, sollte sie meiner Meinung nach eher angezeigt werden.
.gitignorehinzufügt, bleibt sie in der UI weiterhin sichtbar. Die Datei ist immer noch Teil des Repos.Umgekehrt kann man eine von Anfang an ignorierte Datei auch mit Gewalt committen, dafür braucht man aber einen kleinen Trick.
.gitignorelegt nur fest, ob untracked Dateien ausgeblendet werden. Wenn man will, kann man auch ignorierte Dateien committen.showinwebui=(true|false)gut 😄.git/info/excludehervorheben. Das ist ein nur lokales gitignore, also eine Einstellung nur für mich.Zum Beispiel ist es nützlich, wenn ich bei der Untersuchung eines Bugs temporäre Dateien anlege und sie beim Wechseln des Branches behalten möchte.
Ich nutze dafür ein Shell-Alias wie dieses: So kann man mit
git-ignore-local myfile.extganz einfach einen Eintrag hinzufügen.Unter MacOS muss man nur den
readlink-Teil anpassen. Wenn man diese Funktion untergit-ignore-localim PATH registriert, kann man sie wiegit ignore-localverwenden..git/info/excludewird auch ganz am Anfang der Erklärung zu.gitignoreerwähnt./test export-ignorezu.gitattributeshinzufügt, kann man beim Deployment auf Produktionsserver Testdateien ausschließen.Wenn Deployment-Tools wie Capistrano
git exportverwenden, wird das automatisch angewendet, sodass die Testdateien nicht auf dem Server landen.Während der Entwicklung hat das keine Auswirkungen und spart trotzdem Plattenplatz.
git archiveselbst kaum zu kennen.Ich habe gesehen, dass es sogar in grundlegenden CI-Tools fast nie verwendet wird. Capistrano war für mich das erste Beispiel, das es nutzt.
Mit der Option
export-substkann man übrigens auch Informationen ähnlich wie beigit describedirekt in Dateien einfügen.jjwollte ich den.jj-Ordner vollständig aus dem Repo und aus allen Git-Operationen heraushalten.Also auch so, dass er von
git clean -xdfnicht gelöscht wird. Im Moment löse ich das provisorisch mit einem Aliasgit clean -e .jj..git/info/excludeverwenden..mailmapnicht.Die dazugehörige Diskussion steht in der GitHub Community Discussion.
package-lock.json merge=oursfür riskant.Denn bei merge oder rebase ist die Bedeutung von ours/theirs nicht eindeutig.
Solche Einstellungen sind nur in automatisierten Merge-Tools sinnvoll, etwa beim Branch von git-annex.
Siehe dazu: Erklärung der Bedeutung von ours/theirs, interne Struktur von git-annex
.git-blame-ignore-revsist eine gute Funktion, gehört aber eher in den Abschnitt „sonstige Konventionen“.Wenn man den Git-Client nicht entsprechend konfiguriert, schlägt git blame in Repositories ohne diese Datei fehl.
(:optional)verwenden, damit es auch ohne die Datei keinen Fehler gibt.Eine Erklärung dazu gibt es in dieser Stack-Overflow-Antwort.
Schade ist nur, dass nicht alle Tools
.mailmapunterstützen. IntelliJ hat dafür zum Beispiel noch immer nur einen Bug-/Feature-Request-Status.Außerdem ist
.git-blame-ignore-revsnur eine einfache Konvention und funktioniert nicht ohne eigene Konfiguration..ignoreerkennt.Ich dachte, es würde nur
.gitignoregelten, aber als ich in.ignoredie ripgrep-Einstellungen geändert habe, sahen die Suchergebnisse anders aus. Im Nachhinein war das ein nachvollziehbares Verhalten.Link: Artikel auf nesbitt.io