【问题标题】:Migrate from CVS to Git without losing history从 CVS 迁移到 Git 而不会丢失历史记录
【发布时间】:2014-01-01 14:37:17
【问题描述】:

我想知道是否有办法将我的代码从 CVS 源代码管理迁移到 Git?

如果是,那我的提交历史呢?

【问题讨论】:

标签: git version-control cvs


【解决方案1】:

这是我使用cvs2gitlatest stable release is here,但 IIRC 我使用的是 github 开发版本)将 SourceForge CVS 存储库迁移到 Git 的过程,它适用于 Windows 和 Linux,无需任何编译,因为它只是蟒蛇。

此外,您不需要使用此方法拥有 repo,例如,您可以迁移您不拥有的 SourceForge 项目(您只需要结帐的权利,所以这行得通在任何公共回购)。

如何从 sourceforge CVS 导入到 git。
首先,您需要下载/签出包含整个历史记录的 cvs 存储库(不仅仅是签出 HEAD/Trunk):

rsync -av rsync://PROJECT.cvs.sourceforge.net/cvsroot/PROJECT/\* cvs

然后使用 cvs2git(python 脚本,适用于所有平台,无需编译):

python cvs2git --blobfile="blob.dat" --dumpfile="dump.dat" --username="username_to_access_repo" --options=cvs2git.options --fallback-encoding utf-8 cvs

这应该会生成两个文件blobdump,其中包含您的整个 cvs 历史记录。您可以在文本编辑器中打开它们以检查内容是否正确。

然后在另一个文件夹中初始化你的 git repo:

mkdir gitexport/
cd gitexport
git init

然后将导出的 cvs 历史加载到 git:

cat ../{blob,dump}.dat | git fast-import

然后将 git commit 光标放在历史记录的末尾:

git reset --hard

最后,您可以选择推送到远程 git 存储库:

git push -u origin master

当然你需要先git remote add origin https://your_repo_url

注意:cvs2git.optionscvs2git 的 JSON 格式配置文件,您可以在其中为作者姓名等各种内容指定转换(以便在导入后他们的昵称会自动转换为他们的全名)。请参阅documentation hereincluded example options file

【讨论】:

  • 在浏览并尝试了所有其他解决方案之后,这个解决方案对我有用! :D
  • 它也对我有用,我没有 rsync 选项,但我可以手动复制存储库。请记住始终手动将项目复制到文件夹或执行 rsync 不签出。
  • 在linux上你可以apt install cvs2svn,其中包括cvs2git
  • 当我的 CVS 根目录是“pserver”时,我将如何使用 rsync 应用您的第一行?
  • @einpoklum 很抱歉,我对 CVS 的经验不是很丰富,所以我无法回答您的问题,也许其他人可以?您也可以尝试使用该命令直到它起作用,或者使用可以简化该过程的 TortoiseCVS。
【解决方案2】:

我没有亲自完成从 CVS 到 Git 的转换,但我相信 Eric Raymond 的 cvs-fast-export 是可以使用的工具。他发布了手册页herecvsps 是 Eric 维护的另一个工具,但最近它已被弃用,取而代之的是 cvs-fast-exportcvs2git 是另一种工具,它建立在与 cvs2svn 相同的机器上。后者非常熟练,因此我寄予厚望cvs2git 也同样出色。

需要注意的一点:CVS 是一个非常糟糕的 RCS。它可能包含无法在 Git 中准确反映的内容。换句话说,那里存在一些阻抗不匹配,但工具非常努力地尽可能地保留。确保检查您的转化,并且您对结果感到满意。您可能需要修复部分 Git 历史记录以获得更可接受的内容,但我怀疑您是否需要这样做。

【讨论】:

  • cvs-fast-export 在我看来有一个很大的缺陷......它使用 C。这意味着更难调试问题,特别是因为它在标准输出上输出内容并从标准输入读取。它还根据它们在 RCS 文件中的显示方式对 CVS 修订进行重新编号,如果您试图查明问题,这可能会造成混淆。不过,这应该是公认的答案。 +1
  • 我一开始尝试了cvs2git,但它依赖于任何dbm包和一个dbm引擎,而不是默认的。当您安装所有必需的 Python 库并让它运行时,您已经完成了 10 倍的下载和编译 cvs-fast-export 工作,它不需要任何外部库。我发现 cvs-fast-export 在转换我的 CVS 存储库方面做得非常出色。
