Verwalten von zwei separaten Softwareversionen aus derselben Codebasis in der Versionskontrolle

45

Angenommen, ich schreibe zwei verschiedene Versionen der gleichen Software / des gleichen Programms / der gleichen App / des gleichen Skripts und speichere sie unter Versionskontrolle. Die erste Version ist eine kostenlose "Basic" -Version, während die zweite eine kostenpflichtige "Premium" -Version ist, die die Codebasis der kostenlosen Version übernimmt und um einige zusätzliche Mehrwertfunktionen erweitert. Alle neuen Patches, Fixes oder Features müssen in beide Versionen aufgenommen werden.

Ich erwäge derzeit die Verwendung masterund developVerzweigungen für die Hauptcodebasis (kostenlose Version) neben master-premiumund develop-premiumVerzweigungen für die kostenpflichtige Version. Wenn eine Änderung an der kostenlosen Version vorgenommen und in der masterVerzweigung zusammengeführt wird ( developnatürlich nach gründlichem Testen ), wird sie develop-premiumüber den cherry-pickBefehl zum weiteren Testen in die Verzweigung kopiert und dann in die Verzweigung zusammengeführt master-premium.

Ist dies der beste Workflow, um mit dieser Situation umzugehen? Gibt es potenzielle Probleme, Vorbehalte oder Fallstricke, die Sie beachten sollten? Gibt es eine bessere Verzweigungsstrategie als die, die ich mir bereits ausgedacht habe?

Ihr Feedback wird sehr geschätzt!

PS Dies ist für ein in Git gespeichertes PHP-Skript, aber die Antworten sollten für jede Sprache oder VCS gelten.

Joseph Leedy
quelle

Antworten:

83

Anstatt zwei Codeversionen auf einer gemeinsamen Basis zu haben, sollten Sie Ihre Anwendung so gestalten, dass diese Premium-Funktionen durch die Konfiguration und nicht durch unterschiedliche Codebasen bedient werden können.

Wenn Sie Angst haben, diese Premium-Funktionen (aufgrund der Konfiguration deaktiviert) mit der Basisversion auszuliefern, können Sie diesen Code in einem abschließenden Erstellungs- / Paketierungsschritt trotzdem entfernen und haben nur zwei Erstellungsprofile.

Mit diesem Design können Sie auch 5 verschiedene Geschmacksrichtungen ausliefern und sehr flexibel werden, möglicherweise können sogar Dritte einen Beitrag leisten.

OliverS
quelle
2
Ja, daran habe ich letzte Nacht gedacht, bevor ich ins Bett gegangen bin. Vielen Dank!
Joseph Leedy
3
Das moderne Windows ist so konzipiert, dass alle Versionen den gleichen Code haben und die Funktionen je nach verwendetem Lizenzschlüssel freigeschaltet sind.
Mooing Duck
39

Ich empfehle dringend, keine Zweige für diesen Zweck zu verwenden. Im Allgemeinen sollten Sie Zweige für Dinge in Betracht ziehen, die später wieder zusammengeführt werden (oder werden könnten) (oder für Release-Zweige, bei denen Sie schließlich die Entwicklung eines der Zweige stoppen). In Ihrem Fall werden Sie Ihre "Basic" - und "Premium" -Versionen niemals zusammenführen. Beide Versionen werden auf unbestimmte Zeit beibehalten, sodass Zweigstellen nicht geeignet sind.

