Simple-revision-control
simple-revision-control, kurz src genannt, ist ein einfaches aber trotzdem leistungsfähiges Versionskontrollsystem für private Anwender, die einzelne Dateien (Skripte, Texte, Konfigurationsdateien u.ä.) unter eine Versionskontrolle stellen wollen, dabei aber nicht auf kollektives Bearbeiten angewiesen sind und für die daher die üblichen Systeme wie git, Mercurial, Subversion usw. zu aufwendig sind. Es ist auch möglich ein ganzes Verzeichnis mit z.B. verschiedenen Konfigurationsdateien mit einem Kommando "auf einen Rutsch" zu versionieren. Diese Dateien sollten aber nach Möglichkeit nicht voneinander abhängen, weil sie einzeln, jede für sich versioniert werden. Um Abhängigkeiten wie sie z.B. in C-Programmen mit
foo.c #ifndef MYHEADER_H #define MYHEADER_H
vorkommen, müsste man sich dann selbst kümmern.
Bei src handelt es sich um eine moderne Fassung des alten Versionskontrollsystems RCS, es lehnt sich an dessen Konzept an (Verwaltung der Versionen in einem versteckten Verzeichnis .src, in dem sich die auch bei RCS benutzte Historien-Datei "*,v" befindet) wurde aber neu programmiert und verschlankt. src vergibt, anders als RCS, einfache fortlaufende Revisionsnummern (1, 2, 3, ...), es kann mit "Tags" und "Branches" umgehen.
- Tags: Namen die für bestimmte Revisionen vergeben werden können, um dadurch Arbeitszustände besser merk- und aufrufbar machen zu können. Ein Tag (Name) wie "Version_1.0" oder "alpha" ist leichter zu handhaben, als Revision 123 von Datei foo.sh
- Branches: auf deutsch "Zweige" dienen dazu, um mögliche Varianten der Datei zu verwalten, ohne die anderen Varianten zu stören. Bei einem Shellskript könnte es z.B. sein, dass man eine neue Funktion einfügen möchte, ohne sicher zu sein, ob diese Änderung erfolgreich ist. Da bietet es sich an, sozusagen "zweigleisig" zu fahren, einmal im Hauptzweig (in der Regel und bei src "trunk" genannt) weiter zu entwickeln und in einem zweiten Branch, den man "testing" nennen könnte, diese neue Funktion auszuprobieren.
src ist ein Kommandozeilenwerkzeug, hat einen kleinen, aber völlig ausreichenden Befehlsumfang und ist dadurch schnell erlernbar. Es besitzt eine eingebaute Hilfefunktion, die schon fast einem Tutorial gleichkommt. Wer halbwegs die englische Sprache lesen kann, erhält durch die Eingabe dieser drei Befehle (hintereinander) schon alle Informationen, um sofort starten zu können:
src help intro # erläutert die Basic-Konzepte von "commits", "tags" und "branches" und die Form der üblichen Kommandos src help revisions # erläutert den Gebrauch der Revisions-Nr. src help commands # kurze Hilfe zu allen verfügbaren Kommandos
Trotz seiner Einfachheit gibt es bei src auch die Möglichkeit, ein verwaltetes Projekt mitsamt seiner Entwicklungsgeschichte (History) in ein git-Repository zu importieren. Sollte also einmal das Projekt so anwachsen, dass eine "grosse Versionverwaltung" besser geeignet oder gar notwendig werden, so steht dem nichts im Wege.
Installation[Bearbeiten | Quelltext bearbeiten]
sudo apt install simple-revision-control
wobei als Abhängigkeiten lediglich python3 und rcs automatisch mitinstalliert werden, wenn noch nicht vorhanden.
Verwendung[Bearbeiten | Quelltext bearbeiten]
Der Arbeitsablauf (Workflow) ist relativ einfach. Wie bei Versionsverwaltungen üblich gibt zum einen ein Verzeichnis, in dem die Versionen (Revision) und die Entwicklungsgeschichte der Datei(en) gespeichert werden, das sogenannte "Repository", bei src ein verstecktes Verzeichnis mit dem Namen .src und das Arbeitsverzeichnis (Arbeitskopie oder "working copy"), in dem die Datei bearbeitet wird.
Bei src ist das Repository .src ein Unterverzeichnis des Arbeitsverzeichnisses. Um dies zu verdeutlichen nehmen wir an, dass ein Shellskript namens foo.sh entwickelt wird, dass sich im Verzeichnis ~/work befindet und der User paul heisst. Nach dem ersten "commit", so nennt sich der Vorgang, wenn eine Datei unter Versionsverwaltung gestellt wird, ergibt sich folgende Verzeichnisstruktur:
/home/paul/work/foo.sh /home/paul/work/foo.sh/.src/foo.sh,v
Dies nur zur Kenntnisnahme, da man sich nicht um das Erstellen des Verzeichnisses .src kümmern muss, dies geschieht durch src selbst. Auch in diesem Unterverzeichnis, dem Repository .src braucht oder genauer, darf man nichts von Hand verändern.
Der "normale" Ablauf ist folgender:
- anlegen der ersten Fassung des Skriptes foo.sh mit dem Lieblingseditor
- ist man zufrieden (das Skript funktioniert einigermassen) oder hält sonst irgendwie den Zeitpunkt für gekommen, kann das Skript unter Versionsverwaltung gestellt ("commited") werden:
src commit -m "Kommentar" foo.sh
wenn noch nicht vorhanden legt src dabei das Repository .src als Unterverzeichnis und damit die Revision 1 des Skriptes foo.sh an. Dies geschieht nach bewährter Linux-Art geräuschlos, dass heisst nur im Fehlerfall erfolgen Meldungen.
Der oben erwähnte Ablauf kann nun immer wieder im Kreislauf angewendet werden, editieren der Arbeitsdatei und zu einem gewählten Zeitpunkt Übergabe ("commit") und damit Sicherung des jeweiligen Zustandes der Datei im Repository. Dabei wird die Revisionsnummer der Arbeitsdatei kontinuierlich um 1 erhöht.
Nun erwartet man zu Recht noch etwas mehr Infos und Möglichkeiten, als nur Versionen von Dateien im Repo zu sichern. Auch das ist in src vorhanden. Mit
src ls
kann man anzeigen lassen, welche Dateien im Verzeichnis sich unter Versionskontrolle befinden. Könnte man denken, dass weiss man doch auch so, da man sie selbst eingerichtet hat. Ja, mag sein, aber wenn man sein Projekt schon mal ein halbes Jahr hat liegen lassen, ist man durchaus manchmal dankbar, nochmals daran erinnert zu werden.
Ähnliches gilt für den Status. Hat man die Datei nun schon "commited" oder "eingecheckt", wie man auch sagt, oder nicht? Kein Problem, das Kommando status gibt Auskunft
src status DATEINAME
und informiert über das Zeichen am Anfang (Status Code) den Status der Datei mit:
- = Unverändert. Die Datei entspricht der letzten gespeicherten Revision
- M Geändert. Die Datei wurde seit der letzten gespeicherten Revision geändert
- ? Nicht nachverfolgt. SRC führt keine Historie für diese Datei (steht nicht unter Versionskontrolle)
- I Ignoriert. Diese Datei entspricht den Mustern in '.srcignore'
- ! Fehlt. Es gibt eine Historie für diese Datei, aber der Workfile fehlt. Da ist wohl etwas schiefgelaufen
- A Die Datei wurde im SRC registriert, hat aber keine Commits
- L Die Datei ist gesperrt/schreibbar. Dies bezieht sich auf die eventuelle Sperrung durch RCS
Der Status A oder L tritt eigentlich nur auf, wenn die betreffende Datei mit der alten Versionskontrolle RCS bearbeitet wurde.
Der Statuscode zeigt M (geändert an). Was hat sich nun eigentlich seit dem letzten einchecken (commit) geändert? Das wird mit diff angezeigt
src diff DATEINAME
Dies ergibt eine mehr oder weniger lange und bunte Anzeige, hier nur auszugsweise (und rechts etwas abgeschnitten) für diese Textdatei (src.txt) angezeigt:
Zu den Farben, die hoffentlich in allen Terminals unverändert sind:
- weiss: unveränderter Text, der nur den Kontext verdeutlicht, um eventuell besser suchen zu können
- rot: Zeile wurde gelöscht, bzw. verändert (durch die nachfolgende grüne Zeile ersetzt)
- grün: Zeile hat die vorhergehende "rote" Zeile ersetzt, bzw. wenn keine dazugehörende rote Zeile existiert (wie bei der Zeile "status code"), wurde diese neu eingefügt.
Was unabhängig von den Farben funktioniert (es gibt ja auch Terminals die keine Farbe können) sind die vorangestellten Plus- (+) oder Minuszeichen (-). Für Pluszeichen gilt das bei "grün" gesagte, für Minuszeichen das bei "rot" gesagte.
Dann gibt es noch diese Art "Überschrift":
--- src.txt (r3) +++ src.txt (workfile)
Dies sagt uns, dass hier die Arbeitsdatei src.txt mit der Revision 3 (r3) der eingecheckten Datei src.txt im Repo verglichen wird (das hier der Dateiname src.txt ähnlich dem Kommando src ist, hat nur was mit dem versionierten Wikitext zu tun).
Möchte man sich einen Überblick über die bisherige Entwicklung verschaffen, so geschieht dies mit dem Kommando log:
src log DATEINAME
und erhält dabei im wesentlichen eine Auflistung der Kommentare, die beim einchecken mit commit nach der Option -m mitggegeben wurden:
src commit -m "Kommentar" DATEINAME
Man sollte also aussagekräftige Kommentare eingeben. Bei meiner Beispielsdatei src.txt sieht die Ausgabe von
src log src.txt
so aus:
= src.txt ======================================================================================================================================= 4 | 2021-08-15T21:00:51+02Z | trunk Übersicht der wichtigsten src-Kommandos fertig ------------------------------------------------------------------------------------------------------------------------------------------------- 3 | 2021-08-15T16:25:19+02Z | trunk dt. Übersetzung fertig ------------------------------------------------------------------------------------------------------------------------------------------------- 2 | 2021-08-15T16:07:43+02Z | trunk engl. Statusmeldungen ergänzt ------------------------------------------------------------------------------------------------------------------------------------------------- 1 | 2021-08-15T16:05:59+02Z | trunk 1. Fassung -------------------------------------------------------------------------------------------------------------------------------------------------
Zuerst als Titel der Name der Datei, dann für jede Revision in zwei Zeilen zuerst die Revisionsnummer, das Datum des eincheckens und um welchen Zweig (Branch) es sich handelt, wenn nicht ausdrücklich in einen anderen Zweig eingecheckt handelt es sich dabei um "trunk". In der zweiten Zeile steht dann der schon erwähnte Kommentar.
Nun noch ein wichtiger Punkt für eine Versionsverwaltung, also auch für src. Die tolle Neuerung, die man in Revision 5 eingebaut hat, erweist sich als ein Schuss in den Ofen, das frisch gebackene Skript produziert zu viele Fehler oder macht was anderes, als man möchte. Kein Problem, in Revision 4 (oder 3) war die Welt noch in Ordnung, also zurück zu Revision 4
src checkout 4 src.txt
und schon hat man in seiner Arbeitskopie wieder die Revision 4 vom vorigen Freitag. Und das manchmal nützliche ist, auch die Revision 5 ist noch da, nur einen Tastendruck entfernt im Repo, zumindest wenn sie als solche eingecheckt wurde.
Kommandos und Optionen von src[Bearbeiten | Quelltext bearbeiten]
Revisionen, Tags und Branch[Bearbeiten | Quelltext bearbeiten]
Da bei der nachfolgenden Befehlsübersicht immer wieder von "Revision" geredet wird, hier eine kleine Erläuterung dazu. Eine "Revision" ist im Prinzip nichts anderes als eine einfache numerische Versionsbeichnung, Version 1, Version 2, 3 usw. oder ein Tag-Name, der eine ausgewählte Revision bezeichnet, oder ein Zweigname (Branch), der die aktuellste Revision (tip) seines Zweigs bezeichnet, oder "@", der die aktuell abgerufene Revision bezeichnet.
Auch Tag-Namen (tags) kennt man als Bezeichnungen bei Linux, so trägt MX Linux 21 den Namen (oder tag) „Wildflower“. Ähnliches gilt für die Zweignamen (Branch) bei src. Dabei handelt es sich einfach um Namen, die man verschiedenen Entwicklungsversionen (oder besser Entwicklungszweigen) geben kann, um diese zu unterscheiden. So könnte man z.B. an einem Skript arbeiten, dass seine benötigten Daten in einer XML-Datei speichert und gleichzeitig an einem anderen Skript, dass zwar die gleiche Aufgabe löst, aber zur Datenspeicherung nicht XML sondern MariaDB benutzt. Dann könnte man den einen Entwicklungszweig (Branch) "Xaver" und den anderen "Maria" nennen. Bei den Namen hat man relativ freie Hand, nur der zuerst angelegte Zweig trägt den Namen "trunk" (auf deutsch etwa soviel wie "Stamm" oder "Baumstamm"). Eine Tradition der wohl die meisten Versionsverwaltungssysteme folgen.
Ein Revisionsbereich ist eine einzelne Revision oder ein Revisionspaar 'M-N' (alle Revisionen von M bis N) oder 'M..N' (alle Revisionen, die Zweigvorgänger von N und Zweignachfolger von M sind). Wenn N kleiner als M ist, wird der Bereich in umgekehrter Reihenfolge bearbeitet. Wenn SRC sich beschwert, dass die Revisionsangabe wie ein nicht existierender Dateiname aussieht, kann man ein '@' voranstellen (dies ist immer erlaubt).
Kommandos und ihre Optionen[Bearbeiten | Quelltext bearbeiten]
Da die Optionen und Parameter von src vielfältig kombinierbar sind, können nicht alle möglichen Kombinationen angeführt werden. Wichtig ist aber, dass Parameter in eckigen Klammern optional sind, dass heisst, sie können auch weggelassen werden. Bei Benutzung geschieht das natürlich ohne die eckigen Klammern. Das gleichzeitige Einchecken (commit) der Dateien foo, bar und foobar würde also so aussehen:
src ci -m "foo, bar und foobar unter src-Kontrolle" foo bar foobar
Wird kein Dateiname angegeben, bearbeitet src nacheinander jede einzelne Datei im aktuellen Verzeichnis, es sei denn, sie wird durch einen Eintrag in der Datei .srcignore von der Versionsbearbeitung ausgeschlossen.
Die Befehle help, commit, status, delete/rename Befehle für Tags und Branches, ls, move, copy, fast-import, release und version akzeptieren überhaupt keine Revisionsangabe und brechen ab, wenn eine angegeben wird.
Einige Befehle (amend, checkout, cat, Tag- und Branch-Erstellung) nehmen optional nur eine einzelne Revisionsangabe an, während die Befehle log, list, diff und fast-export einen Bereich oder eine einzelne Revisionsangabe akzeptieren .
Sofern bei den einzelnen Befehlen nicht anders angegeben, ist die Standardrevision die aktuellste Revision (tip) des aktuellen Zweigs.
- Anzeige von allgemeiner Hilfe (ohne Angabe von Kommando) bzw. Hilfe zum KOMMANDO bzw. zum entsprechenden Topic (intro, revisions und commands). Die allgemeine Hilfe src help gibt diesen Überblick
- intro -- Basic concepts: commits, tags, branches. The form of commands.
- revisions -- How to specify ranges of commits to operate on.
- commands -- a summary of the commands.
- commit -- the commit command: how to commit changes to a file.
- amend -- the amend command: editing stored change comments.
- checkout -- the checkout command: retrieving historical versions of files.
- cat -- the cat command: dumping revisions to standard output.
- status -- the status command: more details and unusual status codes.
- log -- the log command: dump commit log information to standard output.
- list -- the list command: dump commit summaries to standard output.
- diff -- the diff command: dump revision differences to standard output.
- fast-export -- the fast-export command: export history to other systems.
- fast-import -- the fast-import command: import history from other systems.
- ignores -- .srcignore files and their uses.
src help [KOMMANDO]
- Einchecken der angebene(n) Datei(en) mit dem Kommentar in die Versionsverwaltung. Ohne Angabe von Datei(en) wird das gesamte Verzeichnis eingecheckt. Statt commit kann immer auch ci benutzt werden.
src commit -m KOMMENTAR DATEI1 [DATEI2 ...]
- Einchecken der angebene(n) Datei(en) in die Versionsverwaltung. Der Kommentar wird aus KOMMENTARDATEI eingelesen
src commit -f KOMMENTARDATEI DATEI1 [DATEI2 ...]
- Ändern eines gespeicherten Kommentars der Revision von DATEI. Ist keine Revisionsnummer angegeben, wird der Kommentar der aktuellsten Revision geändert. Statt dem KOMMENTAR kann auch der Flag -f mit der gleichen Syntax wie bei commit benutzt werden.
src amend -m KOMMENTAR [REVISION] DATEI
- Ersetzen der aktuellen Arbeitsdatei DATEI duch die Fassung der angegebenen Revision aus der Versionsverwaltung. Ohne REVISION wird die letzte benutzt. Das Kürzel co kann als Synonym für checkout verwendet werden.
src checkout [REVISION] DATEI
- Ausgabe (Anzeige) der REVISION von DATEI auf der Standardausgabe. Ohne REVISION wird die letzte Revision angezeigt
src cat [REVISION] DATEI
- Status der Datei(en) ausgeben. Statt status kann auch das Kürzel st benutzt werden. Für die ausgegebenen Statusmeldungen siehe die schon oben beim Punkt "Verwendung" angegebenen Erklärung der Abkürzungen. Ohne Angabe einer Datei wird nur der Status von versionierten (eingecheckten) Datei(en) angezeigt. Es ist auch die Angabe von Wildcards wie * möglich.
src status [DATEI1] [DATEI2 ...]
- Tags auflisten (list), erzeugen (create) oder löschen (delete). Fehlt REVISION werden Tags der letzten Revision angezeigt. Mögliche Abkürzungen:
- -l = list
- -c = create
- -d = delete
src tag list [TAGNAME] [REVISION] [DATEI...] src tag create [TAGNAME] [REVISION] [DATEI...] src tag delete [TAGNAME] [REVISION] [DATEI...]
- Zweige (Branches) auflisten (list), erzeugen (create) oder löschen (delete). Wenn BRANCHNAME fehlt, wird als Default der Branch trunk genommen. Mögliche Abkürzungen:
- -l = list
- -c = create
- -d = delete
src branch list [BRANCHNAME] [DATEI...] src branch create [BRANCHNAME] [DATEI...] src branch delete [BRANCHNAME] [DATEI...]
- Tag oder Branch umbenennen. rn ist Synonym für rename
src rename tag ALTER-NAME NEUER-NAME DATEI src rename branch ALTER-NAME NEUER-NAME DATEI
- Informationen über die eingecheckten (commits) Dateien ausgeben. Die mit "*" gekennzeichnete Zeile ist der Zustand, in den die Datei beim Auschecken (checkout) ohne Angabe einer Revision zurückkehren würde. Mit der möglichen Angabe der Option -l n (bzw. -n) kann angegeben werden, dass nur n Infozeilen ausgegeben werden sollen. Als Revisionbereich kann eine einzelne Revisionsnummer (z.B. 2) oder ein Bereich (z.B. 3-5) angeben werden. Im letzteren Fall werden nur Infos über die Revisionen 3 bis 5 ausgegeben.
src list [-l n] [REVISIONSBEREICH] [DATEI...] src list [-n] [REVISIONSBEREICH] [DATEI...]
- Anzeige von Informationen über die angegebenen Commits. Mit der Angabe von -<n> oder -l <n>, (<n> ist eine Zahl) werden nur die letzten n aktuellsten Revisionen angezeigt. Mit den Optionen --patch, -p oder -u wird zusätzlich ein Unified Format Diff Listing für jede Revision gegen ihre unmittelbare Vorgängerrevision angezeigt; -c gibt stattdessen ein Kontextdiff aus. Beim Erzeugen eines Diffs ignoriert -b Änderungen in Leerzeichen, und -w ignoriert alle Leerzeichen. Für die Angabe eines Revisionsbereiches gilt das gleiche wie bei src list
src log [REVISIONSBEREICH] [DATEI...] src log [-l n] [REVISIONSBEREICH] [DATEI...] src log [-l n] [-p] [REVISIONSBEREICH] [DATEI...] src log [-u] [-w]] [REVISIONSBEREICH] [DATEI...] src log [-l n] [-c] [-b] [REVISIONSBEREICH] [DATEI...]
- Anzeige der Unterschiede zwischen der Arbeitskopie und der letzten Revision (wenn kein Revisionsbereich angegeben wird). Besteht der Revisionsbereich lediglich aus einer einzelnen Revisionsnummer, dann wird die Arbeitskopie mit dieser Revision verglichen. Bei der Angabe eines Revisionsbereiches (z.B. 2-4) wird die erste angegebene Revision mit der letzten Revision verglichen. Für das Beispiel 2-4 wird Revision 2 mit Revision 4 verglichen. Das Ausgabeformat entspricht dem vom Bashkommando diff (s. man diff). Wie bei src log können nach diff die Optionen -c (Kontextdiff), -b (ignoriert Leerzeichen) und -w (ignoriert alle Leerzeichen) angegeben werden.
src diff [REVISIONSBEREICH] [DATEI...] src diff -c [REVISIONSBEREICH] [DATEI...] src diff -c -w [REVISIONSBEREICH] [DATEI...]
- Auflisten aller Dateien, die sich unter Versionskontrolle befinden
src ls
- Umbenennen einer Arbeitskopie ohne die Versionsgeschichte zu verlieren. Statt move kann auch mv benutzt werden.
src move ALTER-NAME NEUER-NAME
- Kopieren einer Arbeitskopie ohne die Versionsgeschichte zu verlieren. Danach existieren zwei gleiche Dateien mit der gleichen Versionsgeschichte. Beide können anschliessend unterschiedlich bearbeitet werden (als eine Art Fork). Statt copy kann auch cp benutzt werden. Vorhandene Dateien können so aber weder bei src move noch bei src copy überschrieben werden, d.h. eine Datei NEUER-NAME darf noch nicht existieren.
src copy ALTER-NAME NEUER-NAME
- Export eines oder mehrere Projekte als Git fast-import Stream.
src fast-export [REVISIONSBEREICH] [DATEI...]
- Parsen eines git-fast-import-Streams von der Standardeingabe. Die Änderungen für jede einzelne Datei werden zu separaten SRC-Historien. Markierungs-, Committer- und Autorendaten sowie Markierungs-Querverweise auf übergeordnete Commits werden in RFC-822-ähnlichen Headern auf Protokollkommentaren beibehalten, es sei denn, die Option -p (plain) wird angegeben; in diesem Fall werden diese Metadaten verworfen.
src fast-import [-p] [DATEI...]
- Anzeige der Version von src, Python, RCS und der benutzten Plattform (Linux, was sonst)
src version
Dateien ignorieren[Bearbeiten | Quelltext bearbeiten]
Möchte man Dateien im jeweiligen Verzeichnis für die Versionsverwaltung ignorieren, so kann man eine Datei .srcignore anlegen, in der die Namen der zu ignorierenden Dateien eingetragen werden. Dabei sind auch die üblichen Linux-Muster wie *.bak möglich. Zu den Mustern hier noch eine kurze Übersicht:
Muster | Bedeutung |
---|---|
* | entspricht einer beliebigen Zeichenfolge |
? | passt auf jedes einzelne Zeichen |
[] | definiert eine Zeichenklasse, es entspricht jedem Zeichen innerhalb der eckigen Klammen. [0123456789] z.B. trifft auf jede Ziffer zu |
[!] | das Gegenteil der vorherigen Zeile. Passt auf alle Zeichen, die nicht in den Klammern stehen. [!0123456789] trifft auf alle Zeichen zu, die keine Ziffern sind |
Jeder zu ignorierende Dateiname, bzw. jedes Muster kommt auf eine eigene Zeile:
*~ *.bak x* readme
Die in .srcignore eingetragenen Dateien/Muster werden bei src status nicht angezeigt, es sei denn, es wird das -a Flag benutzt
src status -a
oder sie werden explizit mit angegeben.
In beiden Fällen erscheinen die betreffenden Dateien dann in der Ausgabe mit vorangestellten Kennzeichen I (=ignoriert)
src status foo.bak I foo.bak
Sie werden auch ignoriert, wenn Befehle, die eine Liste der registrierten Dateien erwarten, sie sehen (was z.B. passiert, wenn man Shell-Wildcards in SRC-Befehlen verwendet).
Das Repo-Verzeichnis (normalerweise .src) wird immer - also auch ohne Eintrag in .srcignore - ignoriert, die Datei .srcignore jedoch nicht.