【解决方案3】:

您可以use git-cvsimport 将您的 CVS 存储库导入 Git。默认情况下,这将检查每个修订版本,为您提供相对完整的历史记录。

根据您的操作系统,您可能需要单独安装对此的支持。例如,在 Ubuntu 机器上,您将需要 git-cvs 包。

This answer 更详细。

【讨论】:

  • git-cvsimport 更具弹性 w.r.t. CVS 历史上的问题,但这会产生(默默地)不连贯的结果。我一直在阅读关于类似问题的很多关于 SO 的答案,并且想知道有多少人使用具有真正“伤痕”和问题的存储库进行了实际的现实转换。
  • 在我的例子中:cvs-fast-export 没有导入历史,cvs2git 甚至没有导入文件(示例选项文件上的错误),git-cvsimport 使用非常接近 这个答案上面的链接
【解决方案4】:

我最近(2016 年)使用 Eric Raymond 的 reposurgeon 将 CVS 存储库从 sourceforge 导入到 git。我感到非常惊喜,而且效果很好。 在过去使用 cvs2svn 和其他工具的经验之后,我毫不犹豫地推荐 reposurgeon 完成此类任务。

Eric 发布了一个简单的迁移指南here

【讨论】:

    【解决方案5】:

    为了将项目从 sourceforge 克隆到 github,我执行了以下步骤。

    PROJECT=some_sourceforge_project_name
    GITUSER=rubo77
    rsync -av rsync://a.cvs.sourceforge.net/cvsroot/$PROJECT/\* cvs
    svn export --username=guest http://cvs2svn.tigris.org/svn/cvs2svn/trunk cvs2svn-trunk
    cp ./cvs2svn-trunk/cvs2git-example.options ./cvs2git.options
    vim cvs2git.options # edit run_options.set_project
    cvs2svn-trunk/cvs2git --options=cvs2git.options --fallback-encoding utf-8
    

    https://github.com/$GITUSER/$PROJECT.git创建一个空的git

    git clone git@github.com:$GITUSER/$PROJECT.git $PROJECT-github
    cd $PROJECT-github
    cat ../cvs2git-tmp/git-{blob,dump}.dat | git fast-import
    git log
    git reset --hard
    git push
    

    【讨论】:

      【解决方案6】:

      gaborousanswer 使用git fast-import,这可能会在以UTF-8 编码的 日志消息上失败。

      这将更好地与 Git 2.23(2019 年第二季度)一起使用:git fast-export/import”对已被教导更好地处理使用 UTF-8 以外编码的日志消息的提交。

      参见Elijah Newren (newren)commit e80001fcommit 57a8be2commit ccbfc96commit 3edfcc6commit 32615ce(2019 年 5 月 14 日)。
      (由Junio C Hamano -- gitster -- 合并到commit 66dc7b6, 2019 年 6 月 13 日)

      fast-export:仅在请求时才对提交消息进行自动重新编码

      提交消息的自动重新编码(并删除编码标头)会损害进行可逆历史记录重写的尝试(例如 sha1sum sha256sum 转换,一些子树重写),并且似乎与 @ 其他地方遵循的一般原则不一致987654353@ 需要明确的用户请求来修改输出 (例如--signed-tags=strip--tag-of-filtered-object=rewrite)。
      添加用户可用于指定的--reencode 标志,与其他快速导出标志一样,默认为“abort.

      这意味着Documentation/git-fast-export 现在包括:

       --reencode=(yes|no|abort)::
      

      指定如何处理提交对象中的encoding 标头。

      • 当询问'abort'(这是默认值)时,遇到这样的提交对象,这个程序会死掉。
      • 选择“yes”,提交消息将被重新编码为 UTF-8。
      • 使用“否”,将保留原始编码。

      fast-export: 如果我们无法重新编码,请避免剥离编码头

      fast-export 遇到带有“编码”标头的提交时,它会尝试以 UTF-8 重新编码,然后丢弃编码标头。
      但是,如果它无法在 UTF-8 中重新编码,因为例如中的角色之一 提交消息在旧编码中无效,那么我们需要保留原始编码,否则我们会丢失理解原始提交消息中所有其他(有效)字符所需的信息。

      fast-import: 支持 'encoding' 提交头

      由于 git 支持使用非 UTF-8 编码的提交消息,因此允许 fast-import 导入此类提交。
      这对于不想从外部系统重新编码提交消息的人来说可能很有用,并且对于实现可逆的历史重写也可能很有用(例如 sha1sum sha256sum 转换或子树工作)与在其提交历史中使用专门编码的 Git 存储库。

      Documentation/git-fast-import 现在包括:

      编码`

      可选的encoding 命令指示提交消息的编码。
      大多数提交都是 UTF-8 并且省略了编码,但这允许将提交消息导入 git 而无需先重新编码。


      要查看that test,它使用的作者名称中包含非 ascii 字符,但没有 特殊的提交信息。
      它确实通过检查其大小来检查重新编码为 UTF-8 是否有效:

      如果不重新编码,提交对象将是 240 字节。

      • 删除“encoding iso-8859-7\n”标头会减少 20 个字节。
      • Pi character π 从 iso-8859-7 中的 \xF0 (\360) 重新编码为 UTF-8 中的 \xCF\x80 (\317\200) 会增加一个字节。

      检查预期大小。


      使用 Git 2.29(2020 年第四季度),为导入创建的包头得到了更好的管理。

      参见René Scharfe (rscharfe)commit 7744a5dcommit 014f144commit ccb181d(2020 年 9 月 6 日)。
      (由 Junio C Hamano -- gitster -- 合并于 commit 9b80744,2020 年 9 月 18 日)

      fast-import:使用write_pack_header()

      签字人:René Scharfe

      调用write_pack_header() 进行散列并写入包头,而不是对该函数进行开放编码。
      这消除了重复的代码和神奇的版本号 2——自 c90be46abd 以来一直在这里使用(“更改快速导入的包头创建以使用 pack.h”,2006-08-16,Git v1.5.0 -rc4 -- merge)和pack.h(再次)自29f049a0c2(恢复“将包创建移动到版本3”,2006-10-14,Git v1.4.3)。

      【讨论】:

        【解决方案7】:

        使用 cvs2svn

        从 CVS 迁移到 Git

        分享将 CVS 迁移到 git 的所有步骤

        1.在anyDir创建目录一个cvsProject
        Rsync: 你的 cvs 存储库:
         1. $rsync -av CVSUserName@CVSipAddrress:/CVS_Path/ProjectName/* ~/anyDir/ProjectName
        
        2. cd $../cvs2svn-x.x.0 && ./cvs2git --options=cvs2git-example.options
        3. $./cvs2git --blobfile=cvs2git-tmp/git-blob.dat \ --dumpfile=cvs2git-tmp/git-dump.dat \ --username=CVS_YOUR_USER_NAME \ /path_of_step(1)/cvsProject
        注意: 如果遇到任何编码错误,请将其添加到上述命令中:"--encoding=ascii --encoding=utf8 --encoding=utf16 --encoding =拉丁“
        4. mkdir newGitRepo && cd newGitRepo 5. git init --bare 6. git fast-import --export-marks=/x.x.x/cvs2svn-2.5.0/cvs2git-tmp/git-marks.dat \

        现在你已经完成了,现在你可以将你的 repo 推送到 git..

        参考 : [link1][2] ,[link2][2]

        【讨论】:

        • 如果您遇到任何问题,请告诉我
        【解决方案8】:

        我最近使用“CVS 远程访问程序”,或者,crap (GitHub),获得了成功和相对愉快的体验。

        它显然可以处理各种复杂的 CVS 存储库,而其他任何转换工具都没有/不是所有的转换工具都可以,但我并不精通细节。与 cvs2git 一样,它也遵循转储文件的路径,这些转储文件实际上是使用 git-fast-import 导入到 git 中的。

        我建议这样做的原因是,当我发现它存在缺陷时,我能够将我缺少的功能添加到现有代码中 - 这并不是那么糟糕。我的 PR 正在等待处理,还有一堆错误报告。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-06
          • 2021-12-12
          • 2021-08-16
          • 1970-01-01
          • 1970-01-01
          • 2020-12-01
          • 2021-04-30
          • 1970-01-01
          相关资源
          最近更新 更多