Source-Version-Management-de

From Java4c

Contents

[edit] Navigation

[edit] Source code management (SCM)

@ident=SCM

Links local:

Links in www:

  • [[1]]: wiki.bazaar.canonical.com/Scenarios

This size is in german, because it is discussed in a german team. It will be presented in english in the future. TODO

[edit] Kurzer Abriss, Arbeit mit MKSSI, git, mercurial, Bazaar

@ident=SCM-gitCo

Hartmut: MKSSI ist seit über 10 Jahren bei mir in Gebrauch.

  • Nur auf Arbeit, zentrale Administration,
  • Die MKSSI-Software wird normalerweise nicht ständig updated. Das Arbeiten ist nicht sehr schnell, eher etwas für ordentliche Pflege.
  • Wird gemacht, für die Versionen, die herausgegeben werden. Nicht für stündliche kleine Änderungen. Da wäre der Arbeitsaufwand zu hoch.

Hartmut: git war das erste der 'dritten Generation' für mich.

  • Geht ganz gut, init commit, alles ganz einfach
  • Nachschauen der Änderungen: Hier ist die GUI (gitk) nicht sehr bedienerfreundlich. Die schnelle Tastaturbedienung ist mangelhaft, der Tastaturfokus ist im falschen Teilfenster. Immer mit Maus schieben ...
  • Linux-like cmdline-Bedienung auf Windows-PC ist für mich eher interessant.

Hartmut: mercurial - ähnlich wie git, nur eher für windows, eigentlich sehr ähnlich git.

Hartmut: Bazaar gefällt mir persönlich wegen der GUI besser.

Hartmut: Alle drei Systeme sind aber funktionell eher ähnlich. Ich pflege Quellen in Bazaar, um sie dann auch in hg zu committen, mit selbigem commit-Text wie in Bazaar zuvor zusammengestellt. Das ist nur ein Aufruf. Ein Hg-Archiv beispielsweise für CRuntimeJavalike liegt auf [bitbucket.org/jchartmut/cruntimejavalike]. Hg deshalb, weil die bitbucket-Seite nur hg unterstützt. Der Aufwand, in hg doppelt zu pflegen, ist kaum erhebenswert.

Commit-Text zusammenstellen
Vorderhand geht es beim Commit-text darum: Was leistet diese Version insgesamt, unterschied zur Vorversion. In der Zweiten Linie geht es aber um die Änderung in den einzelnen Files.
Sind im Commit sehr viele Files enthalten, dann handelt es sich meist um das Ergebnis eines Refactoring wegen einer Änderung. Solche Änderungen brauchen in den Quellfiles nicht vermerkt werden, zuviel Aufwand, uninteressant.
Sind dagegen wenige Files geändert, dann lag meist auch eine Änderung der Funktionalität vor. Diese sollte unabhängig vom Commit in den Quellfiles notiert werden. Hier hilft aber die Differenzanzeige, um während des Commit die Änderungen in den Files zu vermerken. Man kann einen passenden Commit-Text zusammenstellen, dabei die Änderung der Einzelfiles betrachten und dabei in den Einzelfiles Änderungen notieren (log des Files).
Ein automatisches Eintragen der Änderung in den Files aus dem checkin-Textes aus der Arbeit mit dem Source-Integrity-System produziert meist Einträge in den Files, die die Änderungen schlecht abbilden. Das liegt daran, weil der Arbeitsaufwand für jeden Einzelfile zu hoch ist. Dieses automatische Eintragen ist aber eine häufig verwendete oder voreingestellte Methode bei MKSSI & co.
Der Arbeitsaufwand bei manuellem Eintragen in den File ist deshalb bei Bazaar geringer, weil
  • Es gibt eine schnelle Übersicht, welche Files betroffen sind. Einfacher Knopfdruck für Viewdiff. Man kann schnell auswählen, bei welchen Files ggf. gleiche Einträge überhaupt notwendig sind. Nicht bei allen geänderten.
  • Mit den Files, die keine wesentlichen Änderungen enthalten sondern nur Anpassungen an Änderungen anderer Files, braucht man sich also gar nicht beschäftigen.
  • Die Änderung im File eingetragen und per Zwischenablage auch im Commit-Text abgelegt ist dann eigentlich nur einmaliger Aufwand, nicht zweimal.
  • Wenn es wesentliche Änderungen sind, dann ist die Beschreibung der Änderung auch ein schöpferischer und nicht formeller Akt. Dann lohnt es sich auch, die entsprechend notwendige Zeit aufzubringen. Möglicherweise wird man bei der Änderungsbeschreibung im File auch noch weitere dabei entdeckte Pflegekorrekturen anbringen, die insgesamt die Quelle weiter aufwerten. Dann hat es sich sowieso gelohnt.


[edit] Einzelne Files vs. SCM-Archiv

@ident=SCM-Files .

[edit] Primat der Datenhaltung im SCM

Ein Source Content Management (SCM) wie Bazaar, git oder andere enthält alle relevanten Files einschließlich deren Versionierung in einer eigenen internen Form (Datenbasis) gespeichert. Dem gegenüber steht der Working tree. Das sind die Files mit denen man arbeitet. Der working tree lässt sich jederzeit aus dem SCM für beliebige Versionen rekonstruieren. Committet man immer auch Änderungen, dann ist der working tree temporär. Man braucht ihn nur während des Editierens, Compilierens, Makens. Danach kann er ersatzlos gelöscht werden, da alles im Archiv des SCM steht.

Damit steht das SCM im Mittelpunkt. Das ist auch in Ordnung so, da dies die entscheidende Stelle für die Versionierung der Sources ist. Diesbezüglich unterscheiden sich zentrale SCM nicht von den verteilten. Lediglich - bei einem zentralem SCM braucht man die Serveranbindung.

Die Files stehen meist als working tree solange bereit, bis man sie nach vorigem commit oder checkin löscht. Damit kann man auch bei einem zentralem SCM dezentral an den Files arbeiten, wenn auch nicht einchecken oder ältere Versionen sichten.

