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

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

但可能是因为WordPress官方的svn仓库太大,历史记录太多,而git-svn的内部实现又有点问题,所以最近几次我用git svn rebase和git 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分支的提交一一对应。这个过程如下图所示:


目录结构如下所示:

$ pwd
/Users/zhixiangzhu/emwi
$ ls -R
git		svn
 
./git:
README.md				license.txt
external-media-without-import.css	readme.txt
external-media-without-import.js	screenshots
external-media-without-import.php
 
./git/screenshots:
screenshot-1.png	screenshot-2.png
 
./svn:
assets		branches	tags		trunk
 
./svn/assets:
banner-1544x500.jpg	icon-128x128.jpg	screenshot-1.png
banner-772x250.jpg	icon-256x256.jpg	screenshot-2.png
 
./svn/branches:
 
./svn/tags:
1.0	1.0.1	1.0.2	1.0.2.1
 
./svn/tags/1.0:
external-media-without-import.css	license.txt
external-media-without-import.js	readme.txt
external-media-without-import.php
 
...
 
./svn/trunk:
README.md				license.txt
external-media-without-import.css	readme.txt
external-media-without-import.js	screenshots
external-media-without-import.php
 
./svn/trunk/screenshots:
screenshot-1.png	screenshot-2.png

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

$ pwd
/Users/zhixiangzhu/emwi
$ ls -R
git		svn		git2svn.sh

脚本内容如下:

# 如果当前是在父目录,则进入git工作目录
if [ $PWD != *git ]
then
	cd git/
	echo $PWD
fi
 
# 将git工作目录最新提交的改动输出到git.diff
git diff --no-prefix HEAD^ HEAD > ../git.diff
 
# 将git最新提交的提交日志输出到git_n.log
git log -1 --format="%B" HEAD > ../git_n.log
 
cd ..
 
# git_n.log的最后一行是空行,要将其删掉
perl -pe 'chomp if eof' git_n.log > git.log
rm git_n.log
 
# 更新svn工作目录
cd svn
svn update
 
# 将改动应用到svn/trunk目录
cd trunk
patch -p0 < ../../git.diff
 
# 提交到svn仓库,提交日志与git相同
cd ..
svn commit -F ../git.log
 
cd ..
rm git.diff git.log

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

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

本文在我的独立博客上的地址:http://zxtechart.com/2018/03/20/apply-git-diff-to-svn

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zzxiang1985/article/details/79634392
文章标签: git svn
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