我管理的是一个较大的(23,000 LOC包含/ src,5000个LOC用于样本),多平台,ANSI C代码库用于从8位嵌入式处理器和32KB闪存到桌面PC运行的所有内容视窗。此代码库将继续增长,我们将为其添加更多平台。
我目前正在使用Subversion维护它,但该公司正在转向使用所有版本控制的git。
我需要一种方法来对目录结构进行不同的映射,以便文件可以适应每个目标开发环境的现有结构。我希望能够从这些映射目录中检查更改,因为我们将在给定平台的目录结构中对库进行主动开发。例如,启动新平台可能会暴露库中的错误,并且最容易将其修复到位,并从该结构提交更改。
例如,一个平台可能具有以下结构:
虽然另一个可能是这样的:
存储库:
我在存储库的目录结构中具有灵活性,但我想要一些有意义且易于维护的东西。我还希望将所有内容保存在单个存储库中,因为更改集可能会影响include
中的一个头文件,src
中的多个文件以及多个示例程序。
使用Subversion,我可以使用svn:externals来进行目录映射。存储库包含名为master
的根目录中的所有文件,然后使用svn:externals将文件/目录从master
映射到给定平台所需的任何布局的每个平台的其他根目录。
我对git很新,但我读过有关子模块的内容,它们似乎不符合要求,因为它们不允许目录映射,并且您无法提交跨多个子模块的更改(AFAIK)
大多数嵌入式开发都在Windows上进行,因此符号链接不适用于目录映射。
我有可能以错误的方式看待这个问题,并且我需要为每个平台提供一个存储库,从另一个存储库中提取公共代码。但是从我在git子模块上读到的内容来看,无法进行目录映射。
答案 0 :(得分:2)
只要版本控制周期与存储库的其余部分足够独立,我就会建议共享模块(子树)的子模块。
另一个想法,恕我直言,将是主题分支。在主题分支中保留一些特定于平台的调整,以便您可以将它们“叠加”在正在开发的中心分支之上。
topgit
是一个我非常喜欢管理主题分支更自动化的工具。根据我的经验,Topgit有一个相当陡峭的学习曲线,所以你可能想暂时回避它。
我当然会把所有东西放在一个回购中;如果你必须,你可以
并且仍然通过适量的脚本编写'逻辑'链接的子树:
请参阅git read-tree
,例如
git read-tree --prefix=externals/ origin/3rdparty:i386/externals
git read-tree --prefix=samples/ origin/samples
(请注意origin/3rdparty:i386/externals
如何直接引用特定引用的子树,例如man git-rev-spec
中的详细信息)
只要您在.gitignore中保留externals/
和samples/
包含此类动态链接子树的常规分支,您就不会遇到太多麻烦(将它们视为链接形式的readonly,就像svn externals一样。)
答案 1 :(得分:0)
所以我终于从Subversion转移到git,并根据@ peachykeen对我的问题的评论,我能够使用junction points进行目录映射。我刚刚创建了一个小批量文件,它通过成对的链接和目标进行循环,并使用rmdir
删除旧链接,使用mklink /j
创建新链接。
@echo off
:: Expand variables at execution time rather than at parse time.
setlocal EnableDelayedExpansion
SET MAPPING= ^
include\foo:include\foo ^
include\bar:include\bar ^
include\baz:include\baz ^
src\foo:Lib\Blah\foo ^
src\bar:Lib\Blah\bar ^
src\baz:Lib\Blah\baz ^
src\util:Lib\Blah\foo\util ^
src\platform:Lib\Blah\foo\platform ^
samples\platform:Samples\foo ^
samples\common:Samples\foo\common ^
test:Test\foo
set PLATFORM=..\..\
set DRIVER=..\
for %%M in (%MAPPING%) do (
for /f "tokens=1,2 delims=:" %%a in ("%%M") do (
set SRC=%%a
set DST=%%b
if exist %PLATFORM%!DST! rmdir %PLATFORM%!DST!
mklink /j %PLATFORM%!DST! %DRIVER%!SRC!
)
)
这甚至可以作为git子模块与驱动程序一起使用。只需运行批处理文件一次即可设置联结。