将git工作目录的改动应用到svn

之前在维护自己写的WordPress插件时,为了能够方便地同时向GitHub仓库和WordPress官方的svn仓库提交,我只在本地维护了一个git工作目录,然后用 git svn dcommit向svn仓库提交,用 git push向GitHub提交。(详见我之前写的日志。)

但可能是因为WordPress官方的svn仓库太大,历史记录太多,而git-svn的内部实现又有点问题,所以最近几次我用 git svn rebasegit svn dcommit都毫无反应。思来想去,为了不耽误时间,我还是决定老老实实用svn客户端了。

于是现在我本地就有了两个目录:一个git工作目录,用于向GitHub提交;一个svn工作目录,用于向svn提交。由于svn里的分支和标签实际上就是目录,因此svn工作目录下还有trunk、branches和tags子目录。trunk子目录里的内容才和git工作目录里的内容相同。

一般我是在git工作目录下写代码,因此思路是在git工作目录commit之后,用 git diff生成patch文件, git log输出提交日志到另外一个文件。然后用 patch命令将 git diff应用到svn工作目录。最后 svn commit的时候利用git log的输出,这样就可以做到svn trunk分支的提交和git master分支的提交一一对应。这个过程如下图所示:

目录结构如下所示:

显然我在其中一个工作目录下做出改动后,还要将改动同步到另一个工作目录并提交。人工同步改动显然繁琐耗时又容易出错,需要自动化。我写了一个脚本git2svn.sh,用于将git工作目录中最新提交所做的改动应用到svn工作目录并自动提交到svn仓库。这个脚本就放在与git工作目录和svn工作目录同级的地方。可以在git工作目录中执行,也可以在父目录中执行:

脚本内容如下:

脚本第17行的perl命令的作用是将 git log -1 --format命令输出的git_n.log文件末尾的空行删掉,见https://stackoverflow.com/a/1654042。其中 -p的作用是打印输入文件git_n.log的每一行, -e的作用是执行 -e后面的perl代码。详见这篇Perl命令行参数的说明chomp用于去除空行。

不过这个脚本没有文件的添加和删除。对这两个情况还需要分别调用 svn addsvn delete,等以后遇到这个需求再改进吧。

发表评论

电子邮件地址不会被公开。 必填项已用*标注