Die Alternative, ein File-Baum nur in direkter Verbindung mit dem SCM bereitzustellen gibt es auch. Dann sind die Files nur aufrufbar, wenn das SCM läuft. Die Files werden vom Betriebssystem dann nicht auf der Festplatte mit dem üblichen Filesystem gespeichert sondern alle Filezugriffe des Betriebssystems laufen über den SCM-Treiber. Damit sind keine Files vorhanden wenn das SCM mit seinem Archiv nicht zugänglich ist. Diese Variante ist die konsequenteste Anbindung an ein SCM, aber für eine offline-Arbeit eher schwierig und daher weniger verbreitet.

Es gibt also ein Primat des SCM gegenüber den Einzelfiles, das mehr oder weniger stark ist.

[edit] Gegenentwurf - Primat der Einzelfiles, lediglich Ablage und Austausch über das SCM

Es ist möglich, die Hauptsicht auf die Files zu legen und das SCM nur als Ablage oder Austauschmedium zu nutzen. Die Files werden dann immer beibehalten, in das SCM wird nur eingecheckt oder committet. Das SCM hat dann den Zweck, auf Altversionen rückgreifen zu können und Versionen einfach zu vergleichen. Austauschen wird man gegebenenfalls über das SCM nur bestimmte Schnittstellenfiles, wenn die Bearbeitung sonst in einer Hand liegt.

Diese Arbeitsweise hat einen entscheidenden Nachteil: Es wird gegebenenfalls nicht bemerkt, dass wichtige Files überhaupt nicht in das SCM aufgenommen worden sind. Wenn dann keine weitere Datensicherung besteht und nur noch der Datengehalt des SCM verfügbar ist, sei es wegen einem Hardwarecrash, sei es bei Bearbeiterwechsel usw, dann kommt das Böse Erwachen. Es compiliert nicht, was fehlt...

Der andere Nachteil ist, das sich möglicherweise Alt-Files ansammeln, man löscht diese nicht aus Befürchtung, irgendwo könnten diese noch wichtig sein.

Tendiert ein Bearbeiter zu der Arbeitsweise, eher Files zu behalten und nur einzuchecken, dann muss es einen Test an anderer Stelle auf Vollständigkeit der Daten im SCM geben. Am einfachsten ist dies getan, wenn auf einem leerem PC oder Verzeichnisbaum aus dem SCM ausgecheckt wird und dort alle relevanten Makeprozesse durchlaufen werden. Laufen diese fehlerfrei und ist das Ergebnis korrekt, dann sind die Sources vollständig.

[edit] Kompromiss - Arbeit mit Files und dem SCM

Eine kleine Anekdote:

Seit mehr als einem Jahrzehnt läuft Software auf Anlagen. Sorry, die Welt ist nicht so schnellebig wie junge Leute heute glauben. Die Software wurde zu einer Zeit erstellt (seit 1994), zu der SCM noch nicht so gängige Praxis war. Jedoch wurde die Software in fleißiger Arbeit postum eingecheckt, prozess-konform, wie es sich ordentlich gehört. - Ein paar Jahre später, Nachbesserung von Hardware auf der Anlage, gegebenenfalls ist die Software betroffen. Mittlerweile war das SCM die "alte Version", doch selbstverständlich, man hat ja Zugänge und Archive gespeichert. 1 Tag Arbeit, und der Zugang funktioniert. Nun jedoch zeigte es sich, das zwar damals alles ordentlich eingecheckt wurde, aber nur die offensichtlichen Endstände. Da fehlte etwas, da stimmt was nicht - da war doch noch was ????. Bis ein Kollege damit herausrückte, er hat mal alle Stände auf CD direkt archiviert, die CD liegt im Schrank.

Die Files auf der CD hatten dann tatsächlich für mich als Entwickler einen hohen Wiedererkennungswert, wichtig dabei die Verzeichnisstruktur. Da die Backups von den laufenden Arbeitsstadionen gezogen worden sind, direkt ohne Zusatzaufwand als Filebaum, war eine Vollständigkeit gewährleistet. Die Zusatzarbeit des Eincheckens in das damalige SCM versionsgetreu hatte also Informationen verwässert.

Mit Diff-View auf den Files war dann schnell wieder der Überblick über den Gang der Entwicklung da. Übrigens - wenn man alles sehr fein säuberlich dokumentiert, auf 100 Seiten oder mehr, muss man dann später die 134 Seiten wieder lesen - ist auch Aufwand.

==>Über lange Jahre ist zwar ein SCM-System stabil und kritikunwürdig (ja klar), aber die Arbeit damit nicht. Zum Glück hat man dann backups der Files direkt.

==>Ein SCM ist wichtig für die zeitnahe Arbeit. Insbesondere für das Diff-View und die Nachverfolgung, wann wurde was geändert. Ohne SCM ist nicht!!! Aber die Arbeit direkt mit den Files hat auch seine Vorteile.


[edit] Mehrere Arbeitsverzeichnisse, mehrere SCM-Archive, Wiederverwendung

Wird Software stark wiederverwendet, dann erscheinen die gleichen Quellfiles möglicherweise innerhalb der jeweiligen Applikationen selbst beim selben Bearbeiter mehrfach.

Diese konsequente Art der Wiederverwendung ist nicht häufig anzutreffen. Wiederverwendung wird meist verstanden als kopiere es und pass es an. Die konsequente Wiederverwendung - gleiche Quellen ohne Anpassung - hat den Vorteil dass Fehler oder Verbesserungen in einer Anwendung gefunden sofort auch in den anderen Anwendungen nützen. Allerdings muss man bei diesen wiederverwendeten Quellen die Unabhängigkeit von der jeweiligen Applikation beachten. Eigentlich eine konsequente Softwaretechnologie.

Werden die Quellen mehrfach für verschiedene Applikationen benutzt, dann kann nicht vorausgesetzt werden, dass alle Projekte mit einem einheitlichen Stand der Quellen arbeiten. Wünschenswert ist es zwar, dass an allen Stellen mit der selben Version gearbeitet wird, eben wegen der Vorteile. Andererseits kann aber eine Änderung in einer Applikation zwar allgemeingültig erfolgen, jedoch nicht fehlerfrei und allgemeingültig genug. In einer anderen Applikation können sich Folgefehler ergeben, die erst gefunden und getestet werden müssen. Ergebnis dessen ist zwar eine verbesserte Allgemeingültigkeit, jedoch ist dies mit Arbeit verbunden. Für Bugfixes aus Sicht einer Anwendung werden sich daher Differenzen nicht vermeiden lassen.

