GIT :在单个存储库中处理同一软件的多个变体
GIT : Handle multiple variations of th same sofware in a single repo
我和我的团队同时处理多个项目,但他们都使用相同的代码库,并且需要针对每个项目进行调整。
例如,我们有包含组件 A 和 B 的基本代码。对于每个新项目,我们必须修改 B,但 A 保持不变。
目前,我们每个项目都有一个 GIT 存储库,但有时我们会在 A 中发现一个问题,我们必须在所有项目中修复该问题.所以我们正在考虑将我们所有的项目放在同一个 repo 中并使用分支来管理它们的可能性,以简化对公共组件的更正。
我一直在寻找涵盖这种代码管理的工作流(gitflow、github flow、gitlab flow...),但我没有找到符合我们需求的东西。
在同一存储库中管理代码库的不同变体是个坏主意吗?
如果没有,是否有我可能没有发现适合这种应用程序的工作流程?还是我们只使用标准工作流程并将所有项目分支视为单个存储库?
在此先感谢您的帮助!
剂量
管理同一个 repo 的多个版本可能是个好主意,这取决于具体的代码库、目标和选择的方法。理想情况下,您希望封装核心功能,以便有一个始终相同的层,然后有不同的高级层并访问核心层。
如何实现这一点有无数种选择,我想简单地提一下:
- 使用
git
:一个选项是在存储库 X
中拥有不变的核心功能,然后将此存储库动态导入到您其他项目的存储库中。这种功能的一个主要例子是 Git 子模块
- 使用依赖注入:根据项目的语言,有 DI 框架,例如
Dagger 2
。您可以使用所有代码维护一个单独的存储库,然后使用 DI 框架动态加载 classes 以进行所需的更改
- 一个示例可能会有所帮助:假设有一个 UI class
A
。此 class 取决于模型 class B
或 C
,具体取决于您要构建的应用程序的变体。 B
或 C
都取决于 class D
,这是您不变的核心功能。在这种情况下,可以让 Dagger 处理依赖注入并提供 B
或 C
- https://dagger.dev/
- 您可以使用专用的构建工具,例如 Gradle 或 Maven。可以定义整个构建管道,这样您就可以将所有代码库保存在一个存储库中,并根据您打算构建的版本执行特定的构建管道。
- 另一种可能性是使用 Jenkins 之类的东西为每个相应的应用程序版本定义单独的构建管道。这本质上只是前面提到的方法的变体,但使用了更通用的工具
您可能需要重构您的代码库以干净地利用这两种方法中的任何一种,但是为了避免 运行 迅速陷入技术债务是非常值得的。
不要做
你不想在任何情况下都想做的是复制代码库,只需稍作改动,然后将其全部放入不同的存储库中。
我实际上已经亲眼目睹了这种方法的实际应用 - 它会在您的脸上爆炸。您最终会维护多个相似但在某种程度上不同的代码库。由于时间限制,来自 A
的改进很可能并不总是进入 B
,反之亦然,您最终会多次执行相同的工作。也很难跟踪任一代码库的状态。
我认为分支的标准行为是选择的手段。这可以用来进化A并作为B的基础。
你看过tags的概念吗?这是一种为提交分配唯一标识符的方法。如果你使用这个,例如在 A 中,然后您可以在派生分支中看到您的功能 B 基于 A 的哪个基础。
我和我的团队同时处理多个项目,但他们都使用相同的代码库,并且需要针对每个项目进行调整。
例如,我们有包含组件 A 和 B 的基本代码。对于每个新项目,我们必须修改 B,但 A 保持不变。
目前,我们每个项目都有一个 GIT 存储库,但有时我们会在 A 中发现一个问题,我们必须在所有项目中修复该问题.所以我们正在考虑将我们所有的项目放在同一个 repo 中并使用分支来管理它们的可能性,以简化对公共组件的更正。
我一直在寻找涵盖这种代码管理的工作流(gitflow、github flow、gitlab flow...),但我没有找到符合我们需求的东西。
在同一存储库中管理代码库的不同变体是个坏主意吗? 如果没有,是否有我可能没有发现适合这种应用程序的工作流程?还是我们只使用标准工作流程并将所有项目分支视为单个存储库?
在此先感谢您的帮助!
剂量
管理同一个 repo 的多个版本可能是个好主意,这取决于具体的代码库、目标和选择的方法。理想情况下,您希望封装核心功能,以便有一个始终相同的层,然后有不同的高级层并访问核心层。
如何实现这一点有无数种选择,我想简单地提一下:
- 使用
git
:一个选项是在存储库X
中拥有不变的核心功能,然后将此存储库动态导入到您其他项目的存储库中。这种功能的一个主要例子是 Git 子模块 - 使用依赖注入:根据项目的语言,有 DI 框架,例如
Dagger 2
。您可以使用所有代码维护一个单独的存储库,然后使用 DI 框架动态加载 classes 以进行所需的更改- 一个示例可能会有所帮助:假设有一个 UI class
A
。此 class 取决于模型 classB
或C
,具体取决于您要构建的应用程序的变体。B
或C
都取决于 classD
,这是您不变的核心功能。在这种情况下,可以让 Dagger 处理依赖注入并提供B
或C
- https://dagger.dev/
- 一个示例可能会有所帮助:假设有一个 UI class
- 您可以使用专用的构建工具,例如 Gradle 或 Maven。可以定义整个构建管道,这样您就可以将所有代码库保存在一个存储库中,并根据您打算构建的版本执行特定的构建管道。
- 另一种可能性是使用 Jenkins 之类的东西为每个相应的应用程序版本定义单独的构建管道。这本质上只是前面提到的方法的变体,但使用了更通用的工具
您可能需要重构您的代码库以干净地利用这两种方法中的任何一种,但是为了避免 运行 迅速陷入技术债务是非常值得的。
不要做
你不想在任何情况下都想做的是复制代码库,只需稍作改动,然后将其全部放入不同的存储库中。
我实际上已经亲眼目睹了这种方法的实际应用 - 它会在您的脸上爆炸。您最终会维护多个相似但在某种程度上不同的代码库。由于时间限制,来自 A
的改进很可能并不总是进入 B
,反之亦然,您最终会多次执行相同的工作。也很难跟踪任一代码库的状态。
我认为分支的标准行为是选择的手段。这可以用来进化A并作为B的基础。
你看过tags的概念吗?这是一种为提交分配唯一标识符的方法。如果你使用这个,例如在 A 中,然后您可以在派生分支中看到您的功能 B 基于 A 的哪个基础。