8. 版本管理工具迁移

更换版本控制工具一定是万不得已而为之。处理不当,将会丢失文件的版本历史记录,这无异于一场灾难。下面仅仅讨论了从 Starteam 移植到 CVS 的过程,其它类型的迁移可以举一反三。

8.1. 用同一套本地目录,对应于相应的 STARTEAM 和 CVS 工程

导出工程在 Starteam 中的文件和目录结构,并在 CVS 中创建新的工程“project”,并导入目录结构。

# cd ~jiangxin/work/
# mkdir project
# cd project
# st config 
配置为 Starteam 的 project 工程视图
# st cd 
# cvs import -m "create directory" project Johnson init
##该命令等效于:
# for i in `find . -type d -exclude "CVS"`; do cvs add $i; done

8.2. 导出 Starteam 每个文件的Commit Log

从 Starteam 中 Checkout 出每个文件,在将每个文件的Commit Log 导出为扩展名为 .jxlog 的文件。 导出的 log 被应用程序 steam2cvs 分析并生成脚本,用于完成文件从 starteam 向 cvs 迁移。

# cd ~jiangxin/work/project
# st -qq co
# for i in `find . -type f -exclude "CVS"`; do i=${i#./}; st log $i >$i.jxlog; done

复杂一些的脚本:

#!/bin/sh

cd <PATH>

xxx=0

for i in `find . -type f`; do 
        if  echo $i | grep -w -e "CVS" -e ".jxlog" -e ".jxsh"; then
                continue
        fi 

        j=${i}.jxlog
        if [ -f $j ]; then
                continue
        fi
        i=${i#./}
        st log $i >$i.jxlog.tmp
        mv -f $i.jxlog.tmp $i.jxlog
        xxx=`eval "expr $xxx + 1"`
        echo "$xxx : $i"
done

8.3. 剖析STARTEAM日志,生成脚本,完成版本控制系统的迁移

根据每个文件的Commit Log 文件(*.jxlog),生成相应的脚本文件。

STARTEAM 日志格式如下:

Folder: starteam  (working dir: /home/jiangxin/src/starteam)
History for: st
Description:
Locked by:
Status: Current
----------------------------
Revision: 58 View: compiler Branch Revision: 1.57
Author: nobody_used_for_utility_coci Date: 3/7/03 11:15:03 AM CST
use trap 'rm -f xxxx' EXIT to remove temporary passwd file


----------------------------
Revision: 57 View: compiler Branch Revision: 1.56
Author: nobody_used_for_utility_coci Date: 10/23/02 7:24:38 PM CST
change server ip from 60 to 6


----------------------------
...
...
...
----------------------------
Revision: 2 View: compiler Branch Revision: 1.1
Author: jiangxin(root) Date: 3/10/02 2:12:24 AM CST
jiangxin edition

----------------------------
Revision: 1 View: compiler Branch Revision: 1.0
Author: jiangxin(root) Date: 3/10/02 2:10:17 AM CST
starteam wrapper. by yangzw

=============================================================================

通过程序 steam2cvs 转换之后的脚本示例如下:

st -qq co -lf -r 1 st
cvs add st
cvs ci -m "starteam wrapper. by yangzw (Author:jiangxin(root), Date:3/10/02 2:10:17 AM CST)" st
st -qq co -lf -r 2 st
cvs ci -m "jiangxin edition (Author:jiangxin(root), Date:3/10/02 2:12:24 AM CST)" st
st -qq co -lf -r 3 st
cvs ci -m "ci failed (Author:jiangxin, Date:3/10/02 2:16:25 AM CST)" st
st -qq co -lf -r 4 st
cvs ci -m "cvs style wrapper (Author:jiangxin, Date:3/10/02 2:23:10 AM CST)" st
...
...
...
st -qq co -lf -r 57 st
cvs ci -m "change server ip from 60 to 6 (Author:nobody_used_for_utility_coci, Date:10/23/02 7:24:38 PM CST)" st
st -qq co -lf -r 58 st
cvs ci -m "use trap 'rm -f xxxx' EXIT to remove temporary passwd file (Author:nobody_used_for_utility_coci, Date:3/7/03 11:15:03 AM CST)" st

转换程序 steam2cvs 即完成了上述日志到脚本的转换。源程序参见:

/src/starteam2cvs/steam2cvs.c,/src/starteam2cvs/mystring.c, ...

对整个工程的文件执行此操作:

# cd ~jiangxin/work/project
# find . -name "*.jxlog" -o -name ".*.jxlog" -type f -exclude "CVS" -exec steam2cvs {} \;

复杂一些的脚本:

#!/bin/sh

cd <PATH>

xxx=0

while : ; do

for i in `find . -name "*.jxlog" -o -name ".*.jxlog" -type f`; do 
        xxx=`eval "expr $xxx + 1"`
        echo -e "$xxx : proc $i ...     \c"
        steam2cvs $i
        j=${i}.jxsh
        # 运行脚本
        sh $j
        rm -f $i
        echo "done"
done

sleep 60
done

8.4. 运行生成的脚本,完成代码 Checkin

# cd ~jiangxin/work/project
# find . -name "*.jxsh" -o -name ".*.jxsh" -type f -exclude "CVS" -exec sh {} \;

同时在 CVS 服务器端,实时计数

# while : ; do find . -type f | wc -l ; sleep 10; done

8.5. 缺憾

因为 Starteam 的Label 不能用命令行显示。因此不能自动将 Starteam 中的 LABEL 恢复为 CVS 相应的 TAG。这是一个遗憾。

对于重要的 LABEL 我们可以用手工方法重建。