Damit sind möglicherweise Seitenzweige im Archiv des SCM erforderlich. Andererseits sollte ein Zuviel an Seitenzweigen vermieden werden, besser ist es jeweils nach Korrekturen den Hauptzweig anzuwenden. Die Seitenzweige sollten eher temporärer Natur sein.

Das SCM Bazaar unterstützt Seitenzweige mit automatisch unterstütztem merge.

[edit] Vermeiden von Seitenzweigen bei Änderungen gemeinsamer Quellen für verschiedene Anwendungen zeitlich nacheinander

Um Seitenzweige zu vermeiden, kann sich folgende Vorgehensweise als geeignet erweisen:

  • Angenommen, eine Applikation A verwendet die Hauptversion 123.
  • In einer anderen Applikation B werden in einer gemeinsamen Source-Komponente Verbesserungen vorgenommen. Damit entsteht letzlich die Hauptverson 137.
  • Nun wird versucht, die Hauptversion 137 auch in A anzuwenden. Angenommen, es gibt Anpassungsnotwendigkeiten, die sich erst aus Sicht der Applikation A zeigen aber insgesamt die gemeinsame Komponente aufwerten. Es entsteht Hauptversion 139.
  • Nun sollte diese Hauptversion auch für B anwendbar sein. Hat man Schnittstellen gut definiert, dann sollte es nicht unbedingt schon wieder Komplikationen geben. Es bleibt also bei der 139.
  • Das Ganze soll nun auch für weitere Applikationen passen. Eventuell sind wiederum Anpassarbeiten notwendig.

Werden die Anpassungen nicht nacheinander sondern parallel ausgeführt, von verschiedenen Bearbeitern, dann entstehen zwischendurch Seitenzweige, die jeweils wieder bereinigt werden müssen. Diese Bereinigungen sind teils mergen, teils Schnittstellen klarer formulieren, teils Verbesserungen für allgemeingültige Verwendung. Es ist nun günstig, diese Bereinigungen in einer Referenzapplikation zentralisiert auszuführen. Der Test, ob die Ergebnisse bei den einzelnen Applikationen passt, ist dann wieder dezentralisiert.

Verwendet man Bazaar, dann entstehen dezentralisiert divergierende Versionen. Diese in einem Baum zusammenzufassen kann sich gegebenenfalls als nicht zweckmäßig erweisen. Gegebenenfalls ist es besser, in der zentralisierten Bearbeitung der Komponente mit der Referenzapplikation zwar alle Inputs zu verwerten, aber nicht auch alle nuancierte Änderungen im Original zu berücksichtigen. Oft ist ein Austausch - eine kompatible aber bessere Variante - die einfache Lösung, die auch Zufriedenheit bei den einzelnen Applikationen auslöst.

Damit ergibt sich allerdings die Situation, dass das formelle Arbeiten mit den Bazaar-Archiven nicht funktioniert. Denn:

  • Applikation A hat ihre Version 125 abgegeben (merge-Input), die eine Verbesserung der zuvor erhaltenen (poll) Version 123 darstellt.
  • Applikation B hat aber in ihrer Version 137 aus der gemeinsamen Versionen 123 hervorgegangen möglicherweise adäquate aber nicht gleiche Lösungen gefunden, die auch der Verbesserung in A entsprechen.
  • Die zentralisierte Bereinigung entschließt sich daher, zwar die Funktionalität von A in 125 in der Nachbearbeitung zu garantieren, enthält aber nicht formell den Versionsstand 125 von A. Die nachbearbeitete Komponente wird also als Version 137 wieder der Applikation A angeboten, jedoch nicht passend in Archivbaum, der in A verwendet wird.
  • A muss nun einerseits möglichst positiv entscheiden, dass die Änderungen zu Version 137 überhaupt benutzt werden. Die positive Entscheidung bedeutet die Fortsetzung der Partizipation an der Weiterentwicklung in der Zukunft. Andererseits muss A den Aufwand treiben, zu testen, dass es keine negativen Auswirkungen gibt.
  • Formell kann die Applikation A nicht das bisherige SCM-Archiv einfach updaten, da die eigene letzte Version nicht enthalten ist.
  • Zielführender ist es, nun auf der Basis der Sichtung der Differenzen der Files zu entscheiden, welche Tests ausgeführt werden müssen und welche Auswirkungen zu erwarten sind. Möglicherweise findet sich die Funktionalität der ursprünglichen Verbesserung 125 in A in nur in wenigen Zeilen nicht identisch aber passend ausgeführt. Alle anderen Änderungen sind nicht relevant da sie nicht verwendete Funktionen betreffen. Es ist also auf Basis der File-Differenz-Sichtung leicht zu entscheiden, dass nunmehr auf der neuen Version 137 aufgesetzt wird.
  • Das SCM-Archiv kann nun in der Applikation A neu importiert werden, das alte Archiv wird gelöscht. Es enthielt zwar die Änderungen von 123 auf 125, die sich im neuen Archiv nicht finden, angenommenerweise ist diese Version 125 in A aber nicht pflegerelevant.

Dieses Szenario kann durchaus als typisch bezeichnet werden. Die meisten Änderungen werden kompatibel vorgenommen oder treffen nicht für alle Applikationen zu, wenn sorgsam in der Komponentenentwicklung gearbeitet wird.

Damit verschiebt sich allerdings die Sicht vom Primat des SCM-Archivs auf das Primat der Files. Zumindestens während des Überganges der Nutzung der neuen Hauptversion 137.

