[linux-l] Versionskontrollen (war: Warum gibt es keine einheitliche Dokumentation?)

Volker Grabsch vog at notjusthosting.com
Sa Jan 20 17:19:13 CET 2007


On Thu, Jan 18, 2007 at 12:02:33AM +0100, Steffen Dettmer wrote:
> [mercurial + GIT]
> > Arch und Monotone sind also IMHO keinen Blick wert, aber das ist nur
> > mein oberflächlicher Eindruck. Ich kann mich da auch übel täuschen.
> 
> Wenn GIT nicht changeset basiert ist, bleibt wohl erstmal mercurial
> heiss :)

GIT *ist* changeset-basiert. Also nochmal:

Versions-Basiert    |  Changeset-Basiert
------------------------------------------
RCS                 |  Darcs
CVS                 |  GIT
Subversion          |  Mercurial
                    |  Arch
                    |  Monotone

> > > > Ditto übrigens auch für Tags. Mercurial hat eine .hgtags-Datei. Sehr
> > > > clever gelöst, finde ich. In CVS natürlich nicht machbar, weil jede
> > > > Datei ihre eigene Rev.-Nummer hat.
> > > 
> > > Versteh nicht, was eine .hgtags-Datei ist. Bei CVS sind Tags Symbole
> > > (strings), werden z.B. bei sticky-tags in CVS/Entries und CVS/weissnicht
> > > verwendet. Na egal, eher Implementierungsdetails.
> > 
> > Jedes Changeset, und damit jede Version des Codes, 
> 
> Hum... Changeset == Version? Komisch, dachte eine Version wird durch
> Anwendung eines Changesets zu einer anderen.

Jedes Changeset hat Eltern-Changesets. Meist nur eines. Manchmal auch
mehrere (bei Merges). Jedes Changeset steht also für einen großen Baum
von Eltern-Changesets. Wendet man all diese auf das "leere Repository"
an, erhält man eine bestimmte Version.

Anders ausgedrückt: In jedem Repository liegen die Changesets in einer
bestimmten Reihenfolge vor. Zu jedem Changeset gibt es also einen
Zustand "danach", also nach dem Anwenden des Changesets. So kann
man jedem Changeset eine "Version" zuordnen.

Versionen gibt es also auch in Changeset-basierten Versionskontrollen.
Nur ist dieser Begriff dort schwieriger zu definieren ... seine
intuitive Bedeutung ist aber klar: Jede Form, die der Code während
seiner Entwicklungszeit angenommen hat.

> Dabei kann ein Changeset
> aus beliebig vielen beliebig viele erzeugen. Dachte ich.

Grundsätzlich schon. Aber in einem konkreten Repository haben die
Changesets dann eine wohldefinierte Baumstruktur, und das ist auch
gut so.

Darcs forciert den Ansatz der unabhängigen Changesets ziemlich stark.
Das ist interessant, aber der Mehrwert ist eher gering, weil man
auch bei problemlosen (konfliktfreien) Merges stets Gefahr läuft, dass
sie gemeinsam einen Fehler darstellen.

Mercurial verfolgt daher den Weg, jeden Merge explizit im Baum
darzustellen, und sei er noch so trivial.

Unabhängig davon, welchen dieser theoretischen Ansätze man favorisiert:
Das ist es nicht, was Changeset-basierte Versionskontrollen ausmacht!

Der *eigentliche*, springende Punkt ist der, dass die Änderungen eine
Baumstruktur darstellen. Entartet diese Baumstruktur zu einer langen
linearen Kette, hat man effektiv wieder ein CVS/Subversion.

Die Herausforderung, der alle Changeset-basierten Versionskontrollen
gegenüberstehen, ist folgende: Sie müssen Teilbäume mergen. An
irgendeiner Stelle driftet der Baum eventuell mehrmals auseinander,
und zwei der Blätter sollen zusammengeführt werden.

Das ist glaubich auch der tiefere Grund, warum sich CVS und auch
Subversion so schwer damit tun, "merges" zu automatisieren: Es ist
ein konzeptuelles Problem. Wenn Subversion in 100 Jahren endlich das
angekündigte "Merge"-Feature haben wird, wird es "unter der Haube"
zu einer Changeset-basierten Versionskontrolle mutiert sein. Und da
es von vornherein nicht darauf ausgelegt war, wird es ein ziemlich
schlechtes sein.

