转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=3239

前不久有人问我是否把版本控制考虑转移到git的事情,其实我在2013年就写过一篇从hg导入git的方法和坑,里面给出了转移的实验,但没有具体计划。已经1年多过去了,git的工具和工作流也慢慢成熟。虽然git仍有一些基础上的缺点,比如无法进行文件改名以及轻易就可以改变历史记录,但由于有submodule和轻量的分支,再加上github的发展,从用户采纳程度来看,在git和hg的竞争中,git已经胜利。是时候再次考虑这个问题了。

需要注意的是,目前KlayGE的hg repository已经超过500M,初次pull的速度很慢,每次push的性能也受其影响。如果能在转移到git的过程中解决这个问题,这样的转移才有意义。否则只是换汤不换药。

几个选择

转移到git有多种方案上的选择,这里分析一下各种方案的利弊,也希望有朋友能帮忙给出建议。

方案1:直接转移

直接把KlayGE从hg转成git的好处是简单易行,一分钟就能完成。Git的repository会小5%左右。但这样并没有解决任何问题,还是需要很长时间来完成初次pull。这个做法最多是当作一个临时的git镜像,不是解决方案。

方案2:全部转成submodule

KlayGE除了引擎本身之外,还包含多个子库,外部库、DXBC2GLSL、glloader、KFL、kfont、MeshMLLib。理论上可以把他们分成多个submodule,而KlayGE作为一个超项目。正如Boost的组织方式。这样虽然听起来很合理,并且可以让repository减到最小,但因此需要完全重建整个repository,工作量极大。而且,由于这几个子库之间的依赖关系密切,用户仍然需要更新所有的submodule才能才能使用KlayGE,失去了submodule带来的所有好处。

另外,有的服务商并不能很好地支持submodule,也让这个方案效果打折扣。

方案3:部分转成submodule

另一个折衷的方案是,只有外部库(boost、freetype等)转成submodule,KlayGE本身保留单一repository和那些外部库的补丁。这样可以直接从外部git源同步代码,并打上补丁后使用。这样repository的大小也可以减少很多。缺点是补丁得频繁修改和测试,同时外部库的git源一旦不稳定(比如boost时不时会被封杀一段时间),就无法编译KlayGE。

同时,这个方案也有submodule支持不好的缺点。

方案4:单一repository,下载外部库发行版

比前面的方案更保守一点,就是还用个单一的git repository,但外部库不包含在内,而是通过脚本下载它们的发行版压缩包,解压和打上补丁后放到相应目录。补丁只需要针对发行版,修改测试的频率都低很多。现有的一些二进制资源文件也可以这样移除。同时这个方案不会遇到submodule的缺点。这个方法仍然需要重建大部分repository,不过至少工作量小于方案2。

总结

我个人倾向于方案4。但无论如何,都会需要写个脚本重建repository,并把trac里的所有ticket都修改到对应的版本号上。这个实验会在近期展开,但不确定需要多长时间才能完全完成。

如果有什么我没想到的方案,也请指出来。