Wie sollte konkret umgegangen werden:

  • Die neue Hauptversion 137 der Komponente wird aus dem erhaltenem SCM-Archiv auf einer unabhängigen Stelle im Filesystem als Workingtree exportiert. Die Files der Komponente in der Applikation werden nicht geändert.
  • Nun erfolgt der Einzelfilevergleich zwischen dem neuen Workingtree und den bestehenden Files. Selbstverständlich sind dabei die Einträge im Log des SCM-Archives für das Verständnis der Änderungen wichtig. Letzlich werden aber die Inhalte der Files auf Passfähigkeit begutachtet.
  • Im zweiten Schritt werden die neuen Files als File, nicht über das SCM-Archiv in die bisherige Applikation kopiert und die im alten aber nicht im neuen Archiv befindliche Files werden gelöscht. Letzteres ist wesentlich und typisch wenn in der Komponente umstrukturiert wurde. Das bisherige Archiv, im Beispiel auf der 125 stehend, wird erstmal weiterverwendet. Der neue Stand wird also als 126 committet.
  • Danach erfolgt der Test von A.
  • Im Idealfall passt alles. Es gibt keine Änderungen. Etwas weniger ideal aber erwartbar ist, dass der Stand der Komponente 137 vollständig akzeptierbar ist, allerdings sind kleine Nachbesserungen in der Applikation notwendig.
  • In diesen beiden Fällen kann dann das Archiv ausgetauscht werden. Das alte SCM-Archiv mit den Versionsständen 123, 125 und zuletzt 126 wird entfernt, statt dessen das gelieferte Archiv mit der 137 eingesetzt. Im Archiv kann dann nachgelesen werden, welche Änderungen es insgesamt in der Komponente gab, auch wenn sich diese nicht aus der Applikation A ergeben hatten. Möglicherweise sind diese Änderungen für die Weiterentwicklung von A interessant oder wichtig.

Der Fall der notwendigen Nachbesserung in der Komponente, weil die Funktionalität in A nicht passt, erfordert den oben beispielhaft dargestellten Zyklus der Nachbesserung in der Komponente mit notwendigem Aufwand wiederum für alle Applikationen. Entweder dieser Aufwand ist gerechtfertigt oder möglich. Oder nach entsprechenden Klärungen ordnet sich die Applikation A dem gegebenen Stand der Komponente unter, oder mindestens vorerst wird weiter mit der eigenen Variante A gefahren.

  • Konkret kann dabei auf der neu gelieferten Version 137 mit neuem Archiv aufgesetzt werden: Dort werden die notwendigen Änderungen vorgenommen und das ganze wird als neuer Versionsstand 138 aus Sicht der Applikation A an die zentrale Komponentenentwicklung zurückgeliefert.
  • Der Zyklus beginnt damit erneut, hoffentlich mit kleinen und kompatibel ausführbaren Änderungen, die für eine Beruhigung der Zyklen sorgt.


[edit] Überblick über die Anzahl Archive für die selbe Softwarekomponente ?

Die Kapitelüberschrift ist mit einem Fragezeichen versehen.

Angenommen, es gibt etwa 10+x Stellen, an denen die selbe Softwarekomponente (gleiche Quellen) eingesetzt wird. Das kann sich auf mehrere PCs und Bearbeiter verteilen, auch auf dem selben PC mag es mehrere Stellen geben, weil die Softwarekomponente eben in verschiedenen Applikationen drinsteckt.

Bazaar sieht nun vor, an jedem Working tree ein eigenes Archiv zu haben. Man kann mit Bazaar-Bordmitteln dann pushen, pullen, mergen jeweils mit einem anderen Archiv. Insbesondere kann an jedem Archiv auch ein 'submit-branch angegeben werden (Settings - configuration - branch). Damit kann unaufwändig ein etwas zentraleres Archiv angesprochen und beobachtet werden. Allerdings gibt es dabei einen Mangel (Bazaar Version 2.3.0): Es werden zwar Differenzen des eigenen Archivs zum submit-Archiv angezeigt, also ein auf ein noch auszuführendes push hingewiesen. Es wird aber nicht ein neuer Stand im submit-Archiv angezeigt, der pull-würdig wäre. Man erfährt also nicht dass man eigentlich gegenüber dem zentralen Archiv einen etwas älteren Stand hat. Aufbauend auf diesen arbeitet man dann los, um dann beim pull festzustellen, dass nun ein aufwändigeres merge ansteht.

Bei 10+x Archiven, die sich gut gegeneinander updaten lassen, können sich Unterschiede breitmachen und Merge-Aufwand erzeugen, die überhaupt nicht gewünscht sind. Außerdem kann man leicht den Überblick verlieren, wo denn überhaupt welche Bearbeitung stattgefunden hat. Beim Mergen muss man dann erst einmal überlegen, was denn die bessere Version ist. Damit artet das Ganze in Arbeit aus, die man doch vermeiden und verbessern wollte ....

Es kann passieren, das es in den Weiten der Festplatte Archive dem Entwickler nicht mehr bewusst ist, wo denn überall Archive stehen. Man hat also vor ein paar Monaten eine Arbeit fortgesetzt, das Archiv an eine andere Stelle kopiert, dann kamen andere Themen dazwischen. Merkt man sich immer wo man als letztes dran war oder kommt es vor, dass eine Arbeit wegen der eigenen Vergesslichkeit doppelt gemacht wird? Irren ist menschlich, aber eine gute Organisation auf dem Computer sollte Irrtümern vorbeugen.

Mit einem zentralen Archiv für einen Benutzer und eine Softwareversion geht es besser

Die Arbeit mit einem zentralen Archiv gestaltet sich einfacher, wenn es eigentlich nur einen Hauptzweig gibt und Unterschiede vermieden werden sollen. Unterschiede entstehen eher unerwünscht bei Parallelarbeiten und sind möglichst schnell wieder abzustellen.

Der Vorteil der dezentralen Archive liegt in der Dezentralisation bei mehreren Bearbeitern oder auf nicht immer im Netz verbundenen Computern eines Benutzers. Die totale Dezentralisation ist jedoch ggf. zuviel des Guten.

Zweckdienlich kann es daher sein, für einen Bearbeiter auf einem PC nur ein Archiv zu halten. Voraussetzung dabei ist, dass alle Applikationen auch mit dem selben Softwarestand arbeiten wollen. Die Files sind nur deshalb mehrfach vorhanden, weil eine lokale Compilierung in der Appplikation stattfinden soll und die Archivierung der Files anderweitig eine Rolle spielt.

