Was ist der einfachste Weg, um mit Projektkonfigurationsdateien umzugehen?

79

Es ist sehr üblich, dass in einem Projekt mindestens eine Konfigurationsdatei vorhanden ist. Jedes Mal, wenn ich ein Projekt mit teile git, habe ich das gleiche Problem mit:

  • vertrauliche Informationen (jeder Entwickler hat unterschiedliche DB-Passwörter usw.)
  • aufgabenspezifische Informationen (wenn der Entwickler an einer bestimmten Aufgabe arbeitet, bei der einige Einstellungen geändert werden müssen)

Offensichtlich müssen Konfigurationen irgendwie ignoriert werden, um zu verhindern, dass entwicklerspezifische Daten das Haupt-Repository überfluten. Jetzt gibt es verschiedene Möglichkeiten, die ich verwendet habe, jede mit einigen Fehlern:

  • .gitignore die Konfigurationsdateien
    • der einfachste Weg
    • Wenn Entwickler Repo klonen, fehlt die Konfigurationsdatei und man muss herausfinden, wo die Konfigurationen sie neu erstellt haben
  • Konfigurationsdatei wird nicht ignoriert. Es enthält einige Dummy-Informationen, die jeder Entwickler entweder aufspürt und in seine Datei einfügt .git/info/excludeoder git update-index --assume-unchanged ...auf die Datei setzt
    • Dateien sind für alle verfügbar, die Repo klonen
    • Es enthält fortgeschrittene Techniken, die Leute verwirren könnten, die zum ersten Mal mit Git arbeiten
    • Wenn jemand versehentlich Konfigurationsdateien festschreibt, können Benutzer nicht ziehen / abrufen (da Ausschlüsse nicht auf die gleiche Weise funktionieren wie .gitignore)
  • Verteilen Sie Konfigurationsdateien, denen beispielsweise ein Suffix hinzugefügt wurde, _originalwährend Sie die realen Dateien in haben .gitignore. Jeder Entwickler benennt dann Dateien in echte Namen um
    • Dateien sind für alle verfügbar, die Repo klonen
    • man muss während der gesamten Anwendung nach allen Konfigurationen suchen und sie umbenennen

Gibt es andere, möglicherweise bessere Möglichkeiten, damit umzugehen? Ich vermute, ich vermisse etwas, zumindest ein Plugin.

Ondrej Slinták
quelle
stackoverflow.com/questions/5132152/… könnte auch hier helfen.
VonC
ok, ich habe dann als Antwort Details zur Filtertreiberoption hinzugefügt.
VonC
Hallo zusammen, was bedeutet diese Aussage? when someone commits config files by accident, it won't allow people to pull/fetch (as excludes don't work the same way as .gitignore)
AnnieFromTaiwan
Nichts mehr von dem, was ich versucht habe. Wenn jemand versehentlich eine ausgeschlossene Datei drückt, scheint das Ziehen auf einem anderen Computer die ausgeschlossene Datei einzeln von oben zu überschreiben. Zumindest mit meinem Git 2.5.4. Ich bin mir nicht sicher, ob es jemals anders funktioniert hat.
Ondrej Slinták

Antworten:

22

Filtertreiber sind die "automatische" Methode zur Implementierung von Option 3, wie unter " Wenn Sie einen geheimen Schlüssel in Ihrem Projekt haben, wie kann ein Push auf GitHub möglich sein? " Beschrieben wird :

Geben Sie hier die Bildbeschreibung ein

Das smudgeSkript wird beim Auschecken:

  • Ermitteln Sie die richtigen Konfigurationsdateien zum Ändern
  • Holen Sie sich die benötigten Informationen (am besten außerhalb eines Git-Repos ) und ersetzen Sie die Vorlagenwerte durch die tatsächlichen.

Von dort aus können die Entwickler jede gewünschte Änderung an diesen Konfigurationsdateien vornehmen.
Dies spielt keine Rolle, da das cleanSkript beim Festschreiben den Inhalt dieser Datei auf seinen ursprünglichen Wert (Vorlagenwert) zurücksetzt. Kein versehentlicher Druck.

VonC
quelle
Ich mag dieses bisher am besten. Wo würde dieses Wischskript platziert werden? Soweit ich weiß, sollte es auf einem Computer platziert werden, auf dem sich das zentrale Git-Repo befindet. Wie würde es dann eingehende Commits erkennen, die wieder normalisiert werden sollten?
Ondrej Slinták
1
@Ondrej: Das Smudge-Skript sollte vom Benutzer referenziert werden PATHoder über ein gemeinsames Verzeichnis zugänglich sein (das von den Entwicklern gemeinsam genutzt wird, wenn es sich um eine Gruppe im selben LAN handelt). Commits werden nicht geändert . Der Inhalt der Datei wird erst beim Auschecken geändert. Und das saubere Skript ändert seinen Inhalt kurz vor dem Festschreiben.
VonC
@Ondrej: Siehe stackoverflow.com/questions/2316677/… als Beispiel, aber denken Sie daran, dass diese Skripte auf dem Inhalt der Datei basieren , nicht auf ihrem Namen oder Pfad: Lesen Sie sorgfältig stackoverflow.com/questions/2562523/… : it Es ging darum, den Filtertreiber zu verwenden, um den Pfad der Datei in den Dateiinhalt selbst einzufügen, und das ist nicht möglich: Ein Filtertreiber hat nur den Inhalt der Datei als Eingabe. Nicht sein Name oder Pfad.
VonC
17