Also lieber gleich GIT/Mercurial/Darcs nehmen. ;-)


> > Ist aber wirklich nebensächlich. Du wirst die .hgtags nicht per Hand
> > bearbeiten, das macht "hg tag ..." für dich. Du musst nur wissen, dass
> > du die Datei nicht löschen darfst, 
> 
> Nee? Warum, kann doch einfach neu auschecken?

Ja, das schon. Aber während die Datei weg ist, kannst du keinen Checkout
z.B. von "release-1.0" machen.  :-)

Außerdem wirst du die .hgtags nicht direkt bearbeiten oder direkt
committen. Das passiert bei "hg tag" unter der Haube, automatisch.

Es ist halt nur interessant, dass auf diese Weise die Interna des
Features sichtbar werden, und dass sie super mit dem Rest
zusammenspielen, ohne eine gesonderte extra Implementierung zu
erhalten.

So kannst du z.B. nicht nur sehen, *welche* Version als "release-1.0"
getaggt wurde, sondern auch *wann* und *von wem*, weil das wie jede
Änderung im "hg log" nachlesbar ist. :-)


> > > > Vielleicht hätte ich von Anfang an Mercurial empfehlen sollen.
> > > > Aber die meisten, die ich bisher kennenlernte, wollten lieber
> > > > erstmal Subversion haben. Und gröartige Keywords, Ignore-Datein
> > > > etc. hatten sie eh nicht.
> > > 
> > > Ja, hab auch den Eindruck, SVN ist gut wenn man keine bes.
> > > Anforderungen hat.
> > 
> > Nicht ganz. Guter Windows-Client, sowie Zugriff über nicht-SSH, das
> > sind schon *sehr* spezielle Anforderungen. 
> 
> Stimmt, und wenn man ne GUI mit grün-blauem default-Hintergrund braucht,
> hat man noch eine *sehr* spezielle Anforderung.

Kennst du überhaupt Tortoise? Das integriert sich in den Windows-
Explorer, und das ist gerade für Windows-Nutzer ne *sehr* feine Sache.

> > Zudem hat die Idee einer *zentralen* Versionsnummer auch eine gewisse
> > Berechtigung bei einfachen Projekten. Ich habe durchaus Projekte
> > gesehen, bei denen Subversion schon allein wegen des prächtigen
> > Windows-Clients "Tortoise" einfach mal erste Wahl war.
> 
> Jo, genau, prima, den Eindruck hab ich auch. Man wählt die Tools nach
> der Anzahl der gleichzeitig in der GUI darstellbaren Farben aus. IPSec
> oder PPTP? PPTP mit PAP, da gibt's mehr Themes für die GUI. lol

Das trifft nicht auf Tortoise zu, der hat höchstens eigene
Dialogfenster, und die folgen der systemweiten Farbgebung.

> na, genug gelästert :)

Das ist in etwa genauso absurd, als würdest du über meine schulterlangen
Haare lästern, obwohl ich nen Kurzhaarschnitt habe. Oder als ob ein
Kabarettist über die Mehrwersteuer-Senkung lästert. (obwohl wir ne
Erhöhung haben).

Thema verfehlt. Setzen, sechs. Erst informieren, dann lästern.

> > Dennoch: Ein anfängerfreundlicher Client, gut ins Dateisystem oder
> > ähnlichem integrierst, das ist schon ne Anforderung, ne ziemlich harte
> > sogar. Da rockt Subversion AFAIK gegenüber allen anderen.
> > (CVS/Darcs/GIT/Mercurial/...)
> 
> Ich find es i.d.R. nicht so gut, wenn man so tut, als ob komplexe
> Probleme wie Versionsmanagement einfach wären. Als ob es einen
> Unterschied macht, 10 Kommandos zu lernen.

Ja, das ist ein Unterschied. Für ständig benutzte Befehle (update,
commit) mag das Befehl-Lernen sinnvoll sein.

Die seltener benutzten Befehle hingegen schlägt man eh ständig nach.
Diese aus einem Menü auswählen zu dürfen ist definitiv benutzer-
freundlicher.