Ich habe auf einem PC eine Entwicklungsumgebung (Eclipse für Java), in der in einem großen Projekt alle Quellen für alle Applikationen eingebunden sind. Damit ist es beispielsweise bei Strukturänderungen relativ einfach, die automatischen Möglichkeiten des Tools zu nutzen (renaming, wird automatisch in allen sichtbaren Quellen nachgezogen). Außerdem gewinnt man bei möglicherweise problematisch inkompatiblen Änderungen sofort den Überblick, wo es klemmen könnte. Es wird jeweils alles compiliert. Diese Arbeitsweise hat sich bewährt. Die Entwicklung an den Quellen wird also auf einem PC zentralisiert unabhänig von den Applikationen ausgeführt.

Jedoch gibt es bei mir für die einzelnen Applikationen verschiedene Stellen im Filesystem (Working areas). Die Applikationen müssen ihre Quellen in einem geschütztem Raum haben. Eine Änderung im Entwicklungsprojekt mit Blick auf Applikation X kann für Applikation Y zwar formell compilierfähig und grundsätzlich richtig sein, ist aber damit noch nicht wirklich getestet. Es kann sein, dass die Bearbeitung im Entwicklungsprojekt zeitlich stagniert und eine kleine Änderung und Auslieferung in Applikation Y dazwischenkommt. Mann kann sich nun keinesfalls auf den letzten Quellenstand beziehen sondern nur auf den gut getesteten Stand. Um nach kleinen Korrekturen einen neue Executable zu erzeugen, compiliere ich mit einem Batch-Aufruf. Das ist einfacher. Beim Batch-Aufruf werden die Files in der Working-Area der Applikation benutzt. Bei einer Feinkorrektur braucht es keinen entwicklungsumgebungsunterstützten Test mit Schritt-Debugging usw. Die Korrektur wird textuell ausgeführt, compiliert und zur Laufzeit getestet.

Da nun die Working area in Applikation Y kein eigenes Archiv hat, sind die Quellen in diesem Moment nicht archiviert und es entsteht auch kein Seitenzweig. Entweder kann mit einer Nacharbeitung ein Seitenzweig gebildet werden, wenn dies dauerhaft notwendig ist. Dann wird auf einem Parallelverzeichnis nun im nachhinein ein Bazaar-Archiv des notwendigen Standes aus dem zentralem Archiv gebildet und die Änderung dort committed. Der Seitenzweig lässt sich dann später wieder in den Hauptzweig mergen. Oft ist aber der Seitenzweig nicht notwendig. Die Änderungen in Applikation Y beziehen sich oftmals gar nicht auf die Quellen selbst sondern auf Zusatzfiles oder dergleichen. In der Nachbearbeitung kann dann statt dessen die Änderung direkt auf das zentrale Archiv überführt werden. Im zweiten Gang wird dann geprüft, ob der Hauptzweig vollständig funktionsfähig ist. Dazu braucht es etwas Testzeit. Damit entsteht gegebenenfalls zwar wieder eine Änderung in Applikation Y, die erneut ausgeliefert werden soll, nun aber wieder auf der Hauptversion basierend gegebenenfalls mit weiteren mittlerweile notwendigen Änderungen.

Hier wäre mal eine Skizze gut!!!

Der Gesamttest wird aber in dem zentralem Eclipse-Projekt mit zentralisierten Files. Damit wird immer auf dem letzten Stand basierend getestet. Von dieser zentralisierter Working-Area wird dann das Archiv (Bazaar) gepflegt, von dort wird committed.

Wie kommt aber nun eine Detailänderung aus einer denzentralen Workingarea in das Archiv? Wie kommt der letzte Archivstand in die dezentrale Working-Area?

Für die zweite Frage gäbe es eine Antwort:

 bzr export %DST% --per-file-timestamps -r %REVISION%

Damit werden nur Files nach %DST% kopiert, sogar mit dem originalem Datum (geht nicht bei Unix), optional mit einer angegebenen Revisionskennzeichnung. Aber: Das ist ein blindes kopieren. Man sieht nicht vorher, welche Änderungen sich damit ergeben. Man übersieht und überschreibt für immer Änderungen in der Workingarea. "bzr export" eignet sich für die Erstellung einer neuen workingarea ohne Archivanbindung, nicht aber für's updaten.

Die ggf. bessere Variante liegt außerhalb des SCM, nämlich bei den altbewährten File-Baum-Diff-Tools. Da gibt es eine Menge, jeder hat seine gewohnten Tools, diese haben sich bewährt. Man kann die Unterschiede per File-Vergleich sichten und damit übersichtlich entscheiden, ob eine Änderung denn überhaupt wesentlich ist, was eine andere Änderung an Nebeneffekten bewirken könnte usw. usf. Ein Merge mit bazaar ist zwar auch ganz gut, aber es erzeugt zuerst Seitenversionen, bei denen man im Nachhinein (!) dann feststellt, dass das eigentlich unerwünschte oder unnötige Seitenzweigänderungen sind. Damit sind diese aber schon im Archiv manifestiert, haben Datenmüll erzeugt und müssen dann zusätzlich im Nachhinein wieder ausgebessert werden (Anschauen, löschen von *.THIS, *.BASE und *.OTher). Die Arbeit kann man sich sparen.

Die Lösung wäre also hier: Ein Archiv (pro PC) mit dem Haupt-Workingtree aus Haupt-Workingarea, manuelles Abstimmen von Files in den einzelnen Workingareas für die jeweiligen Applikationen. Man kann in diesem Zusammenhang "bzr export" nutzen um letzlich genau den Archivstand in eine Applikations-Workingarea hineinzulegen. Zuvor sollte die Workingarea gelöscht bzw. besser parallel gesichert und danach gelöscht werden. Erfolgt das löschen nicht, dann besteht die Gefahr, dass in der Applkations-Workingarea Files liegen, die wichtig für die Applikation sind, sich aber nicht im SCM-Archiv befinden. Das sollte unbedingt kontrolliert und vermieden werden. Wird zuerst per "move"- Befehl gelöscht und gesichert, danach die Files per "bzr export" neu eingespielt und danach compiliert, dann fallen diese Fehler auf. Bei Problemen kann man auf die gesichrten Files zurückgreifen. Letztlich sollte die Sicherung aber vernichtet werden, da sie sonst auch wieder nur Datenmüll ist.

