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

时间:2013-11-15 17:04:38

标签: git git-branch git-fork

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

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

Master 
   Company A  
   Company B  
   Company C

我主要担心的一个问题是如何同步更改?我不认为客户端的fork会发生任何会影响master的更改,但是master会发生一些肯定会影响fork的更改。这会是一场巨大的噩梦吗?这是处理这种情况的最佳方法吗?

5 个答案:

答案 0 :(得分:5)

我会使用rebase。此命令将您的分支倒回到与主分支分开的点,然后在其上重放您的更改。说你有这个(从手册页借来的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会暂停rebase并让你解决它。差异找到冲突,然后

git add conflicting_file
git rebase --continue

或者鸡出来:

git rebase --abort

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

答案 1 :(得分:2)

我已经活过了,这是一个令人难以置信的混乱。通常情况下,您的工作流程最终会变为:忘记来自最近的客户端的master和fork。然后它就变成了一场噩梦。

我强烈建议重构代码,将两个独立的git模块中的东西分成一个“核心”,一个分别用于(每个)公司特定的代码。不知道你回购的确切性质,很难说。我已经看到了工作和拆分模块比回购中的一堆客户分支更容易管理。

答案 2 :(得分:1)

我认为这里最好的选择是使用子模块。为将包含每个客户资料的每个客户创建一个存储库,并将公共核心存储库添加为每个客户端的子模块。可能需要重新安排子目录等,但这样可以让您开发共同核心并按照自己的时间表升级每个客户。一个缺点是它为所有额外的子模块拷贝占用了更多的磁盘空间 - 但是,通过使用git的共享对象存储功能可以部分地减轻这种情况,并且磁盘空间相当便宜。

您可以使用每个客户分支方法在单个存储库中完成您想要的任务,但保持所有分支直接并确保您不会意外地交叉合并或其他内容,这需要谨慎。

答案 3 :(得分:0)

源代码管理是处理此问题的好方法。当您将Master合并/重新绑定到A,并且在Master中更改了第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行中的冲突可能会成为一个大项目的痛苦,但它仍然可能是处理您的情况的最佳方式。

答案 4 :(得分:0)

我尝试过并且有效的方法是为您的产品代码建立一个存储库 例如product_x。您可以将其分叉给每个客户端,从而得到单独的存储库,例如:

product_x_company_aproduct_x_company_bproduct_x_company_c

由于不允许从父级到子级的拉取请求,而仅允许从子级到父级的拉取请求,因此我们必须遵循不同的路线。

我在本地所做的工作是添加到每个公司存储库中,例如product_x_company_a 除了origin拥有自己的仓库网址之外,还有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分支上完成,这样您可以先运行单元测试,集成测试,代码质量度量和手动测试它进入生产分支。