Ein "man hg", Befehl raussuchen, "hg <befehl> ..." kann man natürlich
auch als Menü-Auswahl interpretieren. ;-)

Nee, höchsten ein "hg <tab><tab>" ... und dann die Kommandos per
Autovervollständigung, inkl. Beschreibung. *Das* ist benutzer-
freundlich. BTW, ich müsste meine Shell mal entsprechend konfigurieren.

> Wenn man dank GUI denkt, es wäre einfach, benutzt
> man es, als wäre es einfach. Da kommt dann oft was "einfaches" bei raus
> (vorsichtig ausgedrückt).

Die GUI darf die Konzepte nicht verstecken.

Schlechte GUIs mit guten Kommandozeilen-Tools zu vergleichen ist IMHO
nicht fair. Zumal eine schlechte GUI immer noch besser als ein
schlechtes Kommandozeilen-Interface ist.

Vergleicht man hingegen *gute* GUIs (sind selten, ich weiß!) mit *guten*
Kommandozeilen-Interfaces, dann läuft es letztlich auf rein subjektive
Vorzüge hinaus. Dann ist es letztlich egal, was von beiden man nimmt.

> Aber wenn Du eine komplexe Struktur hast, die von z.B. 10 Repos stammt,
> musst Du bei update ja je ein Kommando in 10 Verzeichnissen machen.
> Macht CVS automatisch. SVN weiss ich nicht, vermute mal, das müsste
> genauso gehen,

Ja, svn macht das genauso.

Mercurial nicht, aber ein "hg up *" oder ähnliches löst das Problem
genauso.

> > Ich wüsste nicht, wieso ich in solch einem Szenario modulübergreifend
> > mergen wollte.
> 
> Na, Du hast einen release branch, machst einen Fix (der Änderungen in
> drei Repos braucht) und willst das halt in den trunk mergen.

Will man das wirklich? Alles auf einmal?

Hat man das Projekt nicht ursprünglich auf mehrere Repositories
aufgeteilt, um sie *unabhängig* voneinander zu behandeln?

> > > > Egal, ob ganzes Repository oder Unterverzeichnis: in Subversion
> > > > ist das Auschecken dafür ein und der selbe Befehl. 
> > > 
> > > Ja klar, wie auch in CVS muss ich natürlich einmal pro Repo ein befehl
> > > verwenden, klar, das SVN muss ja die URL gesagt bekommen etc.
> > > 
> > > bei CVS geht jedenfalls ganz einfach:
> > > 
> > > $ cvs -d $repo1 module1
> > > $ cvs -d $repo2 module2
> > > 
> > > usw., danach geht ein cvs up, welches automatisch in beide Verzeichnisse
> > > wechselt.
> > 
> > Klappt mit "svn up" genauso.
> 
> Nö, tut es nicht:
> 
> steffen at hostname:/tmp/steffen_exp/projectroot/ # svn up
> Skipped '.'

Weil dein "projectroot" kein Checkout ist, oder?
Ich dachte, es gibt immer ein "Hauptprojekt", als das "eigentliche"
Projekt, und der Rest sind Bibliotheken/Module, die es verwendet.
In meinen Augen würde es sonst keine klare Struktur mehr haben.

Wo ist der Vorteil, das anders zu handhaben?

> > > Atomares einchecken über mehrere repos kann ich mir jedenfalls nicht
> > > vorstellen. Wie auch immer. Hab ich nie so gebraucht.
> > 
> > Wozu auch? Ich würde die nacheinander committen, schon allein deshalb,
> > weil das Modul wahrscheinlich ne andere Log-Message als der Rest haben
> > würde.
> 
> Ja, auch ein Problem mit den Messages, klar, aber "nacheinander
> committen" ist gerade nicht atomar! 
> 
> Bei uns wird bestimmt irgendwo auf der Welt gerade jemand ein update
> machen, einen nicht-kompilierenden Zwischenstand auschecken, nach 15-30
> Minuten rumsuchen eine Mail schicken und gleich noch eine ("sorry, just
> saw that it is fixed already") 
> 
> :-)

Merkwürdige Schnittstellen, wenn ein Bugfix mehrere Module beeinflusst,
und deren Änderungen nicht unabhängig voneinander sind ...