Es gibt noch eine andere Möglichkeit des Bindens nur eines Archives an mehrere Working-Areas:

Unter Linux kann ein symbolischer Link bzr. auf das Archiv gelegt werden. Das Archiv muss dabei auf demselben Datenträger stehen, einige Funktionalitäten in Bazaar gehen sonst nicht. Aber es kann zentral irgendwo anders stehen. Mehrere symbolische Links können auf das selbe Archiv zeigen.

Nun kann man damit

  • commit von verschiedenen Working-Areas ausführen und trifft jeweils das selbe Archiv. Die committeten Files erscheinen damit im Archiv, nicht jedoch automatisch in den anderen Working-Areas!
  • den Filebaum betrachten und feststellen, welche Änderungen im Archiv passiert sind, die nicht aus dieser Workingarea stammmen. Man kann sich über die Bazaar-GUI die Differenzen anzeigen. Da Bazaar diese Arbeitsweise so nicht vorsieht, präsentieren sich die Änderungen spielelverkehrt. Geänderte Files mit neuem Stand im Archiv erscheinen als commitwürdig der alten Files. Neue Files im Archiv erscheinen als deleted files. Um hier zu unterscheiden, was denn Änderungen in der speziellen Working Area sind, muss man schon die eigenen Files kennen. Dabei hilft ein kleines Backup des letzten Standes aus dem SCM, auf dem aufgesetzt worden ist, dabei wieder mit File-Diff-View außerhalb des SCM - nur um die eigenen Änderungen zu erkennen. Das ist damit eindeutig. File-Diff-Tools können teils auch direkt in Zip-Archiven arbeiten. Man benötigt also nur ein einfaches Zip-Backup angelegt bevor man in der speziellen Working area losarbeitet. Man kann auch postum über ein "bzr export" den Ausgangstand wieder erzeugen.
  • committen einzelner Files, die nur in dieser Working Area geändert worden sind.
  • Zuletzt über
bzr revert
  • +den Stand aus dem SCM-Archiv in die working-Area hinein synchronisieren um wieder einen gemeinsamen Ausgangsstand zu haben.

Unter Windows geht das mit dem symbolischen Link nicht. Man kann aber stattdessen mit einem move-Befehl das Archiv von einem Platz auf einen anderen Hin- und Herschieben. Es sollte zuletzt immer auf dem zentralen Platz wieder landen, sonst weiß man nicht wo es aktuell steht. Der move-Befehl kopiert nicht die Archiv-Files auf der Festplatte sondern ändert tatsächlich nur einen Verzeichniseintrag. Das ist also von der Belastung der Festplatte und vom Zeitaufwand her gesehen sehr billig. Vorraussetzung: Selbe Partition der Festplatte!

Ich habe dazu folgende Befehlsfolge in einem zentralen Batch-File niederlegt:

File bzr_mvExpl.bat

set CMPN=%1
REM Add the Bzr directory to system-wide PATH environment variable
SET PATH=D:\Progs\Bazaar;%PATH%
attrib -h \Bzr\%CMPN%\.bzr
if not exist .bzr move \Bzr\%CMPN%\.bzr .bzr
echo Bazaar-Explorer: 
bzrw.exe explorer .
bzr.exe version-info >_bzr_version.txt
if not exist \Bzr\%CMPN%\.bzr move .bzr \Bzr\%CMPN%
attrib +h \Bzr\%CMPN%\.bzr

Wichtig für das funktionieren des move-Befehls ist das Rücksetzen des Hidden-Attributes für das .bzr-Archiv.

Dieses File wird in einem File im Arbeitsverzeichnis (Working Area)

.bzr.bat 

mit drei Zeilen

SET USERNAME=hartmut
SET BZREMAIL=hartmut.schorrig@vishia.de
bzr_mvExpl.bat srcJava_vishiaBase

aufgerufen. Das srcJava_vishiaBase ist hierbei der Name der Softwarekomponente und der Name des Verzeichnisses in dem das .bzr-Archiv steht. Alle .bzr-Archive stehen dabei zentral auf der selben Festplatte (keine Laufwerksangabe am Pfad) im Verzeichnis \Bzr. Da dies so zentral festgelegt ist, kann das Batchfile direkt darauf zugreifen. Im Start-Batchfile sind zusätzlich in lokal gültigen Umgebugsvariablen die Commit-Daten niedergelegt. Diese sind damit Working-Area-spezifisch.

Es gibt dann noch einen weiteren interessanten Batchfile:

File bzre.bat

@echo off
REM Add the Bzr directory to system-wide PATH environment variable
SET PATH=D:\Progs\Bazaar;%PATH%
SET USERNAME=hartmut
SET BZREMAIL=hartmut.schorrig@vishia.de
::
if not "%1" == "cd" goto :nocd
echo on
cd %2
echo off
:nocd
REM if the directory contains .bzr.bat, it is processed. It doesnt return!	
REM if the directory or any parent does not contain .bzr change to the parent.
 if exist .bzr.bat .bzr.bat
 if not exist .bzr cd ..
 if exist .bzr.bat .bzr.bat
 if not exist .bzr cd ..
 if exist .bzr.bat .bzr.bat
 if not exist .bzr cd ..
 if exist .bzr.bat .bzr.bat
 echo Bazaar-Explorer: %CD%
 bzrw.exe explorer .
 bzr.exe version-info >_bzr_version.txt
 goto :ende  
 
:ende
exit /B

Dieses File kann entweder parameterlos gerufen werden oder mit den Parametern

bzre.bat cd aktuelles_Verzeichnis

Anhängig davon ob im angegebenen aktuellen Verzeichnis oder mehreren übergeordneten Verzeichnissen entweder ein Verzeichnis .bzr vorgefunden wird - das wäre also ein lokales eigenes Archiv - oder es wird ein File .bzr.bat vorgefunden, wird entweder der Bazaar-Explorer mit dem vorhandenen lokalen Archiv gerufen, oder es wird das oben aufgeführte bzr_mvExpl.bat aufgerufen, das das Archiv hin-und herkopiert. Man hat also einen Aufruf für alle vorkommenden Fälle und kann den Bazaar-Explorer unabhängig und schnell starten, ohne nachdenken und suchen zu müssen.

