Schnipsel aus dem Zettelkasten


Fossil SCM

Versionsverwaltung auf Basis von SQLite

Inhalt

Was ist Fossil?

  • Fossil SCM ist ein verteiltes Versionsverwaltungssystem. Anders als Git und Mercurial bietet Fossil zusätzlich Eigenschaften, zum Beispiel ein eingebettetes Wiki und ein Ticket-System. Als einfache, ausführbare Datei ist es deutlich leichter selbst zu hosten als vergleichbare Lösungen wie GitLab.
  • Git wurde entwickelt, um eine eher lose verbundene Entwickler-Gemeinde zu unterstützen (einen “Basar” im Sinne von Eric S. Raymond). Fossil hingegen eignet sich besser für kleine Gruppen, die eng verbunden agieren (die “Kathedrale”). Dies ist auch mit ein Grund, warum an Stelle eines Push die Autosync-Funktionalität entwickelt wurde: Die beteiligten Personen sollen immer eng am übergeordneten Repository arbeiten.
  • Obwohl Fossil grundsätzlich auch große Dateien verarbeiten kann, so ist es für große Projekte (>20 GB) nicht geeignet, da die Synchronisierung mit einem entfernten Repository sehr lange dauert.
  • Fossil ist für die meisten Unix-artigen Betriebssysteme verfügbar, vorkompilierte Binaries sind auch für Windows und MacOS vorhanden.

Arbeiten mit Fossil

  • Sämtliche Befehle können mit fossil help <cmd> untersucht werden.
  • Alle zu einem Projekt gehörenden Dateien befinden sich in nur einer Datei mit der Endung .fossil. Bei dieser Dabei handelt es sich um eine SQLite-Datenbank, die mit dem Fossil-Programm verwaltet wird.
  • Eine solche Repository-Datei erzeugt der Befehl fossil new prj.fossil. Es ist sinnvoll, sich vorher zu überlegen, wo im Dateisystem die Repository-Dateien liegen sollen; eine Möglichkeit ist ein Verzeichnis .repos im Heimatverzeichnis.
  • Nach dem Erzeugen einer Repository-Datei kann allerdings noch nicht damit gearbeitet werden, zunächst muss sie in einem Arbeitsverzeichnis geöffnet werden: mkdir <prj> && cd <prj> && fossil open ~/.repos/prj.fossil. Es erscheint eine Datei namens .fslckout. Jetzt ist es möglich, Dateien und Verzeichnisse zum neuen Projekt hinzuzufügen. Das funktioniert wie anderen VCS mit dem Befehl add: fossil add <Datei oder Verzeichnis>. Umbenennen ist ebenfalls möglich: fossil mv <old> <new> (mvist gleichbedeutend mit rename).
  • Dateien lassen sich “löschen” mit fossil rm <datei>, allerdings löscht dieser Aufruf nicht die Datei oder das Verzeichnis im Dateisystem, sondern nimmt sie nur aus der Versionsverwaltung.
  • Der Befehl fossil status liefert einen Überblick über das Repository und neue, geänderte und fehlende Dateien bzw. Verzeichnisse:
    fossil status
    repository:   /home/myuser/.repos/prj.fossil
    local-root:   /home/myuser/prj/
    config-db:    /home/myuser/.config/fossil.db
    checkout:     b66c0a6153fd2ecd4c35d1fa2f55c9b...
    parent:       f3a90d9c355b6865919149221b4b4a6...
    tags:         trunk
    comment:      updated fossil post (user: myuser)
    EDITED     content/post/fossil.md
    EDITED     content/post/vcs.md
    
    Hier fehlen allerdings Dateien, die (noch) nicht mit Fossil verwaltet werden. Dazu ist der Befehl fossil extras gedacht. Sollen nur Änderungen aufgelistet werden, ist fossil changes der zugehörige Befehl.
  • Bei umfangreichen Änderungen kann es schnell passieren, dass Dateien verschoben, neu erzeugt, gelöscht und verändert werden, ohne das dazu die passenden Fossil-Befehle zum Einsatz kommen. Am Ende des Tages meldet ein fossil status viele fehlende Dateien und ein fossil extras viele “neue”. Um jetzt in mühevoller Kleinarbeit die fehlenden Dateien mit fossil rm löscnen und mit fossil add die neuen hinzufügen zu müssen, bietet Fossil den Befehl addremove an. Damit werden alle als fehlend geführten Dateien gelöscht und nicht versionierte hinzugefügt. (fossil status entspricht einer Kombination von fossil info mit fossil changes.)
  • Um sich einen Überblick über die verwalteten Dateien zu verschaffen, genügt ein fossil ls. Etwaige Unterschiede, bspw. nach einer Änderung, zeigt fossil diff an.
  • Wie bei anderen VCS auch müssen sämtliche Änderungen nach Abschluss fixiert werden. Dazu dient der Befehl fossil commit. Über die Option -m "..." lässt sich direkt eine Commit-Nachricht mitgeben; fehlt sie, ruft Fossil automatisch den voreingestellten Editor auf, damit die Nachricht dort eingegeben werden kann. Wichtig: Es darf keine Leerzeichen zwischen -m und der Nachricht stehen.
  • Sollen Änderungen rückgängig gemacht werden, so ist dies mit fossil revert <datei> möglich. fossil undo rollt u.a. ein update, ein merge und ein revert zurück.
  • Eine Arbeitskopie kann auch wieder geschlossen werden: fossil close. Das bietet sich bspw. nach Projektabschluss an, damit überflüssige Verzeichnisse nicht das Dateisystem vermüllen und Platz verbrauchen.
  • Der Befehl fossil serve startet einen Webserver, der mit einem Browser unter der lokalen Adresse http://localhost:8080/ erreichbar ist. Über diesen Weg sind neben den Dateien und der Commit-Zeitlinie auch das Projekt-Wiki sowie das integrierte Ticketsystem erreichbar. Die wichtigste Seite ist dabei http://localhost:8080/help.