Wenn die Einzelteile so stark miteinander verwoben sind, wieso teilst
du sie dann auf unterschiedliche Repositories auf?

> > Willst du trotzdem aus irgendeinem Grund mehrere Branches in einem
> > Repository, geht das mit Mercurial auch. Es warnt halt nur, weil's
> > i.d.R. nicht das ist, was man will.
> 
> in einem Repository oder in einer Sandbox? Oder sind solche CVS/SVN
> Begriffe hier einfach nur falsch?
> 
> Bei CVS hab ich eine Sandbox, die i.d.R. aus einem Branch stammt (die
> alle im Repository liegen). Ich kann natürlich Dateiweise mischen (nach
> SCM-Terminologie "konfigurieren").

Was in CVS als Sandbox-Muster bezeichnet wird, ist genau das, was in
Darcs/Mercurial/GIT/... bereits ein Repository *ist*. Insbesondere kann
sich dort jeder selbst beliebig viele "Sandboxes" anlegen. Weil das so
einfach ist, ermöglicht es eine Weiter-Entwicklung des Sandbox-Musters:
Micro-Branches. Häufige, private Branches, die ständiges Merging erfahren,
dafür sind Mercurial/Darcs/GIT/... super geeignet, und das ist eine *sehr*
angenehme Art der Entwicklung.

Aus der Mercurial-Philosophie: Jedes Arbeitsverzeichnis ist ein Repository
und damit ein (potentieller) Branch.

Kopiere dein gesamtes Arbeitsverzeichnis woanders hin (auch: auf einen
anderen Rechner), arbeite in beiden Verzeichnissen unabhängig voneinander.
Jederzeit kannst du die Änderungen des einen in das andere mergen.
Eventuell musst du Konflikte lösen, aber mehr nicht. Die Übersicht hat
Mercurial.

Du kannst dann wirklich frei in Begriffen denken wie: "Branch sowieso
wurde in Trunk gemerged." Kein Herumfummeln mit internen Versionsnummern
und ähnlichem.

Schau doch einfach selbst mal in die GIT- und Mercurial-Einleitungen. Da
gibt's auch spezielle Hinweise für CVS-Umsteiger, also für dich. Wenn du
dir die Zeit nimmst, meine Mails zu lesen, kannst du dort auch ruhig mal
surfen. Dort ist es wahrscheinlich auch viel besser erklärt, als ich es
hier könnte.

> > > Na, modul1 liegt auf repo1 (vielleicht ist das 5 Jahre alt und 4 nicht
> > > mehr benutzt worden), modul2 ist von jemand anders, anderes Land, repo2
> > > usw. Dann gibts Server mit open source repo3 und NDC sourcen repo4 nur
> > > intern erreichbar. Oder sowas.
> > 
> > Und an welcher Stelle musst du da zwischen verschiedenen Repositories
> > mergen?
> 
> Praktisches Nummer #1 Beispiel ist wohl, wenn eine "unten" (Basis, lib)
> Funktionen einen neuen Parameter braucht. Muss in lib (modul1) und
> natürlich vom Aufrufer (modul2) beachtet werden. nicht-atomares
> einchecken kompiliert nicht unbedingt (kann ich natürlich machen, wenn
> ich lib / modul1 kompatibel halte, aber wenn ich gerade Fehler erzwingen
> möchte, wenn der Parameter fehlt, geht das halt nicht).

Welchen Sinn haben dann die unterschiedlichen Repositories? Dein
Szenario funktioniert nur, wenn du davon ausgehst, dass kein weiteres
Projekt dein "modul1" benutzt. Sonst würde dir auch eine atomische
Änderung von modul1 und modul2 nichts bringen, weil trotzdem app5 auf
server132 kaputt geht.

Will sagen, atomische Commits über mehrere Repositories lösen ein
Symptom, aber nicht das Problem.

> > > > > Aber wenn man keine Anforderungen hat, ist SVN sicher ok.
> > > > 
> > > > SVN erfüllt auch Anforderungen, die CVS nicht hat.
> > > 
> > > Ja, ich weiss. Es kann http und basiert auf XML/SOAP.
> > 
> > Subversion kann HTTP(S) + WebDAV.
> 
> Ist das gleiche, bloss ich hab die besseren Hype-Wörter benutzt, oder?