Pflegen Sie stattdessen eine gemeinsame Version des Quellcodes und verwenden Sie die bedingte Kompilierung (z. B. #ifdefin C / C ++, nicht sicher, was das Äquivalent für PHP ist), um die Codeabschnitte einzuschließen oder auszuschließen, die sich zwischen "basic" und "premium" unterscheiden.

Es sieht so aus, als ob in PHP möglicherweise keine solche bedingte Kompilierungsfunktion eingebaut ist. Sie könnten also den C-Präprozessor verwenden ( cppwahrscheinlich haben Sie ihn bereits), um Ihren gemeinsamen Quellcode vorzuverarbeiten und daraus ein "Basic" und ein "Premium" zu erstellen. Version ohne die Präprozessor-Direktiven. Wenn Sie sich dazu entscheiden, sollten Sie natürlich makeden Prozess des Ausführens des Präprozessors mit oder ähnlichem automatisieren.

Greg Hewgill
quelle
Was Sie über Branchen sagen, ist absolut sinnvoll! Vielleicht könnte ich stattdessen ein separates Repo erstellen, das nur den Premium-Code enthält, und ein Release-Skript oder ein Submodul verwenden, um es mit dem Basiscode zu kombinieren? Dies könnte TDD jedoch schwieriger machen ...
Joseph Leedy
14
Das Erstellen eines anderen Repositorys ist noch schlimmer als das Erstellen von Zweigen! Sie möchten auf jeden Fall eine Lösung wählen, bei der der versionierte Code am wenigsten dupliziert wird.
Greg Hewgill
2
Der Sinn des zweiten Repos ist es, nur den zusätzlichen Code zu speichern - keine weitere Kopie der gesamten App.
Joseph Leedy
1
Ah, ich verstehe, das wäre eher das "Plugin" -Modell, bei dem Ihr Basiscode Plugins laden und ausführen kann (falls vorhanden). Der Plugin-Code ist separat und bietet die Premium-Funktionen.
Greg Hewgill
4
@Joseph: Die Verwendung von zwei Repos ist nur dann sinnvoll, wenn die Versionierung der beiden Codebasen nahezu unabhängig voneinander ist. Wenn das nicht der Fall ist, würde ich dringend empfehlen, das zu tun, was Greg geschrieben hat und alles in einem Repo zu behalten . Das einzige, was ich überdenken würde, ist die Verwendung des "C-Präprozessors". Ich denke, ein kleines Skript in der Sprache Ihrer Wahl (PHP selbst ist in Ordnung, Perl oder Python noch besser), das eine Kopie Ihres Codes ohne die (irgendwie markierten) Premium-Funktionen erstellt, würde den Trick tun.
Doc Brown
8

Wir verwenden zwei separate Projekte, das Basic-Projekt und das Premium-Projekt, die vom Basic-Projekt abhängen. Verwenden Sie keine Braches, sie werden normalerweise für Features verwendet.

Silviu Burcea
quelle
Das gefällt mir, weil Sie mit Ihrem Build-Skript die Erstellung von Basis- und Premium-Programmen automatisieren können.
Neontapir
1
Im Allgemeinen benötigen Sie drei Projekte: einen gemeinsamen Teil, der häufig als Bibliothek organisiert ist, und benutzerdefinierte Teile für zwei verschiedene Versionen.
Andriy Tylychko
3

Während die meisten aktuellen Antworten eine bedingte Kompilierung anstelle von Verzweigungen befürworten, gibt es ein Szenario, in dem die Verwendung von Verzweigungen einen eindeutigen Vorteil bietet: Wenn Sie (jetzt oder später) entscheiden, den Quellcode der Basisversion einschließlich aller zur Verfügung zu stellen Versionshistorie, jedoch ohne alle Premium-Funktionen, dann können Sie dies mit dem Branches-Ansatz tun, jedoch nicht mit einem einzigen Branch und einer bedingten Kompilierung.

Ich würde vom Kirschpflücken abraten und stattdessen alle Änderungen von der Basisversion in die Premiumversion übernehmen. Es sollte keine Funktion oder Fehlerbehebung im Basic enthalten sein, aber in der Premium-Version fehlen. Um die Arbeit so einfach wie möglich zu gestalten, sollten Sie sicherstellen, dass der Premium-Zweig die allgemeinen Dateien so wenig wie möglich ändert. Daher sollte der Premium-Zweig meistens zusätzliche Dateien und möglicherweise einige geringfügige Änderungen zur Erstellung von Anweisungen enthalten. Auf diese Weise werden Änderungen gegenüber der Basisversion automatisch zusammengeführt, ohne dass Konflikte auftreten.

Gregs Antwort schlug vor, dass Sie "Zweige für Dinge in Betracht ziehen, die später wieder zusammengeführt werden (oder werden könnten)". Bei dem Ansatz, den ich gerade beschrieben habe, ist dies der Fall, mit der Ausnahme, dass der letzte Zweig für alle Festschreibungen master-premiumnicht ist master(was tatsächlich der Fall ist master-basic).

Selbstverständlich sind auch Submodule möglich. Es hängt von Ihrem Build-Prozess ab, aber wenn Sie die Premium-Version in ein Projekt umwandeln können, das die Basisversion als Modul verwendet, ist das in Ordnung. Es könnte Ihnen jedoch schwerer fallen, wenn Sie sich irgendwann dazu entschließen, Funktionen aus der Premium-Branche in die Basisbranche zu verschieben. Bei Untermodulen würde eine solche Änderung als zwei unterschiedliche Festschreibungen dargestellt, wohingegen bei Zweigen dies eine einzelne Festschreibung für die Basisversion wäre, und die nächste Zusammenführung in die Premiumversion würde wissen, dass diese Änderungen bereits enthalten sind und nicht enthalten sind wieder zusammengeführt werden.

MvG
quelle
0

In "Hardware" wird dies oft gemacht, es handelt sich um Systeme, die verkauft werden, um das Durcheinander zu kontrollieren. Tut mir leid, ich kann mich nicht erinnern, wie sie genannt werden.

Sobald die Waschmaschine der mittleren Preisklasse ausgeliefert wird, ändert sich ihr Code nur noch für eine sehr wichtige Fehlerbehebung, selbst wenn derselbe Code in der Waschmaschine der unteren Preisklasse geändert wird, die einige Monate später ausgeliefert wird.

Kunden erwarten keine Upgrades für eine bereits mitgebrachte Waschmaschine, ein neues Modell wird auch nicht alle paar Monate ausgeliefert.

Die meisten von uns leben nicht in dieser Welt, also tun Sie, was Greg sagt, es sei denn, Sie schreiben Software für Waschmaschinen.

Ian
quelle