Gau*_*ier 8 git embedded workflow branch
我很快就开始维护一系列包含相同嵌入式软件变体的产品.由于我已经玩git一年并非常欣赏它,我很可能将它用于源代码控制.
我可以看到几个选项来维护固件的变体,但没有一个让我高兴.您为自己的工作申请的最佳做法是什么?
我能想到的替代方案:
定义.预处理.优点:源代码中始终存在所有内容,因此很难错过其中一个产品的更新.缺点:难以阅读.它可能没问题,而我们只有两个变体,当它变成四个或更多时会很痛苦.此外,应用DRY原则似乎更难(不要重复自己).
每个产品变体一个分支.如果包含适用于所有产品的更改,则必须将更改合并到其他产品.缺点:如果提交包含所有产品的更改和特定变体的更改,则会出现问题.当然,您可以确保提交仅包含一种更改:此产品更改或整个系列更改.但是试着强迫一个团队?加上合并不起作用,我们应该采摘樱桃.对?
一个核心库作为子模块.使包含核心功能的所有文件成为存储库.所有产品都包含一个版本的核心存储库作为子模块.缺点:我看不出最终会出现核心子模块的变体.然后我们再次陷入困境,然后我们再次使用定义或坏事.有分支的核心存储库?然后我们回到上一个替代方案:必须合并适用于所有分支的更改,但合并还包括产品特定的内容.
创建每个模块的存储库.例如,显示驱动程序的存储库,另一个用于电源管理硬件,另一个用于用户输入接口,...优点:良好的模块化.只需选择您需要的模块作为子模块来制作新产品!所有子模块都可能具有分支,例如,变体以不同的方式使用硬件.缺点:有很多模块,每个模块都跟踪几个文件(包含文件和源文件).麻烦.有人在某些模块中进行了重要更新吗?然后,如果合适,有人需要在此模块的其他分支中包含更改.然后有人还必须更新每个产品存储库中的子模块.相当一些工作,我们有点失去了git的快照方面.
你是怎么做到的,它是如何运作的?或者你会怎么做?
我有一种感觉,我应该有樱桃采摘的经验.
您应该尽可能地将每个变体的自定义代码保存在自己的文件集中.然后,您的构建系统(Makefile或其他)根据您正在构建的变体选择要使用的源.
这样做的好处是,在处理特定变体时,您可以将所有代码放在一起,而不需要其他变体的代码来混淆事物.可读性也比使用#ifdef,#elif,#endif等乱丢源更好.
当您知道将来要将分支中的所有代码合并到主分支(或其他分支)时,分支最有效.它仅用于合并从分支到分支的一些更改(尽管它当然可以完成).因此,为每个变体保留单独的分支可能不会产生良好的结果.
如果使用上述方法,则无需在版本控制中尝试使用此类技巧来支持代码的组织.
我试着尽可能地去做#define.使用适当的代码,您可以最大限度地减少对可读性和重复性的影响.
但同时#define方法可以安全地与拆分和分支相结合,其应用取决于代码库的性质.
我不确定这是否是"最佳实践",但是Scintilla项目多年来一直使用的东西仍然很容易管理.它只有一个通用于所有平台的分支(主要是Windows/GTK +/Mac,但有VMS,Fox等的变体).
不知何故,它使用了第一个很常见的选项:它使用了定义来管理源内部的小平台特定部分,在这里放置公共代码是不切实际或不可能的.
请注意,某些语言(例如Java)无法使用此选项.
但是可移植性的主要机制是使用OO:它抽象一些操作(绘图,显示上下文菜单等),并为每个目标使用一个Platform文件(或几个),提供具体的实现.
makefile只编译适当的文件,并使用链接来获取正确的代码.