我将与其他人一起研究使用cvs的项目中的代码。我们想使用分布式的vcs来完成工作,或者当我们完成时或者有时不时地一次,我们想将我们的代码和所有修订历史提交给cvs。我们没有对该项目的cvs存储库的写访问权,因此我们不能非常频繁地提交。我们可以使用什么工具将修订历史记录导出到CVS?当前,我们正在考虑使用git或mercurial,但如果可以简化导出,则可以使用其他分布式vcs。
我将与其他人一起研究使用cvs的项目中的代码。我们想使用分布式的vcs来完成工作,或者当我们完成时或者有时不时地一次,我们想将我们的代码和所有修订历史提交给cvs。我们没有对该项目的cvs存储库的写访问权,因此我们不能非常频繁地提交。我们可以使用什么工具将修订历史记录导出到CVS?当前,我们正在考虑使用git或mercurial,但如果可以简化导出,则可以使用其他分布式vcs。
Answers:
幸运的是,对于仍然被迫使用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
无论哪种方式,请记住两点:
cvsimport
,这将永远长久。master
分支机构中,以便可以将更改合并(或重新设置为基础)到本地/主题分支机构中。实际上,我建议始终在分支上进行更改,并且仅合并到 master
在准备好将这些更改导出回CVS存储库。您可以在分支机构上使用任何您喜欢的工作流程(合并,重新设置基准,挤压等),但是当然可以应用标准的重新编制基准规则:如果其他人将其更改基于您的分支机构,则不要重新编制基准。
该git cvsexportcommit
命令允许您将单个提交导出到CVS服务器。您可以指定一个提交ID(或任何描述定义的特定提交的ID man git-rev-parse
)。然后生成差异,将其应用于CVS签出,然后(可选)使用实际cvs
客户端提交给CVS 。您可以在主题分支上导出每个微型提交,但通常我想在最新的情况下创建合并提交,master
并将单个合并提交导出到CVS。导出合并提交时,必须告诉git使用哪个提交父对象来生成差异。另外,如果您的合并是快进的,则这将不起作用(请参阅执行合并时选项的“ HOW MERGE WORKS”部分)。这是一个示例:man git-merge
中的快进合并的说明),因此您必须使用--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 config 中设置选项:
% 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
上面的缩写中设置了authors文件)。
如果您需要多个人来执行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时的“下一件好事”是不切实际的。
git cvsimport
Debian,请尝试apt-get install git-cvs
Initialized empty Git repository in /Users/gus/projects/foo/foobar/.git/ Can't exec "cvsps": No such file or directory at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-cvsimport line 777. Could not start cvsps: No such file or directory git cvsimport: fatal: cvsps reported error
所以可悲的是,这并不能帮助您摆脱CVS的不足:(
您不应盲目相信cvsimport并检查导入的树是否与CVS存储库中的内容匹配。我通过使用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
底线:导入后检查您的树
除了Brian Phillips的答案:还有git-cvsserver,其功能类似于CVS服务器,但实际上访问git仓库...但是它有一些限制。