Ich bin ein weiterer Subversion-Benutzer, der Mühe hat, sich in das Tao der verteilten Versionskontrolle einzuarbeiten.
Bei der Verwendung von Subversion war ich ein großer Fan des Projekt-Minor-Ansatzes, und mit den meisten meiner früheren Arbeitgeber haben wir unsere Repository-Filialen strukturiert. Tags & Trunk wie folgt:
branches-+
+-personal-+
| +-alice-+
| | +-shinyNewFeature
| | +-AUTOMATED-+
| | +-shinyNewFeature
| +-bob-+
| +-AUTOMATED-+
| +-bespokeCustomerProject
+-project-+
+-shinyNewFeature
+-fixStinkyBug
tags-+
+-m20110401_releaseCandidate_0_1
+-m20110505_release_0_1
+-m20110602_milestone
trunk
Innerhalb des eigentlichen Quellbaums würden wir (so etwas wie) die folgende Struktur verwenden:
(src)-+
+-developmentAutomation-+
| +-testAutomation
| +-deploymentAutomation
| +-docGeneration
| +-staticAnalysis
| +-systemTest
| +-performanceMeasurement
| +-configurationManagement
| +-utilities
+-libraries-+
| +-log-+
| | +-build
| | +-doc
| | +-test
| +-statistics-+
| | +-build
| | +-doc
| | +-test
| +-charting-+
| | +-build
| | +-doc
| | +-test
| +-distributedComputing-+
| | +-build
| | +-doc
| | +-test
| +-widgets-+
| +-build
| +-doc
| +-test
+-productLines-+
| +-flagshipProduct-+
| | +-coolFeature
| | +-anotherCoolFeature
| | +-build
| | +-doc
| | +-test
| +-coolNewProduct
+-project-+
+-bigImportantCustomer-+
| +-bespokeProjectOne
| +-bespokeProjectTwo
+-anotherImportantCustomer-+
+-anotherBespokeProject
Die Idee war (und ist), die Struktur des Repositorys zu verwenden, um die Kommunikation zwischen dem Engineering-Team zu strukturieren. der kundenorientierte Teil des Geschäfts und verschiedene andere Stakeholder und Domain-Experten.
Übrigens: Quelldokumente, die sich in einem der "Projekt" -Verzeichnisse befinden, werden nur einmal verwendet (und verdienen Geld). Dokumente, die sich in einem der "productLines" -Verzeichnisse befinden, verdienen so viel Geld, wie ein Produkt aus dieser bestimmten Zeile verkauft wird. Dokumente, die sich in einem der "Bibliotheks" -Verzeichnisse befinden, verdienen so viel Geld, wie Produkte, die sie verwenden, verkauft werden.
Der Begriff der Amortisation von Kosten wird explizit erwähnt, und es wird eine Unterstützung für die Wiederverwendung von Quelldokumenten im gesamten Unternehmen geschaffen.
Dies bedeutet auch, dass es eine gemeinsame Struktur gibt, über die unsere Build-Automatisierungstools arbeiten können. (Unsere Build-Skripte durchsuchen den Quellbaum nach "Build" -Ordnern, in denen sie Konfigurationsdateien finden, die angeben, wie die einzelnen Komponenten erstellt werden sollen. Ein ähnlicher Prozess wird für die Dokumentationserstellung und das Testen ausgeführt.)
Bezeichnenderweise benötigen die Produkte, an denen ich arbeite, in der Regel eine LANGE Zeit, um Leistungstests und Charakterisierungstests durchzuführen. von 20 bis 200 Stunden; Generieren von verarbeiteten Testergebnissen / Zwischendaten zwischen mehreren GB und mehreren TB (die gespeichert und an eine bestimmte Systemkonfiguration gebunden werden müssen, damit die Leistungsverbesserung im Laufe der Zeit gemessen werden kann). Dieses Problem macht das Konfigurationsmanagement zu einer wichtigen Überlegung und macht auch eine Zentralisierung erforderlich, da in der Regel nur begrenzte Rechenressourcen zum Ausführen der Leistungsmessung und der Charakterisierungstests erforderlich sind. (eine kleine Gruppe von 64-128 Kernen).
Als eine letzte Anmerkung; Das kontinuierliche Integrationssystem weiß, dass es einen Build auslösen muss. statische Analyse; Rauch- und Einheitentestlauf bei jeder Änderung des Trunks, bei jeder Änderung eines "Tag" -Zweigs und bei jeder Änderung eines "AUTOMATISIERT" -Zweigs. Auf diese Weise können einzelne Entwickler das CI-System mit ihren persönlichen Filialen nutzen, eine wichtige Funktion, IMHO.
Hier ist meine Frage: Wie kann ich all das oben Genannte mit Mercurial nachbilden (und es, wenn möglich, verbessern)?
--bearbeiten:
Meine derzeitige Denkweise besteht darin, ein zentrales Subversion-Repository zu verwenden, um die Gesamtstruktur zu definieren, aber die Verwendung von hg als Client zuzulassen, damit Entwickler Repos lokal verfügbar haben.
quelle
Antworten:
Die Antwort von Spoike ist ausgezeichnet, aber ich denke, es gibt ein paar Dinge, die es wert sind, hinzugefügt zu werden, die zu groß für Kommentare sind.
Branchenorganisation
Mit Mercurial können Sie das gesamte erste Organigramm ignorieren. Wie Spoke sagt, hat jedes Repository einen eigenen Satz von Tags, Zweigen (benannt und anonym) und kann entsprechend den geschäftlichen Anforderungen organisiert werden.
Wenn
bespokeProjectTwo
eine spezielle Version dercharting
Bibliothek benötigt wird, können Sie verzweigencharting
, die neuen Funktionen hinzufügen und diese in verwendenbespokeProjectTwo
. Die neuen Einrichtungen (und ihre Fehler) würden nicht von anderen Projekten verwendet, die auf die Standardbibliothek verweisen würdencharting
. Wenn in dercharting
Hauptbibliothek Fehler behoben wurden, können Sie diese Änderungen in den Zweig einfügen. Wenn diese Einrichtungen auch für andere Projekte erforderlich sind, können Sie diese Projekte entweder dazu bringen, den speziellen Zweig zu verwenden, oder den Zweig in der Hauptlinie zusammenführen und den Zweig schließen.Es steht auch nichts mehr im Wege, wenn Sie eine Richtlinie zum Strukturieren von Filialnamen haben, um bestimmte Funktionen wie Ihre AUTOMATION-Filialen bereitzustellen.
Verzeichnisorganisation
Es gibt keinen Grund, warum Sie Ihr Quellverzeichnis nicht genau so behalten können wie bei Mercurial. Der einzige Unterschied besteht darin, dass Sie mit Subversion ein einziges monolithisches
(src)
Repository haben, während Sie mit Mercurial besser in Repositorys aufteilen, die logisch gruppiert sind. Aus Ihrer Quelltextstruktur würde ich wahrscheinlich jedes der folgenden Elemente als einzelne Repositorys extrahieren:Auf diese Weise kann jedes Produkt oder maßgeschneiderte Projekt bei jeder Überarbeitung eine beliebige Kombination von Bibliotheken verwenden. Schauen Sie sich die mercurial-Unter-Repositorys an, um auf einfache Weise zu verwalten, welche Bibliotheken für eine bestimmte Version eines Produkts oder Projekts verwendet werden.
Arbeitsablauf
Eine Alternative zum von Spoike vorgeschlagenen Workflow (der Entwickler greift auf das gesegnete Repo zurück, arbeitet lokal, gibt eine Abrufanforderung aus und schließlich zieht der Integrator diese Änderungen ab und führt sie zusammen) wäre die Verwendung des kontinuierlichen Integrationssystems als Vermittler.
Wie zuvor zieht der Entwickler aus dem gesegneten Repo und arbeitet lokal, aber wenn er fertig ist, zieht er erneut aus dem gesegneten Repo und verschmilzt sich, bevor er zu einem nicht gesegneten Repo wechselt. Alle Änderungen am nicht gesegneten Repo werden dann (entweder manuell oder automatisch) überprüft und nur dann in das gesegnete Repo verschoben, wenn sie genehmigt wurden.
Dies bedeutet, dass der Integrator nur eine Änderung akzeptieren oder ablehnen muss, nicht aber die Zusammenführung. Meiner Erfahrung nach ist es für den Entwickler, der den Code geschrieben hat, fast immer besser, die Zusammenführung durchzuführen, als für einen anderen.
Wie im Mercurial-Buch vorgeschlagen, können Hooks verwendet werden, um diesen Vorgang zu automatisieren:
Andere Probleme
Das Problem großer Testdatensätze kann auch dadurch gelöst werden, dass diese Testdaten in ein Quecksilber-Sub-Repository gestellt werden . Dadurch wird verhindert, dass das Code-Repository mit Testdaten überfüllt wird, während die Testdaten weiterhin unter Versionskontrolle bleiben.
quelle
productLines
oderbigImportantCustomer
als Super-Repos.Okay, versuche das einfach zu beantworten.
Was du wissen musst
Das erste, was Sie wissen müssen: Mercurial ist eine verteilte Versionskontrolle und verfügt über einige Eigenschaften, die Sie kennen sollten.
Das übliche Modell, mit dem die Leute in DVCS (das in Github und Bitbucket verwendet wird) arbeiten, ist es, es semi-zentral zu machen.
Jeder Benutzer verfügt über ein öffentliches Repository (in einer Freigabe oder auf einem sicheren Server) und ein privates Repository (auf seinen eigenen Arbeitsstationen). Sie sind beide Klone des "gesegneten" Repository eines Integrators. Wann immer sie sich bereit fühlen, ihren Code zu veröffentlichen, können sie die Änderungen in ihr öffentliches Repository übertragen. Ein Integrator kann dann auswählen, welche Benutzer Code in das "gesegnete" Repository ziehen sollen.
Wenn der Integrator den Code eines Benutzers nicht einfach zusammenführen kann, werden die Änderungen verworfen, und es liegt an diesem bestimmten Benutzer, sein Repository zu aktualisieren und die Zusammenführung selbst zu beheben. Es ist normalerweise nicht so schwierig, wenn Sie häufig zusammenführen (da weniger Code zusammengeführt werden muss), und normalerweise sollte der Benutzer wissen, was bei der Zusammenführung schief gelaufen ist.
Projektarchiv-pro-Projekt-Setup
So ist die übliche Einstellung, dass es für jedes Projekt die folgenden gibt:
Ein öffentliches schreibgeschütztes Repository, für das der Integrator verantwortlich ist. Es ist "gesegnet".
Dh alle Benutzer können Inhalte abrufen / abrufen, haben jedoch keinen Zugriff darauf.
Jeder Benutzer kann einen eigenen öffentlichen Klon des Repositorys haben.
Am einfachsten lässt es sich auf einem freigegebenen Laufwerk einrichten (auch wenn Sie eventuell ein Hosting wie bitbucket in Betracht ziehen). Der Integrator empfängt Pull-Anforderungen von den Benutzern und versucht, den neuen Code aus diesen Repositorys abzurufen. Wenn Zusammenführungen problemlos durchgeführt werden, werden sie in das schreibgeschützte Repository gestellt. Ist dies nicht der Fall, werden Benutzer aufgefordert, die Zusammenführungskonflikte zu beheben, die durch das lokale Aktualisieren und Zusammenführen entstehen.
Jeder Benutzer kann seine eigenen privaten Klone des Repositorys haben.
Es hat sich bewährt, von ihrem öffentlichen Klon abzurufen, aber es spielt keine Rolle, ob sie von ihrem öffentlichen Klon oder dem des Integrators abrufen. Alle Festschreibungen sind eindeutig identifizierbar, so dass das Zusammenführen von Festschreibungen, die Sie in der Öffentlichkeit vergessen haben, relativ einfach zu beheben ist (indem Sie die Änderungen von privat an öffentlich weitergeben, werden auch die Änderungen des Integrators automatisch übernommen).
Organisation des Quellcodes
Wie man die Projektquelle selbst arrangiert, muss man sich überlegen. Wenn ein Artefakt einer Quellcodeverwaltung unterzogen werden muss, versetzen Sie es in die Quellcodeverwaltung. Persönlich mag ich es nicht, Artefakte einzuchecken, die während des Builds oder der Laufzeit erstellt wurden (aufgrund des hohen Risikos von Zusammenführungskonflikten bei solchen Artefakten), wie z. B. Binärdateien oder Protokolldateien.
Sie können auch die Konfiguration einchecken, sofern dies Entwicklern den Einstieg erleichtert und die Konfiguration für Releases oder Live- / Produktionsumgebungen (z. B. App- / Webserver-Einstellungen) nicht beeinträchtigt. Dies führt zu dem Gedanken, dass, wenn die Konfiguration, die Sie vorgenommen haben, die Entwickler ernsthaft daran hindert, innerhalb von fünf Minuten nach dem Auschecken des Codes zu beginnen, dieser überarbeitet werden muss. Eine weitere Anforderung ist, dass es für die Entwickler verdammt schwierig sein sollte, die Release- oder Live- / Produktionsumgebung durcheinander zu bringen.
Sie erwähnen, dass Sie Testdaten haben, die an eine Version des Codes gebunden werden müssen. Das ist etwas kniffliger, da DVCS-Systeme wie Mercurial und Git dazu neigen, beim Einchecken von riesigen Daten langsam zu werden. Nach meiner Erfahrung wird es nach 5 GB Binärdateien wirklich unerträglich (Ihre Laufleistung kann variieren, Sie sollten also testen, wie es für Sie funktioniert). Ich würde jedoch empfehlen, dass Sie generierte Daten in einem eigenen Repository ablegen und sie beim Einchecken von Ihrem Testsystem entsprechend kennzeichnen lassen (und / oder Textdateien für dieselben Metadatenzwecke erstellen).
Ich hoffe das alles macht Sinn. Bitte kommentieren Sie unten, wenn ich ein Detail verpasst habe oder wenn etwas näher erläutert werden muss, und ich werde versuchen, es zu bearbeiten.
quelle