我正在复制一个相当古老的代码项目,从我定期使用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有这样的魔力事情,但我找不到明显适合我的情况。
答案 0 :(得分:2)
您有三种选择。所有这些都从干净的cvsimport开始,所以继续这样做。
第一个意味着外部项目依赖于内部,但可能不适合你。
在subtree merge howto中解释了第二个问题。对你来说可能已经足够了。
但是如果你喜欢干净的线性历史,你可以做#3并将它们纠缠在一起。我在一个清理项目中做了something similar,并且还有很多文档和工具。
基本思想是将所有更改分成可重建更改的修补程序历史记录。默认情况下,此历史记录采用某种存储库顺序,但运行我在帖子中提到的脚本会按时间顺序将修补程序重新排列为新序列。
树形哈希应该让你知道你没有破坏除了血统以外的任何东西。
如果我再次这样做,我可能只是发出一个移植文件并执行filter-branch
。
答案 1 :(得分:0)
根据this answer for combining git repositories找出如何做我想做的事情,使用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存储库中的target子目录是全新的,或者至少不包含与CVS模块中的目标共享名称的文件,那么合并应该顺利进行。
有一点需要注意:我上面已经说过了,因为OS X附带的BSD sed不能像\ t那样进行字符转义,而且我还没有打扰别名。