需求:一个常见的需求是后端代码不断的提交,而上到生产环境上并不一定是svn上最新的代码(比如说有些功能需要前端app来配合)。那么就存在这样一个需求,给生产的版本打一个补丁并发布
如何实现呢?
让svn回退到历史某版本打补丁,之后再更新回当前状态
实际上我们需要“merge backwards”功能,在当前版本和之前版本之间应用diff到当前版本(这样我们实际上得到的就是一个看起来就是之前版本的一个最新版本),然后再次提交就可以了。
在intellij idea中可以使用terminal来执行以下svn操作
比如说我们当前版本为r20159,想让版本回退到历史版本r19956(当前生产的版本),提交之后版本为r20160,打好补丁后提交为版本r20161,jenkins来构建并进行发布,发布完成后再恢复回r20161。最终的效果是svn的最新版本的内容并没有啥变化,但是已经在生产的版本打好了补丁
第一步:
先执行r20159回退到r19956
svn update
之后将要修改的几个文件复制到一个新的文件夹中
svn merge –r 20159:19956 . 不要忘记这个.
svn commit –m “Rolled back to r19956”
第二步:
提交完成后最新版本为r20160
之后参考第一步复制出来的文件来打补丁,提交到svn,最新版本为r20161,提交到部署管道进行构建打包发布
第三步:
再执行r20161回退到r20159
svn update
svn merge –r 20161:20159 . 不要忘记这个.
svn commit –m “Rolled back to r20159”
查看svn history可以看到
完美实现此功能
如果在执行过程中打补丁之后,忘记了第二步提交,而直接进行了第三步,那么就会出现conflict,比如说我修改了Class A这个类,那么第三步执行到merge的时候就会冲突了,冲突的原因是我们执行r20568,merge之后恢复到r20567,由于我们忘记了提交,那么r20568在merge之后与r20567区别就只有Class A了,这样就会conflict
解决方法就是选择postpone,之后手动解决掉冲突
另外,merge之后会产生大量的可提交文件(这是因为r20568 merge之后与r20568 merge之前(即svn up to date版本)对比产生的),直接提交就可以了。所以easy,第二步忘了提交也没啥。
下面说明一下可能遇到的两个问题。
1. 在执行svn update 时产生Node remains in conflict的问题
原因是比如说有人提交了log.log文件到svn了(这当然是不对的)。当你自己提交svn的时候,显然会skip掉这个文件。但是当你使用terminal svn update(没有skip这个文件)的时候,就会产生这个问题了
先执行svn revert --depth=infinity log.log
之后再执行svn update就可以了
2. 如果在执行merge命令的时候报错
merge tracking not allowed with missing subtrees, try restoring these items first
这个问题的原因就是说在19956版本存在exception和reindex这两个文件,而20160版本已经不存在了。其根本原因是svn用户在本地删除掉了这两个文件,然后提交了svn(svn老版本并不知道这两个文件被删除了),那么当向老版本merge的时候,就会出现这个问题
这个问题怎么处理呢?
首先svn update
之后一次执行
svn rm 加上图中的文件及路径
如svn rm xxxxxxxx\exception
显示
之后就可以了
参考:How do I return to an older version of our code in Subversion?
How to update an SVN branch made with svn-copy?