バージョン管理で同じコードベースから2つの異なるソフトウェアバージョンを維持する


45

同じソフトウェア/プログラム/アプリ/スクリプトの2つの異なるバージョンを作成し、バージョン管理下に保存しているとしましょう。最初のバージョンは無料の「ベーシック」バージョンで、2番目は有料バージョンの「プレミアム」バージョンで、無料バージョンのコードベースを取得し、いくつかの付加価値機能で拡張します。新しいパッチ、修正、または機能は、両方のバージョンへの道を見つける必要があります。

現在、有料版のサイドとブランチに沿って、メインコードベース(無料版)のブランチを使用することmasterを検討していdevelopます。無料版に変更が加えられ、ブランチにマージされると(もちろん徹底的なテストの後)、さらにテストするためにコマンドを介してブランチにコピーされ、にマージされます。master-premiumdevelop-premiummasterdevelopdevelop-premiumcherry-pickmaster-premium

これは、この状況を処理するのに最適なワークフローですか?認識すべき潜在的な問題、警告、または落とし穴はありますか?私がすでに思いついたものよりも良い分岐戦略がありますか?

あなたのフィードバックは大歓迎です!

PSこれはGitに保存されているPHPスクリプト用ですが、回答はすべての言語またはVCSに適用する必要があります。

回答:


83

共通のベースを持つ2つのコードバージョンを使用する代わりに、これらのプレミアム機能をプラグ可能にし、異なるコードベースではなく構成によって駆動するようにアプリケーションを設計する必要があります。

基本バージョンでこれらのプレミアム機能(構成により無効)を出荷することを恐れている場合でも、最終ビルド/パッケージング手順でそのコードを削除し、2つのビルドプロファイルのみを保持できます。

このデザインを使用すると、5種類のフレーバーを出荷し、非常に柔軟になり、サードパーティが貢献することもできます。


2
はい、これは私が寝る前に昨夜考え始めたことです。ありがとう!
ジョセフリーディ14年

3
現代のWindowsはこのように設計されており、すべてのバージョンにすべて同じコードがあり、使用中のライセンスキーに応じてロック解除される機能があります。
Mooingダック14年

39

この目的でブランチを使用しないことを強くお勧めします。一般に、後で再びマージされる(またはマージされる可能性のある)ブランチ(またはブランチの1つの開発を最終的に停止するリリースブランチ)のブランチを検討する必要があります。あなたの場合、「基本」バージョンと「プレミアム」バージョンをマージすることはありません。これらは両方とも無期限に維持されるため、ブランチは適切ではありません。

代わりに、ソースコードの1つの共通バージョンを維持し、条件付きコンパイル(たとえば#ifdef、C / C ++では、PHPに相当するものがわからない)を使用して、「基本」と「プレミアム」で異なるコードのセクションを含めたり除外したりします。

PHPにはそのような条件付きコンパイル機能が組み込まれていないように見えるため、Cプリプロセッサ(cpp、おそらく既に持っている)を使用して共通のソースコードを前処理し、そこから「基本」および「プレミアム」を生成できますプリプロセッサディレクティブのないバージョン。もちろん、これを行うことを選択した場合はmake、プリプロセッサを実行するプロセスを自動化するために、または同様のものを使用する必要があります。


ブランチについてあなたが言っていることは全く理にかなっています!代わりに、Premiumコードのみを含む別のリポジトリを作成し、何らかのリリーススクリプトまたはサブモジュールを使用してベースコードと組み合わせることができますか?これは、困難TDDを作るかもしれませんが...
ジョセフLeedy

14
別のリポジトリを作成することは、ブランチを作成することよりもさらに悪いです!間違いなく、バージョン管理されたコードの重複が最も少ないソリューションを選択する必要があります。
グレッグヒューギル14年

2
2番目のレポのポイントは、アプリ全体の別のコピーではなく、追加のコードだけを格納することです。
ジョセフリーディ14年

1
ああ、それはもっと基本的なコードがプラグインをロードして実行する機能を持っている「プラグイン」モデルに似ているでしょう(存在する場合)。プラグインコードは独立しており、プレミアム機能を提供します。
グレッグヒューギル14年

4
@Joseph:2つのリポジトリの使用は、2つのコードベースのバージョン管理が互いにほぼ独立している場合にのみ適切です。そうでない場合は、Gregが書いたことを実行し、すべてを1つのリポジトリに保管することを強くお勧めします。私が考え直す唯一のことは、「Cプリプロセッサ」の使用です。(多少マークされた)プレミアム機能なしでコードのコピーを作成する、選択した言語(PHP自体は問題ありませんが、PerlまたはPythonはさらに良い)で書かれた小さなスクリプトがトリックを行うと思います。
ドックブラウン14年

8

基本プロジェクトと、基本プロジェクトに依存するプレミアムプロジェクトの2つの別個のプロジェクトを使用しています。ブラケットは使用しないでください。通常は、機能に使用されます。


ビルドスクリプトを使用して、基本プログラムとプレミアムプログラムの両方の作成を自動化できるため、これは魅力的です。
neontapir

1
一般的には、3つのプロジェクトが必要です。多くの場合、ライブラリとして編成される共通部分と、2つの異なるバージョンのカスタム部分です。
アンドリーティリチコ14年

3

現在のほとんどの答えはブランチではなく条件付きコンパイルを支持していますが、ブランチを使用することには明確な利点があるシナリオが1つあります。バージョン履歴がすべてのプレミアム機能を除外している場合、ブランチアプローチを使用することはできますが、単一のブランチと条件付きコンパイルを使用することはできません。

さくらんぼ狩りに反対し、代わりに基本バージョンからプレミアムバージョンにすべての変更をマージます。基本バージョンには含まれるが、プレミアムバージョンにはない機能またはバグ修正はありません。物事をできる限り簡単にするために、premiumブランチが共通ファイルをできるだけ変更しないようにする必要があります。そのため、プレミアムブランチには主に追加のファイルが含まれている必要があり、おそらくビルド手順に若干の変更が必要です。これにより、基本バージョンからの変更は、競合を引き起こすことなく自動的にマージされます。

Gregの回答は、「後で再びマージされる(またはマージされる可能性のある)ブランチを検討する」ことを示唆しています。先ほど説明したアプローチでは、これが事実です。ただし、すべてのコミットの最終ブランチはそうではありmaster-premiumませんmaster(実際にはそうですmaster-basic)。

もちろん、サブモジュールもオプションになります。ビルドプロセスに依存しますが、基本バージョンをモジュールとして使用するプロジェクトにプレミアムバージョンを作成できる場合は、問題ありません。ただし、ある時点で機能をプレミアムブランチからベーシックブランチにチェリーピッキングすることに決めた場合は、苦労するかもしれません。サブモジュールでは、このような変更は2つの別個のコミットとして表されますが、ブランチでは、これは基本バージョンへの単一コミットであり、プレミアムバージョンへの次回のマージでは、これらの変更がすでに含まれており、再びマージされます。


0

「ハードウェア」では、これは頻繁に行われます。これらは混乱を制御するために販売されているシステムです。

「ミッドレンジ」洗濯機が出荷されると、数か月後に出荷される「ローエンド」洗濯機で同じコードが変更された場合でも、非常に重要なバグ修正以外のコードは変更されません。

顧客はすでに持ってきた洗濯機へのアップグレードを期待していません。新しいモデルも数ヶ月ごとに出荷されません。

私たちのほとんどはその世界に住んでいないので、洗濯機用のソフトウェアを書いているのでない限り、グレッグが言うことをしてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.