使用 Git 管理多个客户端的主分支中的多个分支



我有一个主资料库,其中包含我开发的站点,我希望此主资料库包含我正在处理的产品的基本通用内容。此主资料库将用作将由多个客户端使用的站点的起点。 这些客户端中的每一个显然都有不同的设置(例如数据库连接,也许还有品牌),但将来也可能包含自定义功能。

我想做的是拥有主存储库,然后从主分支分叉每个客户端,然后对这些分叉进行任何类型的自定义。 所以它看起来像:

主人   A公司    B公司    C公司

我主要关心的问题之一是如何同步更改? 我不认为客户端的分叉中会有会影响主节点的更改,但是对主节点的更改肯定会影响分支。 这会是一场巨大的噩梦吗? 这是处理这种情况的最佳方式吗?

我会使用变基。此命令将分支倒退到它与主节点的分集点,然后在其上重播更改。假设你有这个(从手册页借来的ascii艺术):

      A---B---C company_a
     /
D---E---F---G master

这样做:

git checkout company_a
git rebase master

你会留下这个。

              A'--B'--C' company_a
             /
D---E---F---G master

所有这些都是自动完成的。如果发生冲突,git 将暂停变基并允许您解决它。比较以查找冲突,然后

git add conflicting_file
git rebase --continue

或者用:

git rebase --abort

这只是一个摘要,全部在手册页中。

我经历过这种情况,这是一个令人难以置信的混乱。通常发生的事情是,您的工作流程最终会变成:忘记最近的客户端的主分叉。然后,它变得古怪变成了一场噩梦。

我强烈建议重构代码,将内容拆分为 2 个独立的 git 模块,一个"核心"模块和一个(每个)公司特定的代码。不知道您的回购的确切性质,很难说。我已经在工作中看到过,拆分模块比存储库中的一堆客户分支更易于管理。

我认为这里最好的选择是使用子模块。为每个客户创建一个存储库,其中包含每个客户的内容,并将公共核心存储库添加为每个客户的子模块。可能需要重新排列子目录等,但这将允许您开发共同核心并按照自己的时间表升级每个客户。一个缺点是它占用了更多磁盘空间用于所有额外的子模块副本 - 这可以通过使用git共享对象存储功能来部分缓解,而且磁盘空间无论如何都非常便宜。

您可能可以通过按客户分支的方法在单个存储库中完成您想要的内容,但是保持所有分支笔直并确保您不会意外交叉合并或其他东西,则需要谨慎。

我尝试过的,它的工作原理是为您的产品代码提供一个存储库例如product_x.您为每个客户端分叉它,从而产生单独的存储库,如下所示:

product_x_company_aproduct_x_company_bproduct_x_company_c

由于拉取请求不允许从父级到子级,

而只允许从子级到父级,因此我们必须遵循不同的路线。

我在本地所做的是在每个公司存储库中添加,例如product_x_company_a 除了origin有自己的存储库 URL 之外,还parent指向product_x存储库

git remote add parent https://github.com/ourcompany/product_x.git

如果您键入git remote -v您将在此特定文件夹中看到类似的列表:

origin  https://auser@github.com/ourcompany/product_x_company_a.git (fetch)
origin  https://auser@github.com/ourcompany/product_x_company_a.git (push)
parent  https://auser@github.com/ourcompany/product_x.git (fetch)
parent  https://auser@github.com/ourcompany/product_x.git (push)

然后,可以从本地从子存储库中提取推送到产品的更改,如下所示:

git pull parent master

如果一切都在本地按预期工作 - 它们可以像这样推送到特定的客户端存储库:

git push origin master

您通常不需要提交某些内容,因为基本上将提交从一个存储库传递到另一个存储库!

您可以在这些存储库中进行公司特定的代码更改,同时,如果产品(父产品)中存在错误或功能,则可以毫不费力地将其推送到所有客户端:)

请注意,最好不要直接在master上完成,而是在dev分支上完成,这样您就可以先运行单元测试、集成测试、代码质量指标和手动测试,然后再将其放入生产分支。

源代码

管理是处理此问题的好方法。 当您将主控合并/变基为 A 时,并且主控中的第 10-20 行已更改,A 中的第 15-25 行已更改,然后合并后:

lines 10-15 will match what's in Master
lines 15-20 will be marked as in-conflict, and you'll have to resolve the differences manually, use your favorite tool like diffmerge
lines 20-25 will match what's in A

我猜自定义将在绒毛内容区域中,而您的大多数 Master 更改将是具体功能。 在这种情况下,您的项目可能不会经常发生冲突。 因此,手动协调第 15-20 行中的冲突在大型项目中可能会很痛苦,但这仍然可能是处理您的情况的最佳方式。

最新更新