代码之家  ›  专栏  ›  技术社区  ›  user9876

如何恢复CVS中的重大更改?

  •  28
  • user9876  · 技术社区  · 17 年前

    他添加和删除了数百个文件,所以简单的“从旧签出和提交中复制文件”是不够的。

    我有RTFM和STFW,我试过:

    cvs co modulename  # Note no -P option
    cvs up -jHEAD -jMAIN:2008-12-30 modulename
    

    我可能可以为此编写一个shell脚本,但这个功能肯定已经存在于CVS中了吗?

    • 我能得到一份工作 在特定日期对模块进行更新。问题是如何将其重新输入CVS。

    • 我确实有备份,但使用CVS这样的版本控制系统的要点是,应该很容易获得任何历史状态。下次发生类似情况时,我可能没有足够的运气进行备份(例如,备份是每天进行的,因此我可能会损失多达一天的工作)。

    更新2:我要开始悬赏了。 要获得赏金,您必须解释如何使用正常的CVS命令而不是黑客shell脚本进行恢复。

    CVS 1.12.13 . 通过pserver进行访问。我可以在Linux PC上使用相同版本的CVS,或者 CVSNT 2.0.51d Windows上的客户端。

    10 回复  |  直到 16 年前
        1
  •  27
  •   Ralph    16 年前

    实际上,您最初的方法非常接近解决方案。问题是,基于日期的加入不能正确处理删除的文件和目录。您需要先将标记设置为要加入的代码库:

    mkdir code_base1 && cd code_base1
    cvs co -D "2008-12-30" modulename
    cvs tag code_base_2008_12_30
    

    cd .. && mkdir code_base2 && cd code_base2
    cvs co modulename
    cvs update -d -j HEAD -j code_base_2008_12_30  # use -d to resurrect deleted directories
    

    比较代码_base1和代码_base2的内容。除了CVS元信息之外,它们应该是相同的。最终将2008年12月30日的代码作为新的头提交:

    cvs commit -m "Revert all changes this year"
    

    请注意,这样标记您希望加入的代码将不起作用,因为在使用-D:

    cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename
    
        2
  •  4
  •   Keltia    17 年前

    1. CVS是面向文件的,没有变更集或snasphot的概念。这意味着像您想要恢复的更改这样的更改有点难以处理。提交是给定目录内的原子提交,而不是外部提交。

    2. -P )你必须具体说明 -d 在签出/更新时创建它们。

    FreeBSD project 并且很快了解CVS有多可恨。。。看见 here 了解我对版本控制软件的一些看法。

        3
  •  2
  •   JW.    17 年前

    cvs co -P modulename
    cvs co -P -jHEAD -jMAIN:2008-12-30 modulename
    

    如果要还原HEAD以外的分支,例如X,请在两个命令中传递-rX参数:

    cvs co -P -rX modulename
    cvs co -P -rX -jHEAD -jMAIN:2008-12-30 modulename
    
        4
  •  1
  •   user9876    17 年前

    # Get woking copy we're going to change
    cd ~/work
    rm -rf modulename
    cvs up -dP modulename
    cd modulename
    
    # Remove all files
    find . -name CVS -prune -o -type f -print | xargs cvs rm -f
    
    # Get the old revision
    cd ~
    mkdir scratch
    cd scratch
    cvs -q co -D 2008-12-31 modulename
    cd modulename
    
    # Copy everything to the working dir and do "cvs add" on it
    find . -name CVS -prune -o -type f -print | \
        xargs tar c | \
        (cd ~/work/modulename && tar xv | \
        xargs cvs add)
    
    # Check everything is OK before we commit
    cd ~/work/modulename
    cvs -nq up
    
    # it gave me an error on readme.txt because I'd deleted and then added it, so:
    mv readme.txt x # save good rev
    cvs add readme.txt # resurrect the bad rev
    mv x readme.txt # clobber file with good rev
    
    # Commit it
    cvs commit -m "Revert all changes this year"
    
    # Delete now-empty directories
    cvs -q up -dP
    
    # Double-check everything is back how it was
    diff -ur -xCVS ~/scratch/modulename ~/work/modulename
    

    然后我发现仍然存在差异——我的同事添加了包含空格的文件名,而这些空格并没有被上述过程删除。我不得不分别删除这些内容。(我应该用 find ... -print0 而不是 -print ,并通过了考试 -0 xargs . 我只是不知道有带空格的文件。)

        5
  •  1
  •   smcameron    16 年前
        6
  •  0
  •   JB.    17 年前

    你有没有试过使用 -d

    据我记忆所及,这意味着 cvs co ,但不是为 cvs up .

        7
  •  0
  •   Colin Ross    17 年前

    http://www.astro.ku.dk/~aake/MHD/docs/CVS.html

    cvs update -D "30 Dec 2008 23:59"
    
        8
  •  0
  •   Rob Anderson Rob Anderson    17 年前

    这是一个大问题,并没有完整的答案,只是关于如何编写脚本来处理文件名中的空格的提示。

    而不是

    find ... | xargs tar c - | ...
    

    试一试推杆

    find ... | perl -e '@names = <>;' -e 'chomp @names;' -e 'system( "tar", "c", "-", @names);' | ...
    

    还有一件事,很可能它真的会工作:如果有一个CVS to SVN实用程序,使用它(我假设这样的实用程序会从“CVS阁楼”中提取删除的文件),然后 如果

        9
  •  0
  •   Russell Silva    14 年前

    如果您或同事对git感到满意,您可以使用 git cvsimport 创建镜像CVS存储库的git存储库。在git中恢复提交/变更集非常简单(使用 git revert ).然后你可以使用 git cvsexportcommit 将恢复提交发送到CVS。

    git cvsimport

        10
  •  0
  •   Tim Cooper    14 年前

    如果您有存储库的备份(服务器上的实际RCS文件,例如磁带上的文件),您可以将CVS服务器上的文件夹恢复到以前的状态。在执行此操作之前,不要忘记停止CVS服务器(然后重新启动它)。