26.2 git-svn的奥秘

通过上面对git-svn的工作流程的介绍,相信您已经能够体会到git-svn的强大。那么git-svn是怎么做到的呢?

git-svn只是在本地Git库中增加了一些附加的设置和特殊的引用,并引入了附加的可重建的数据库实现对Subversion版本库的跟踪。

26.2.1 Git库配置文件的扩展及分支映射

当执行git svn init或git svn clone时,git-svn会通过在Git库的配置文件中增加一个小节,记录Subversion版本库的URL,以及Subversion分支/里程碑和本地Git库的引用之间的对应关系。

例如:当执行git svn clone-s file:///path/to/svn/repos/demo指令时,会在创建的本地Git库的配置文件.git/config中引入下面的新配置:


[svn-remote "svn"]

url=file:///path/to/svn/repos/demo

fetch=trunk:refs/remotes/trunk

branches=branches/:refs/remotes/

tags=tags/:refs/remotes/tags/


默认svn-remote的名字为svn,所以新增的配置小节的名字为:[svn-remote "svn"]。在git-svn克隆时,可以使用—remote参数设置不同的svn-remote名称,但是并不建议使用。因为一旦使用—remote参数更改svn-remote名称,必须在git-svn的其他命令中都使用—remote参数,否则报告[svn-remote "svn"]配置小节未找到。

该小节中主要的配置有:

url=<URL>

设置Subversion版本库的地址。

fetch=<svn-path>:<git-refspec>

Subversion的开发主线和Git版本库引用的对应关系。

在上例中Subversion的trunk目录对应于Git的refs/remotes/trunk引用。

branches=<svn-path>:<git-refspec>

Subversion的开发分支和Git版本库引用的对应关系。可以包含多条branches的设置,以便将分散在不同目录下的分支汇总。

在上例中Subversion的branches子目录的下一级子目录(branches/*)所代表的分支在Git的refs/remotes/下建立引用。

tags=<svn-path>:<git-refspec>

Subversion的里程碑和Git版本库引用的对应关系,可以包含多条tags的设置,以便将分散在不同目录下的里程碑汇总。

在上例中Subversion的tags子目录的下一级子目录(tags/*)所代表的里程碑在Git的refs/remotes/tags下建立引用。

可以看到Subversion的主线和分支默认都直接被映射到refs/remotes/下。如trunk主线对应于refs/remotes/trunk,分支demo-1.0对应于refs/remotes/demo-1.0。Subversion的里程碑因为有可能和分支同名,因此被映射到refs/remotes/tags/之下,这样里程碑和分支的映射就放到了不同的目录下,不会互相影响。