将git的变更merge到svn或将svn的变更merge到git.

来源:互联网 发布:像韩国人的淘宝模特 编辑:程序博客网 时间:2024/06/05 09:34

  今天遇到个问题,项目使用SVN做版本控制,但是里面用了一个开源项目是放在github上的,本地做了自定义修改。后来开源项目发了新版本,我们项目要升级的时候遇到了问题。由于版本控制信息已经不是一个base, 所以没法用svn merge之类的指令来完成升级。Google之后发现思路基本是把开源项目的变更diff出来,然后用patch指令打patch到我们项目。 

cd /path/to/svn/reposvn diff -r 125 > /tmp/patch.diffcd /path/to/git/repopatch -p0 < /tmp/patch.diff

git diff出来的patch和svn的格式略有不同,可以用如下命令将其格式化为svn格式:

git diff  --no-prefix --ignore-space-at-eol | sed -e "s/^diff --git [^[:space:]]*/Index:/" -e "s/^index.*/===================================================================/" > changes.patch

diff和patch都很顺利,但是到处理冲突的时候就麻烦了。patch指令会讲原始信息,冲突信息,合并信息分别存到三个文件中(a.py, a.py.orig, a.py.rej)。这样处理冲突很麻烦,也没有合适的工具来处理,google上大部分都是推荐手动处理,虽然找到个工具wiggle能解决部分问题, 但是依然没有svn merge那种 <<< === >>>分割的格式方便。

  因为我很懒,觉得这种dirty work实在太累了, 太违和了, 为什么patch不能像svn merge一样把冲突格式化到一个文件中呢? 最后发现原来patch是支持这个功能的, 就是在打patch的时候带上--merge参数: 

patch --merge -p0 < /tmp/patch.diff

  这样一来冲突就自动格式化为<<< === >>>了。但是还有个小问题,这样patch后有冲突的文件不会在svn st中标注出来,因为我们没有使用svn merge, 所以svn 没能跟踪到这些冲突, 所有被修改文件都是M状态。这时候可以使用如下指令找到所有有修改的文件:

find . -name '*rej'

原理是使用--merge参数后patch依然会生成.rej文件将冲突信息放进去。然后我们就可以利用这些文件找到有冲突的文件了。

最后处理完所有冲突, 移除零时文件:

find . -name '*rej' | xargs rm

find . -name '*orig' | xargs rm

​搞定收工,测试无误后提交吧。

将svn diff patch applay到git上也可以用类似的方法。

另外,高版本svn (>1.7) 和git 都有svn patch 和 git patch指令,就合patch指令功能差不多甚至还要更好些. 但是相信大部分现有项目还是<1.7的, 而且1.7和1.6的svn库是不兼容的。

0 0
原创粉丝点击