Nein, WebDAV und SOAP sind unterschiedliche Protokolle.

XML/SOAP ist in der Tat doppelt gemoppelt, das solltest du
einfach SOAP nennen. Und wenn, dann sollte es eher HTTP(S) + SOAP
heißen. :-)

Subversion basiert *nicht* auf SOAP. Es gibt nur:

a) lokalen Zugriff

b) eigenes Netzwerk-Protokoll
    ("svnserver", durch SSH tunnelbar)

c) ein auf HTTP(S)+WebDAV basiertes Protokoll,
    strebt DeltaV-Konformität an.

> Obwohl "WebDAV mit Web 2.0 Technologie" auch cool klingt. So richtig
> nach "mach einen Bogen um mich".

Subversion nutzt keine der sog. "Web 2.0" Architekturen. Davon abgesehen
bekommst du mit WebDAV- oder gar DeltaV-Konformität einen Haufen
weiterer Clients geschenkent. Konkret bei Subversion nutzt die aber
eh keiner, daher stimme ich dir zu, dass diese WebDAV- und DeltaV-
Geschichten *erstmal* nur Overkill sind.

Dass Subversion jedoch ein auf HTTP basiertes Protokoll spricht, *hat*
handfeste Vorteile: Du kannst das Repository über einen Webserver
verfügbar machen. Kein zusätzlicher Port, kein extra abzudichtener
SSH-Zugang.

Für diesen Zweck ein extra Apache-Modul zu schreiben *ist* jedoch
wiederum Overkill. Macht es unnötig nervig zu installieren, und wer
Performance braucht, geht eh nicht über HTTP+WebDAV. :-)
Eleganter ist z.B. das, was Mercurial macht: Sie bieten ein CGI-
Script an. So hat man auch einen Zugang zu HTTP, und zwar
sinnvollerweise einen, den *sowohl* die Kommandozeilen-Tools *als*
auch der Benutzer mit Browser erreichen kann.

Will sagen: Nicht alle Akronyme sind schlecht oder nichtssagend. Ich
würde eher behaupten, dass "Protokoll über HTTP nur mit Apache-Modul
möglich" nach einem großen Bogen schreit.

Besonders absurd: Es gibt dann wieder CGI-Scripte für SVN-Repositories,
d.h. beides geht über HTTP, über einen Webserver, aber das eine per
CGI-Script und das andere als Apache-Modul, entsprechend mit
unterschiedlichen URLs etc.

> > > mmm... und wenn das weg ist? Platte kaputt oder so? Zentral hat auch
> > > Vorteile (besser für backup).
> > 
> > Wenn das Repository im Netz ist, ist das noch viel nerviger.  Davon
> > abgesehen: Regelmäßige Backups tun's auch.
> 
> Ich mein, Backup ist einfach, wenn man "ein Verzeichnis" sichert und
> "alles" hat. Bei CVS und SVN geht das. Bei anderen kriegt man es
> hoffentlich irgendwie hin :)

Ja sicher, da hast du mit "ein Verzeichnis" sogar nicht nur alle
Versionen, sondern außerdem ne aktuelle Arbeitskopie.

Konkret in Mercurial hast du in deinem Arbeitsverzeichnis ein
Unterverzeichnis ".hg". Im Gegensatz zu SVN und CVS hast du das
nur einmal, nicht in jedem Unterordner (".svn/" bzw. "CVS/").

Dieses Verzeichnis ".hg" kannst du auch allein sichern. Dann hast
du nur die Repository-Daten. Kopiere es irgendwohin in ein leeres
Verzeichnis, und schon kannst du von dort (bzw. nach dort) einen Push
oder Pull machen. Oder du machst dort ein "hg update", schon hast
du ne aktuelle Arbeitskopie.

Sehr schick gemacht, find ich. Selbiges gilt für Darcs mit dem "_darcs"
Verzeichnis. In GIT sieht's wohl auch so aus.


Viele Grüße,

    Volker

-- 
Volker Grabsch
---<<(())>>---
Administrator
NotJustHosting GbR



Mehr Informationen über die Mailingliste linux-l