Die Art und Weise, wie wir es bei dem letzten Projekt gemacht haben, an dem ich gearbeitet habe, bestand darin, eine Master-Konfigurationsdatei zu haben, die eine lokale Konfigurationsdatei des Benutzers lud, falls vorhanden, die die im Master festgelegten Standardeinstellungen überschreiben konnte, falls angegeben, und ihre eigenen Konfigurationsinformationen deklarierte, wenn sie nicht vorhanden waren im Meister. Die lokale Datei wurde zu gitignore hinzugefügt. Auf diese Weise können alle gängigen Inhalte gemeinsam genutzt werden und einige Konfigurationen sind immer vorhanden, und jeder Entwickler kann seine lokalen Einstellungen ändern.

Pest
quelle
4
Dies sowie eine README-Datei, in der erläutert wird, wo die lokale Konfigurationsdatei abgelegt werden soll.
Haydenmuhl
6

Da ich eine Weile gebraucht habe, um eine funktionierende Lösung mit den Hinweisen von @VonC zu finden, finden Sie hier ein vollständiges Beispiel für das Ignorieren von Kennwörtern mit einem Git Clean-Filter in einer Objective-C-Headerdatei.

  1. Angenommen, Sie haben ein Standardkonfigurationsskript Config.hmit diesem Namen

    // Change "12345" to your password
    #define kPass @"12345"
    #define kConstant 42
    
  2. Erstellen Sie ein Skript hidepass.sh, das den kritischen Zeilen entspricht, und drucken Sie stattdessen die Standardzeile

    #!/bin/sh
    awk '{ if (/#define kPass/) print "#define kPass @\"12345\""; else print $0; }'
    exit 0
    
  3. Machen Sie das Skript ausführbar und fügen Sie es dem Repo hinzu

  4. Sagen Sie git, dass es Ihre Konfigurationsdatei filtern soll, indem Sie diese Zeile .gitattributeshinzufügen (fügen Sie Ihrem Repo auch .gitattributes hinzu).

    Config.h filter=hidepass
    
  5. Weisen Sie git an, das hidepass.shSkript für den Hidepass- Filter während der Bereinigung zu verwenden:

    git config filter.hidepass.clean ./hidepass.sh
    

Das war's, Sie können jetzt das Passwort in ändern Config.h aber git übernimmt diese Änderung nicht, da diese Zeile beim Einchecken immer durch die Standardzeile ersetzt wird.

Dies ist eine schnelle Lösung für ein einzeiliges Passwort. Sie können verrückt werden und z. B. die zu ignorierenden Zeilen mit einer speziellen Zeichenfolge beenden und nach Zeilen mit dieser Zeichenfolge suchen.

Pascal
quelle
3

In Projekten, die ich bisher durchgeführt habe, haben wir eine Standardkonfiguration, und Entwickler haben ihre eigene Konfiguration an einem bestimmten Ort außerhalb der Versionskontrolle (Konvention über Konfiguration). Die Werte der letzteren werden verwendet, um die Werte der ersteren zu überschreiben.

Wir haben begonnen, die Verschlüsselung für vertrauliche Details in der Konfiguration zu verwenden: Behandeln von Kennwörtern in der Produktionskonfiguration für die automatisierte Bereitstellung

Im Falle von Git können Sie git attributes filter attributesowohl das Ersetzen lokaler Werte als auch das Entschlüsseln sensibler Werte auf automatisierte Weise durchführen.

Sie können auch Submodule haben, die das production.ymlund mit eingeschränktem Zugriff auf das Submodul-Repo haben.

Manojlds
quelle
2

Eine Sache, an die ich denken kann, ist ähnlich wie bei Methode 2 und Methode 1 oben. Wenn Sie ein Verzeichnis haben, in dem Sie komplexe Dinge speichern, die für die Site eindeutig sind, z. B. Verzeichnisse für Konfigurationsdateien, vom Benutzer hochgeladene Dateien usw.

Sie halten nur die Konfigurationsdatei selbst von der Versionskontrolle fern, haben dann aber eine Dummy-Kopie, deren Name sich geringfügig von der tatsächlichen Verwendung der Site unterscheidet. Diese Datei enthält detaillierte Anweisungen zu den Konfigurationsparametern und zum Erstellen einer umbenannten Kopie.

Angenommen, Sie haben ein Verzeichnis "site_profile". In diesem Verzeichnis erstellen Sie eine Datei mit dem Namen "README.settings.php" sowie ein Verzeichnis "files", das vom Benutzer hochgeladene Dateien enthält (sowohl von Administratoren als auch von Front-End-Benutzern). All dies unterliegt der Versionskontrolle.