[edit] Synchronisierung mehrerer Bearbeiter

Wenn jeder sein eigenes bzr-Archiv hat und es wird gemerged, dann ist das so wie es Bazaar vorsieht.

Wenn es aber einen Hauptbearbeiter gibt und mehrere eher Nutzer dieser Sources, dann kann es auch eine File-diff-Tool-Abstimmung geben wie oben dargestellt. Man muss sich nur ab und zu in einem Netzwerk treffen. Es will nicht jeder immer und überall alle Files ändern.

[edit] Source Content Management oder hart archivieren? Nur Quellen im SCM?

Eine harte Archivierung ist das Verpacken der Files auf einem Datenträger. Da das Zip-format sich als langjährig beständig erwiesen hat, kann man ganze File-Bäume zippen und irgendwo aufheben.

Nachteil: Keine Unterstützung für Diff-View außer auspacken und mit einem Diff-tool vergleichen. Der Total-Commander eignet sich dazu allerdings recht gut, da er in beiden Paneelen in zip-Archive tief eintauchen kann.

Vorteil: Unabhängig von einem Tool, die Files einer Version sind zusammengebunden einfach da. Es hat sich schon oft als günstig erwiesen, lange Jahre zurückliegende Files nicht mit den damaligen Tools aufrollen zu müssen sondern einfach entzippen.

Der Vorteil für die Langjährigkeit sollte bedacht werden.

=>Schlussfolgerung: Ab und zu zippen und wegpacken, mindestens bei wichtigen Releaseständen. Aber unnütze zipfiles auch mal löschen.

=>Schlussfolgerung: Für akutelle Softwareentwicklung jedenfalls ein Source-Integrity-Tool nutzen, Zippen nur zusätzlich.


[edit] Verzeichnissstuktur-Rückschluss

Sowohl für das Zippen als auch für Sourcenpflege, Sourcenaustausch usw. liegt der tatsächliche Umfang von Sources insgesamt meist in einem Bereich von wenigen Megabyte. Damit ist der Datenaustausch mindestens erleichtert. Wenn man in die selbe Verzeichnisstruktur in der Quellen liegen noch hineintue:

  • Objects
  • erzeugte executable und umfangreiche Datenbasis-Files (Visual Studio ncb-Files und dergleichen)
  • logfiles, Output-Files beim Testen
  • alte Archive (zips)

dann springt der Umfang des Verzeichnisbausms von wenigen Megabyte ganz schnell auf -zig Megabyte. Das Problem merkt man

  • beim zippen (ganz schnell mal ablegen zum späteren Vergleich)
  • beim Vergleichen (alle Obj erscheinen als geändert, alles rot, erst mal schaun was das ist)
  • bei der Pflege der Sources in einem SM-system (Source Management): viele nicht erfasste files: Sind die wichtig? Ach, sind nur Obj, doch ein wichtige wird übersehen.

=>Schlussfolgerung: Möglichst Sources von Testfiles und Executables trennen. Die wenigen Files, die nicht trennbar sind (weil die Tools sie ins aktuelle Verzeichnis legen), in einer ignore-Liste erfassen, ggf. beim zippen ausschließen usw. Sind es wenige, dann sind sie verwaltbar

  • Object-Files auf einem tmp-Ordner speichern
  • Generierergebnisse neben dem Source-Baum speichern.

[edit] Quellen und Generate in einem Verzeichnis ?

Sowohl für das Zippen als auch für Sourcenpflege, Sourcenaustausch usw. liegt der tatsächliche Umfang von Sources insgesamt meist in einem Bereich von wenigen Megabyte. Damit ist der Datenaustausch mindestens erleichtert. Wenn man in die selbe Verzeichnisstruktur in der Quellen liegen noch hineintue:

  • Objects
  • erzeugte executable und umfangreiche Datenbasis-Files (Visual Studio ncb-Files und dergleichen)
  • logfiles, Output-Files beim Testen
  • alte Archive (zips)

dann springt der Umfang des Verzeichnisbausms von wenigen Megabyte ganz schnell auf -zig Megabyte. Das Problem merkt man

  • beim zippen (ganz schnell mal ablegen zum späteren Vergleich)
  • beim Vergleichen (alle Obj erscheinen als geändert, alles rot, erst mal schaun was das ist)
  • bei der Pflege der Sources in einem SM-system (Source Management): viele nicht erfasste files: Sind die wichtig? Ach, sind nur Obj, doch ein wichtige wird übersehen.

=>Schlussfolgerung: Möglichst Sources von Testfiles und Executables trennen. Die wenigen Files, die nicht trennbar sind (weil die Tools sie ins aktuelle Verzeichnis legen), in einer ignore-Liste erfassen, ggf. beim zippen ausschließen usw. Sind es wenige, dann sind sie verwaltbar

  • Object-Files auf einem tmp-Ordner speichern
  • Generierergebnisse neben dem Source-Baum speichern.

[edit] Archivieren von Executables

Aus oben genannten Gründen sollten die Libs und Executables nicht mit den Sources im SM gemischt werden.

  • Die libs und executables könnten einerseits immer aus den Sources generiert werden (wenn alles richtig ist)
  • Die libs und executables sind nicht vergleichbar mit üblichen diffs.
  • Die libs und executables sind im Code-Umfang zu hoch.

Es ist aber wichtig, libs und exe im Zusammenhang mit einem Checkpoint der Sources zu speichern.

  • Als Auslieferungsstand
  • Als wichtigen Teststand für Rückrüsten, möglicherweise ein Kandidat für Auslieferung.