Zusammenarbeit im Projekt

  • Ein bestehendes Repository kann über HTTP(S), SSH und natürlich über das Dateisystem geklont werden. Bei der Verwendung von SSH ist ein passwortloser Zugang zum Zielsystem über einen Schlüssel oder ein Zertifikat sinnvoll.
  • Ein Beispiel mit SSH, bei dem der Account jdoe das entfernte Repository prj.fossil klonen möchte:
    fossil clone ssh://jdoe@host.net//path/prj.fossil \
      ~/.repos/prj.fossil
    
  • Wichtig bei der Verwendung von SSH ist der zusätzliche Slash zu Beginn des Pfadanteils: ...net//path/to.... Klonen innerhalb des Dateisystems ist vergleichsweise simpel: fossil clone /path/prj.fossil ~/.repos/prj_clone.fossil.
  • Bevor mit der Arbeit am Projekt begonnen werden kann, ist es ratsam, mit fossil update etwaige Änderungen, die von anderen Projekt-Mitgliedern vorgenommen wurden, in den lokalen Klon zu übernehmen. Nur so bleibt das lokale Repository auf den aktuellen Stand.
  • Fossil nutzt im normalen Betrieb den Modus autosync. Dieser führt dazu, dass vor jedem update das lokale Repository zunächst mit dem Herkunfts-Repository synchronisiert und erst dann die Arbeitskopie aktualisiert wird. Ähnlich verhält es sich mit einem commit: Gespeicherte Änderungen werden automatisch an das Herkunfts-Repository “gepusht”. Damit reduziert sich das bei anderen verteilten VCS das Pull, Update, Change, Commit, Push zu einem Update und Commit.

Branch

  • Ein Fork ist ein “versehentliches” Abspalten oder auch technisch verursacht (bspw. durch fehlenden Netzzugang), das durch ein Merge behoben wird.
  • Eine beabsichtigte Abspaltung heißt in Fossil Branch und erhält üblicherweise einen Namen. Technisch besteht zwischen Fork und Branch kein Unterschied. Um einen Branch markdown auf Basis des Trunks zu erzeugen, kann der `branch’-Befehl verwendet werden:
    fossil branch new markdown trunk --bgcolor yellow
    
    Der Branch wird in der Web-Oberfläche jetzt gelb aufgeführt.
  • Um auf einen anderen Branch zu wechseln, nutzt man fossil update <branch name>.
  • Forks und Branches können mit fossil merge wieder zusammengeführt werden. Für einen Fork sind keine weiteren Angaben nötig, Fossil geht los und repariert Forks, ein Branch-Merge braucht zusätzlich den Branch-Namen als Argument: fossil merge markdown.

Tagging

  • Ein Tag ist ein zusätzlicher Name, der für einen Commit (auch Check-in genannt) vergeben werden kann:
    fossil add tag <tagname>
    
    Tags kommen oft zum Einsatz, um Versionen eines Projekts zu markieren. Die im Repository vorhandenen Tags lassen sich mit fossil tag ls anzeigen.
  • Tags können ebenso wie Branch-Nane als Optionen für Befehle wie fossil update <tag> genutzt werden.

Fazit

  • Fossil ist weitaus umfangreicher als hier beschrieben, bleibt dabei aber einfacher als Git.
  • Mit seiner extrem einfachen Installation und dem grundsoliden Fundament SQLite bietet es für kleine bis mittlere Teams eine gute Alternative zu den derzeit verbreiteten Werkzeugen zur Versionsverwaltung. Schon die Portabilität der Repository-Dateien ist ein Alleinstellungsmerkmal, zusätzlich zum intergrierten Wiki- und Ticket-System.
  • Die Autosync-Funktionalität vermeidet die sonst bei Teams häufiger vorkommenden Versionskonflikte weitgehend und reduziert so die Arbeitslast.

Cheat Sheet

  • Repository erstellen: fossil new ~/.repos/prj.fossil
  • Repository klonen: fossil clone [--no-open] ssh://user@remote//path/prj.fossil
  • Arbeitskopie eöffnen: fossil open ~/.repos/prj.fossil
  • Änderungen verwalten: fossil add|mv/rename|rm <Datei/Verzeichnis>
  • Arbeitskopie aktualisieren: fossil update
  • Änderungen übertragen: fossil commit -m "msg"
  • Tags setzen|anzeigen:fossil tag add <name>|ls