我将与其他人一起使用来自使用cvs的项目的代码.我们希望使用分布式vcs来完成我们的工作,当我们完成或者每隔一段时间我们想要将我们的代码和所有修订历史记录提交给cvs.我们没有对项目的cvs repo的写访问权限,所以我们不能经常提交.我们可以使用什么工具将修订历史导出到cvs?目前我们正在考虑使用git或mercurial但我们可以使用另一个分布式vcs,如果它可以使导出更容易.
幸运的是,对于我们这些仍然被迫使用CVS的人来说,git提供了很好的工具来完成您想要做的事情.我的建议(以及我们在$ work的工作):
用于git cvsimport
将CVS修订历史记录克隆到git存储库中.我使用以下调用:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \ -A /path/to/authors/file cvs_module_to_checkout
该-A
选项是可选的,但它有助于使从CVS导入的修订历史看起来更像git(man git-cvsimport
有关如何设置的详细信息,请参阅参考资料).
根据CVS存储库的大小和历史记录,首次导入将花费很长时间.如果您想要确实发生某些事情,您可以在上面的命令中添加-v.
一旦完成此过程,您将拥有一个master
应该反映CVS的HEAD 的分支(除了git cvsimport
默认情况下忽略最后10分钟的提交以避免捕获半完成的提交).然后git log
,您可以使用和朋友一起检查存储库的整个历史记录,就像它从一开始就使用git一样.
有一些配置调整将使CVS(以及出口)的增量导入在未来更容易.这些没有记录在git cvsimport
手册页上,所以我想他们可以在没有通知的情况下进行更改,但是,FWIW:
% git config cvsimport.module cvs_module_to_checkout % git config cvsimport.r cvs % git config cvsimport.d $CVSROOT
可以在命令行中指定所有这些选项,以便您可以安全地跳过此步骤.
后续git cvsimport
应该比第一次调用快得多.但是,它确实cvs rlog
在每个目录上执行(即使那些只有文件的目录Attic
),所以它仍然需要几分钟.如果你已经指定了上面建议的配置,你需要做的就是执行:
% git cvsimport
如果尚未设置配置以指定默认值,则需要在命令行中指定它们:
% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout
无论哪种方式,要记住两件事:
确保您位于git存储库的根目录中.如果你是其他任何地方,它将尝试做一个新的cvsimport
,将再次永远.
确保您在master
分支机构上,以便可以将更改合并(或重新绑定)到您的本地/主题分支.
在实践中,我建议始终在分支上进行更改,并且只有master
在准备好将这些更改导出回CVS存储库时才合并.您可以在分支机构中使用您喜欢的任何工作流程(合并,重新定位,压缩等),但当然标准的变基规则适用:如果其他人一直在您的分支上进行更改,请不要改变.
该git cvsexportcommit
命令允许您将单个提交导出到CVS服务器.您可以指定单个提交ID(或描述特定提交的任何内容man git-rev-parse
).然后生成diff,应用于CVS签出,然后(可选)使用实际cvs
客户端将其提交到CVS .你可以导出的每个微提交关于你的话题分支机构,但通常我喜欢创造一个合并提交上了最新的master
出口是一个合并提交到CVS.导出合并提交时,必须告诉git使用哪个提交父级来生成diff.此外,如果您的合并是快进(请参阅man git-merge
快速合并的描述的"HOW MERGE WORKS"部分),这将不起作用,因此您必须使用--no-ff
执行合并时的选项.这是一个例子:
# on master % git merge --no-ff --log -m "Optional commit message here" topic/branch/name % git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD
您可以在git-cvsexportcommit的手册页上看到每个选项的含义.你可以-w
选择在你的git配置中设置选项:
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
如果补丁不管是什么原因失败了,我的经验是,你(可惜)可能会更好过手动复制已更改的文件,并使用CVS客户端提交.这不应该发生,但是,如果你要确保master
是最新最新与CVS在合并您的主题分支之前.
如果提交失败无论出于何种原因(网络/权限问题等),你可以在错误输出端采取打印到你的终端的命令,并在你的CVS执行它的工作目录.它通常看起来像这样:
% cvs commit -F .msg file1 file2 file3 etc
你做下一次git cvsimport
(等待至少10分钟),你应该看到的补丁导出的承诺重新导入到你的本地仓库.它们将具有不同的提交ID,因为CVS提交将具有不同的时间戳并且可能具有不同的提交者名称(取决于您是否在cvsimport
上面的初始中设置了作者文件).
如果您有多个人需要这样做cvsimport
,那么拥有一个执行cvsimport的git存储库并将所有其他存储库创建为克隆会更高效.这完全有效,克隆的存储库可以执行cvsexportcommits,如上所述.但是有一点需要注意.由于CVS提交通过不同的提交ID返回的方式(如上所述),您不希望克隆的分支跟踪中央git存储库.默认情况下,这是git clone
配置存储库的方式,但这很容易解决:
% git clone [CENTRAL_REPO_HERE] % cd [NEW_GIT_REPO_DIR_HERE] % git config --unset branch.master.remote % git config --unset branch.master.merge
删除这些配置后,当您想从中央存储库中提取新提交时,您必须明确说明从何处以及从中获取什么:
% git pull origin master
总的来说,我发现这个工作流程是非常易于管理的,而且当完全迁移到git时,"下一个最好的东西"是不切实际的.
您不应该盲目信任cvsimport并检查导入的树是否与CVS repo中的匹配.我通过使用eclipse CVS插件共享新项目并发现存在不一致性来完成此操作.
使用相同的提交消息在不到一分钟内完成的两次提交(为了还原错误删除的文件)被分组为一个大提交,这导致从树中丢失文件.
我能够通过将'fuzz'参数修改为不到一分钟来解决这个问题.
例:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \ -A /path/to/authors/file cvs_module_to_checkout -z 15
底线:导入后检查您的树