Lösung:

  • Beim committen eines guten Standes, der angetestet ist, ein kleines batch laufen lassen, das die exes lokal kopiert mit Datumskennzeichnung.
  • Damit sind mehrere exes mit Datumsverbindung zum commit lokal vorhanden. Es kann getestet werden.
  • Auslieferung: Executables und ggf. libs als zip abspeichern,, siehe oben. Dabei auf den Stand zugreifen, der vorher lokal kopiert wurde und garantiert aus den Sources, die committed wurden, erstellt wurde.
  • Nur bei Master-Releases, die entgültig ausgeliefert werden, sollte folgeder Aufwand getrieben werden: Nach erfolgreichem Test die Quellen auf Produktgenerierungsrechner von anderer Person auschecken, neu compilieren, neues Generat erstellen und nochmals testen. Diese Vorgehensweise sichert die Konsistenz der Quellen mit dem Generat und dürfte bei Auslieferungen wichtig sein, dauert aber in der täglichen Fortschrittsarbeit einfach zu lange.


[edit] Archivierung der Datenbasis des SCM

Die Datenbasis besteht aus Files, die in üblicher Art als File-Bündel archiviert und restauriert werden können.


[edit] Mehrere Produkte aus einem Repository

@ident=SCM-Cmpn-de

Das große Thema ist Wiederverwendung (Reuse). Häufig zu Beobachten: Reuse besteht aus copy'n paste and change. Die Quellen wandern also irgendwo anders hin, bzgl SCM auch für den einzelnen besser zu beherrschen - man muss sich nur mit dem beschäftigen, was man selbst hat.

Das ist keine wirkliche Wiederverwendung. Der wirkliche Vorteil des reuse geht dabei verloren:

  • Fehler, die in Produkten festgestellt werden, werden in den jeweiligen Modulen korrigiert und sind dann automatisch auch für andere Produkte mit korrigiert, obwohl sie dort ggf. noch gar nicht aufgefallen sind.

Für true-reuse ist es notwendig, die Software-Module so zu bauen, dass sie unverändert in verschiedenen Produkten verwendbar sind und das Änderungen für alle Produkte nutzbar sind. Das ist eine Frage der Schnittstellen. Die Schnittstellen sind viel wichtiger als die innere Funktionalität. Letztere kann man immer noch verbessern. Schnittstellenänderungen sind kritisch. - Andererseits sind Schnittstellenänderungen auch verträglich, wenn sie formell adaptiert werden können.

Ein shared-Repository in bazaar scheint die Lösung zu bieten, aus einem recht großen Quellenumfang für verschiedene Komponenten verschiedene Quellen herauslösen zu können. Die Komponenten haben selbe gemeinsame Quellen, ggf. in verschiedenen Revisionen, die aber immer abgeglichen werden können sollten. Die Komponenten sind dann Basis für ein Produkt. Komponenten existieren in Form von libs oder jars in Java und können eigenständig getestet werden:


 Quellen           Komponenten           Produkte
 viele        ===> weniger Details  ===> aus Komponenten
 verschiedene      überschaubarer        und Produkt-spezial-Quellen
                                         gebaut.

Wie funktioniert shared-Repository als zentraler Bezug - bin beim testen. (Hartmut)

[edit] Zentrale Ablage für Repositories

@ident=SCM-centralRepos-de

Man kann immer und überall Repositories haben. Behält man den überblick und synchronisiert diese gegenseitig (push, pull), dann gibt es auch nicht zuviele Seitenzweige.

Jedoch, arbeiten viele Leute mit den Repositories, auch weniger eingeweihte, einfache Nutzer, anderes Problem Archivierung, langjähriges aufheben: Dann sollte an einer definierten Stelle das Master-Repository stehen. Jeder Quellenbearbeiter hat die Pflicht, sich mit dem Master-Repository abzustimmen, also seine Änderungen zu pushen oder von dort zu pullen. Gegebenenfalls sollte eine Person mit der Pflege des Master-Repositories beauftragt sein. Mindestens bei Releaseständen muss diese Person dort bereinigend eingreifen.

[edit] Creating one shared repository in the local space

The local space means any external hard disk, network folder or such which is owned by one person, by me. It is my local space, which can be used from some more people in my direct environment.

For any component of sources one shared repository should be created one time. On one sub directory per component: bzre: Bazaar -> Start -> Initialize: (x) Shared repository. An existing plain branch can be pushed to them.

[edit] Creating a branch for working

  • Create a new plain branch at the working position: bzre: Bazaar -> Start -> Initialize: (x) Plain branch.
  • Pull from a shared repositiory: Button Pull, select the shared repository, select a branch.
    • If there are some files already, create the branch at a new position and then move .bzr subdir.

[edit] Branches und dessen Auflösung

@ident=SCM-sidebranch-en

Viele Seitenzweige wegen unterschiedlichen Korrekturen
Man kann sich auf den Standpunkt stellen, bei Korrekturen für kundenrelevante Software jeweils nur das aufgetretene Fehlerbild zu behandeln, alle anderen Softwareteile unverändert zu lassen. (Do not touch a running system). Das ist eine weit verbreitete Vorgehensweise. Folge sind dann sehr viele Seitezweige, die kaum mehr zusammenfließen.
Primär ist diese Vorgehensweise richtig.
Es zeigt sich aber, dass eine Änderung in Quellen, auch Restrukturierung, häufig zwar Nacharbeiten erforderlich macht. Diese Nacharbeiten sind aber formal abhandelbar. Man braucht nicht an jeder Stelle einer notwendigen Adaption an geänderte Quellenstände nachzudenken sondern muss nur den Compiler befragen. Kommt keine Fehlermeldung, ist alles in Ordnung. Eine Fehlermeldung soll mit formellen anschauen von Aufrufargumenttypen usw. behebbar sein, ohne dass man in die eigentliche Funktionalität einsteigt. Ist eine solche Nacharbeit möglich, dann kostet diese nur die Zeit der Pflege der Quellen, keine extra Testzeit. Zudem kann die Quellenpflege von jemanden ausgeführt werden, der zwar sehr gute Kenntnisse von Quellen und COmpiler hat, aber keine Tiefenkenntnis für die jeweilige Anwendung haben braucht. Man kann also delegieren.
In diesem Sinn ist eine Adaption eines Produktes an veränderte Quellen der Komponenten möglich und zweckmäßig. Mann kann dann eher an einem Hauptzweig arbeiten.
Schlussfolgerung: Schnelle Änderungen ->Seitenzweig, Auflösen dessen, Änderung in Hauptzweig einfließen lassen und Adaption des Produktes auf Hautpzweig der Komponenten ausführen.
Personal tools