Die Site führt ihre Einstellungen jedoch über "settings.php" aus, die hier nicht vorhanden sind. Wenn Sie jedoch "README.settings.php" in "settings.php" umbenennen würden, hätten Sie die Konfigurationsdatei, die Sie benötigen (nachdem Sie natürlich Ihre benutzerdefinierten Einstellungen vorgenommen haben).

Auf diese Weise können Sie den anderen Entwicklern mitteilen, was sie aus ihrer Konfigurationsdatei benötigen, während Sie Ihre eigene Konfigurationsdatei aus dem Mix heraushalten. Stellen Sie einfach Ihre Konfigurationsdatei so ein, dass sie ignoriert wird, oder führen Sie niemals ein pauschales Festschreiben für dieses Verzeichnis und niedriger durch.

Es ist das, was wir mit Drupal-Sites machen, auf denen ich arbeite, und es funktioniert wirklich gut.

Patrick
quelle
2

Für die beiden Fälle, die Sie erwähnen:

  • vertrauliche Informationen (jeder Entwickler hat unterschiedliche DB-Passwörter usw.)

    Schreiben Sie Ihre Skripte so, dass diese vertraulichen Dateien im Home-Verzeichnis des Entwicklers und nicht im Projektverzeichnis gespeichert werden.

  • aufgabenspezifische Informationen (wenn der Entwickler an einer bestimmten Aufgabe arbeitet, bei der einige Einstellungen geändert werden müssen)

    Normalerweise habe ich die Standardeinstellungen im Repository eingecheckt. Wenn Sie dann Ihre Commits vorbereiten, können Sie leicht überprüfen, ob Sie eine dieser Einstellungen geändert haben, und sie vor dem Commit zurücksetzen.

avh4
quelle
2

Ich habe meine lokalen Konfigurationsänderungen in einem Git-Stash gespeichert. Ich verwende git stash apply anstelle von pop, damit ich es nie aus der Stash-Warteschlange entferne. Auf diese Weise kann ich reset --hard verwenden, wann immer ich Lust dazu habe.

Casebash
quelle
0

Sie haben keine Erfahrung mit Git, haben sich aber in anderen Kontexten mit denselben Problemen befasst (Hibernate-Anmelde-Creds in einer Spring JUnit-Suite oder ANT-Skripte), für alles, was benutzerspezifisch ist oder von der lokalen Umgebung eines Benutzers abhängt:

  1. Haben Sie eine README-Datei, in der diese Abhängigkeiten aufgelistet sind und wie Sie Ihre lokale Umgebung für die Ausführung des Skripts konfigurieren.
  2. Ersetzen Sie diese Abhängigkeiten in Ihrer Conf durch Aufrufe von Systemeigenschaften oder eine Framework-Methode zum Abrufen externer Werte. In einem ANT - Skript, zum Beispiel, können Sie Zeichenfolge ersetzen <sysproperty key="jdbc.username" value="${jdbc.username}"/>, wo jdbc.usernameeine Systemvariable ist (die Sie in Eclipse einstellen).

Entwickler können einchecken, was sie wollen, da das conf benutzerunabhängig ist.

ein Zug
quelle
0

Viele gute Optionen aufgelistet. Einige weitere Optionen zu erwähnen:

  • Fügen Sie alle Konfigurationen zu .gitignore hinzu. Dann haben Sie ein separates Git-Projekt mit nur den Konfigurationsdateien. (Bewahren Sie dieses GIT # 2 in einem völlig anderen Ordner auf.) Erstellen Sie in diesem GIT # 2 einige ähnliche Skripte wie apply-config /path/to/my_git1:save-config /path/to/my_git1 die kopieren oder Konfigurationsdateien für das Haupt-GIT-Repo speichern.
    • Ich bevorzuge die Verwendung von Submodulen. Ich habe festgestellt, dass die Arbeit mit Submodulen in einem großen Team umständlich ist.
    • Sie können dann Konfigurationen verfolgen oder mehrere GIT-Repos für Dinge wie Produktionseinstellungen, Debug-Einstellungen, optimierte Einstellungen usw. verwenden.
    • Verwendet ein Tool (GIT), das jeder versteht.
  • Ich mag die Idee, im Home-Ordner nach vertraulichen Dingen wie DB-Verbindungsinformationen zu suchen. (Erwähnt von @avh)
  • Für devOps sollten Sie Dinge wie Ansible / Salt / Chef / Puppet in Betracht ziehen, um Bereitstellungen und Einstellungen zu automatisieren.
SilentSteel
quelle
-1

Eine weitere sehr häufige Option, die von The Twelve-Factor App populär gemacht wird , besteht darin, keine Konfigurationsvariablen in Dateien fest zu codieren, sondern sie aus Umgebungsvariablen zu laden. Auf diese Weise benötigen die Dateien im Repository keine besondere Behandlung.

Ondrej Slinták
quelle