如何将现有的CVS模块导入到现有git仓库的子目录中?

6
我正在恢复一个比较旧的代码项目,当我还经常使用CVS时创建的,现在将其作为一个组件用于我已经在使用git的新项目中。我仍然可以访问包含旧项目模块的CVS存档,所以我打算使用git-cvsimport获取提交历史记录,然后从那里开始进行。但是,这只会在当前仓库内创建一个新的git仓库。很可能我需要将其作为多步骤过程来完成,其中我先将其从CVS转换为全新的git仓库,然后再使用其他工具将其导入到现有的git仓库中。
在newproj/newsubdir中运行此命令($CVSROOT已在我的shell配置中正确设置):
git cvsimport -k -o master -u -s \- -A ~/Documents/cvs-authors.txt oldproj

这将为我创建一个全新的存储库newproj / newsubdir / .git /,其中包含所有正确的提交(注释,时间戳,历史记录),并将HEAD设置在我想要的位置。

我想要的是历史CVS提交看起来就像它们总是在newproj / newsubdir / oldproj-file1、newproj / newsubdir / oldproj-file2等中。根据我的经验,git有这种魔力可以做到这一点,但我找不到一个明显适合我情况的方法。

2个回答

2
您有三个选项。它们都从执行清洁的cvsimport开始,所以请继续执行。
  1. 将该仓库作为子模块引用。
  2. 将仓库获取到现有仓库中,并进行子树合并以加入历史记录。
  3. 类似于#3的操作,然后将树重新移植,以便按时间顺序交错提交。
第一种方式意味着外部项目依赖内部项目,但可能不适合您。
第二种方式在子树合并指南中有详细说明。这可能对您来说已经足够好了。
但是,如果你喜欢一个漂亮干净的线性历史,你可以选择第三种方法,并将它们彻底纠缠在一起。我曾经在一个清理项目中做过类似的事情,现在还有很多文档和工具。

基本思路是将所有更改分离成一个补丁历史,以重构更改。默认情况下,这个历史记录按照存储库顺序排列,但运行我在帖子中提到的脚本将把补丁重新排列成按时间顺序的新序列。

树哈希应该让你知道,除了谱系之外,你没有破坏任何东西。

如果我再次这样做,我可能会只发出一个嫁接文件并执行filter-branch


哎呀,你回答的时候我正在自言自语。可恶我的不耐烦! - UltraNurd

0

根据这个合并git存储库的答案,我找到了实现自己想要的功能的方法,使用git filter-branch使得从CVS导入的模块好像已经直接合并到了现有git存储库中所需的子目录中。

从包含newproj的目录开始,即现有的git存储库:

% git cvsimport -k -u -s \- -A ~/Documents/cvs-authors.txt \
    -C newproj-sibling oldproj
% cd newproj-sibling
% git filter-branch --index-filter \
    'git ls-files -s | gsed "s-\t-&subdir/of/newproj/-" |
     GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
     git update-index --index-info &&
     mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD
% cd ../newproj
% git pull ../newproj-sibling master

假设 Git 存储库中目标子目录是全新的,或者至少不包含与 CVS 模块中同名的文件,则合并应该能够顺利进行。
一个注意点:我在上面使用了 gsed,因为 OS X 自带的 BSD sed 无法执行字符转义,例如 \t,并且我还没有设置别名。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接