GIT和CVS的区别 [英] Difference between GIT and CVS

查看:91
本文介绍了GIT和CVS的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Git和CVS版本控制系统有什么区别?

我已经快乐地使用CVS 10多年了,现在我被告知Git要好得多。有人能解释一下两者之间的区别是什么,为什么一个人比另一个人好?解析方案

主要区别是(正如在其他回复中已经说过的那样),CVS是(旧的)集中式版本控制系统,而Git是分发的。

但即使您使用版本控制开发人员,在单一机器上(单一帐户),Git和CVS之间有一些差异: 存储库即可。 Git将存储库存储在项目顶部目录的 .git 目录中; CVS需要设置CVSROOT,它是存储不同项目(模块)的版本控制信息的中心位置。这种设计对于用户来说的后果是,将现有源导入版本控制就像Git中的git init& git add。&& git commit一样简单,而它是更加复杂的/ CVS手册:/ximbiot.com/cvs/manual/cvs-1.11.23/cvs_3.html#SEC38 =noreferrertitle =CVS Manual 原子操作。因为CVS在开始时是围绕每个文件的RCS版本控制系统的一组脚本,所以提交(和其他操作)在CVS中不是原子的;如果存储库上的操作在中间被中断,那么存储库可能会处于不一致的状态。在Git中,所有的操作都是原子操作:要么是整体成功,要么是没有任何改变而失败。 CVS中的更改是每个文件,而Git中的更改(提交)时,它们始终引用整个项目。这是非常重要的范式转变。其中一个后果就是Git非常容易恢复(创建撤消变更)或撤消整个变更;其他的结果是在CVS中很容易做到部分签出,而目前在Git中是不可能的。事实上,每个文件的变化被分组在一起,导致在CVS中发明用于提交消息的GNU Changelog格式; Git用户使用(和一些Git工具期望的)不同的约定,用单行描述(汇总)变化,然后是空行,然后是更详细的变更描述。

命名修订/版本号。还有一个问题与CVS更改中的每个文件有关:版本号(如有时在关键字扩展中看到的那样,请参见下文),如1.4反映给定文件已更改多少次。在Git中,整个项目的每个版本(每个提交)都有其唯一的名称,由SHA-1 ID给出;通常前7-8个字符足以识别提交(不能在分布式版本控制系统中使用简单编号方案 - 需要中央编号权限)。在CVS中,版本号或符号名称是指整个项目的状态,您可以使用标记;在Git中也是如此,如果你想在某个项目的某个版本中使用'v1.5.6-rc2'这样的名字......但是Git中的标签更容易使用。

  • 轻松分支。在我看来,CVS分支过于复杂,很难处理。你必须为分支标记一个整个存储库分支的名称(如果我没有记错的话,甚至在某些情况下可能会失败,因为每个文件都有处理)。除此之外,CVS没有合并跟踪,因此您必须记住或者手动标记合并和分支点,并手动为cvs update -j提供正确的信息进行合并分支,这使得分支是不必要的难以使用。在Git创建和合并分支是非常容易的; Git自己记得所有需要的信息(所以合并分支就像git merge branchname 一样简单)......它不得不这样做,因为分布式开发自然会导致多个分支。

    b
    $ b

    这意味着您可以使用主题分支,即在单独的功能分支的多个步骤中开发单独的功能。

  • b $ b
  • 重命名(和复制)跟踪。 CVS中不支持文件重命名,手动重命名可能会将历史记录分为两部分,或导致无效的历史记录,无法在重命名之前正确恢复项目的状态。基于内容和文件名的相似性,Git使用启发式重命名检测(此解决方案在实践中运行良好)。您还可以请求检测文件的复制。这意味着:当检查指定的提交时,你会得到一些文件被重命名的信息,


  • >合并正确地将重命名考虑在内(例如,如果该文件只在一个分支中重命名)

  • git blame,这是(cvs annotate)显示文件内容的行式历史记录,也可以在整个重命名之后遵循代码移动


  • 二进制文件

  • STRONG>。 CVS对二进制文件(例如图像)的支持非常有限,要求用户在添加(或者稍后使用cvs admin,或者通过包装自动根据文件名自动执行该操作)时显式标记二进制文件,以避免二进制文件通过行末转换和关键字扩展。 Git以同样的方式基于内容自动检测二进制文件CNU diff和其他工具可以完成这些工作;您可以使用gitattributes机制覆盖此检测。此外,由于'safecrlf'上的默认值(以及您必须请求末尾转换,尽管这可能会根据分配情况默认打开),并且该(有限)关键字可以防止无法恢复的损坏在Git中,扩展是一种严格的选择加入。
  • 关键字扩展。与CVS相比,Git提供了非常有限的一组关键字(默认情况下)。这是因为两个事实:Git中的更改是每个存储库而不是每个文件,并且Git避免修改切换到其他分支或倒回到历史中其他点时未更改的文件。如果你想使用Git嵌入修订版本号,你应该使用你的构建系统来完成这个工作。以下是Linux内核源代码和Git源代码中GIT-VERSION-GEN脚本的示例。

  • 因为在分布式VCS(如Git)中, 独立于创建提交,所以可以更改(编辑,重写)未发布的历史记录部分,而不会给其他用户造成不便。特别是如果你注意到提交信息中的错字(或其他错误)或提交中的错误,你可以简单地使用git commit --amend。这在CVS中是不可能的(至少不是没有沉重的骇客)。 更多工具
    。 Git提供比CVS更多的工具。其中一个更重要的是
    git bisect ,可用于查找引入错误的提交(修订版);如果你的提交很小并且是独立的,那么它应该相当容易,然后发现错误在哪里。 b
    b
    $ b

    如果您与至少一位其他开发人员合作,您会发现Git和CVS之间还存在以下差异:


    • 合并前提交 Git使用 commit-before-merge 而不是像CVS一样, merge-before-commit (或 update-then-commit )。如果在编辑文件时,准备创建新的提交(新版本),其他人在同一分支上创建了新的提交,并且它现在存在于存储库中,CVS强制您首先更新您的工作目录并解决冲突,然后再允许您提交。 Git并非如此。您首先提交,将版本保存在版本控制中,然后合并其他开发人员更改。您还可以让其他开发人员进行合并并解决冲突。



      如果您希望获得线性历史记录并避免合并,则始终可以使用 commit-通过git rebase(和git pull --rebase)合并重新提交工作流,类似于CVS,因为您可以在更新后的状态之上重播更改。但是你总是首先提交。

    • 没有必要使用中央存储库你的改变。每个开发人员都可以拥有自己的存储库(或更好的存储库:他/她进行开发的私有存储库,以及公布该部分已准备就绪的公共存储库),并且可以从其他存储库中提取/获取对称的时尚。另一方面,大型项目通常会定义/指定中央存储库,每个人都从中获取(从中获取更改)。


      ul>




      最后,当需要与大量开发人员进行协作时,Git提供了更多的可能性。下面是Git中针对不同感兴趣阶段的CVS与项目中的位置(使用CVS或Git的版本控制下)之间的差异:

      <强>潜伏者即可。如果您只想从项目中获取最新更改(不传播您的更改),或者正在开发 private 开发项目(无需返回原始项目);或者使用外国项目作为自己项目的基础(更改是本地的,发布它们没有意义)。



      Git支持 匿名未认证 通过自定义高效的 git:/ / 协议,或者如果您在防火墙后面阻止 DEFAULT_GIT_PORT (9418),则可以使用普通HTTP。



      对于CVS最常见的解决方案(据我了解)只读访问是 guest账户 ,用于上的'pserver'协议。 CVS_AUTH_PORT (2401),通常称为匿名并且密码为空。凭证默认存储在 $ HOME / .cvspass 文件中,因此您必须仅提供一次;尽管如此,这还是有点障碍(你必须知道访客帐户的名称,或注意CVS服务器信息)和烦恼。 附带开发者(叶贡献者)。在OSS中传播更改的一种方式是通过电子邮件发送补丁。如果您(或多或少)是意外开发人员,发送单个更改或单个错误修复,则这是最常见的解决方案。 BTW。发送补丁可能是通过审查委员会(补丁评论系统)或类似的手段,不仅通过电子邮件。



      Git在这里提供的工具有助于这种传播(发布)机制发件人(客户端)和维护者(服务器)。对于希望通过电子邮件发送更改的用户,可以使用 git rebase (或git pull --rebase)工具在当前上游版本之上重播您自己的更改,因此您的更改将在当前版本之上(是新鲜的),并且 git格式-patch 创建具有提交信息(和作者身份)的电子邮件,更改(扩展)统一差异格式(加diffstat以便于查看)。维护人员可以直接将此类电子邮件转换为使用 git am



      CVS不提供这样的工具:您可以使用cvs diff/cvs rdiff来生成更改,并使用GNU补丁来应用更改,但据我所知,无法自动应用提交消息。 CVS意在用于客户端 - 服务器时尚... 如果您是项目(子系统)的独立部分的维护者,或者您的项目开发遵循Linux内核开发过程中使用的信任网络工作流程,或者只是您拥有自己的公共存储库,并且更改了您想要发布太大以至于无法通过电子邮件发送 patch series ,则可以向项目的(主要)维护者发送 pull request



      这是针对分布式版本控制系统的解决方案,因此CVS当然不支持这种协作方式。甚至还有一个名为git request-pull的工具,它有助于准备发送给维护人员的电子邮件,请求从存储库中提取。感谢git bundle,即使没有公共存储库,也可以通过电子邮件或sneakernet发送一系列更改来使用此机制。某些Git托管网站(如 GitHub )支持通知某人正在为您的项目工作(发布了一些工作)(前提是他/她使用相同的Git托管站点),并为PM提供一种拉取请求。 直接发布他/她的更改(到主/规范存储库)的人。这个类别对于分布式版本控制系统更为广泛,因为让多个开发人员拥有对中央存储库的写入访问权限不仅是可能的工作流程(您可以让单个维护人员 推动 更改为规范存储库,他/她所从中挑选的一组副手/子系统维护人员,以及通过邮件向维护人员/项目邮件列表或其中一名副手/子维护人员发送补丁的大量叶开发人员)。

      使用Git,您可以选择使用 SSH协议(SSH中包装的git协议)发布更改,并使用诸如git shell之类的工具(以帮助安全,限制访问shell帐户)或 Gitosis (用于管理访问而无需单独的shell帐户)和 HTTPS 与WebDAV,普通的HTTP认证。



      使用CVS,您可以在自定义未加密(纯文本) pserver 协议或使用远程shell (您真的应该使用 SSH )发布您的更改,这对于集中式版本控制系统来说意味着提交更改(创建提交)。那么,你也可以使用SSH隧道'pserver'协议,并且有派对工具可以自动执行此操作......但我不认为这很容易。 Gitosis。



    一般而言,分布式版本控制系统(例如Git)提供更广泛的可能工作流程选择。使用CVS等集中式版本控制系统时,必须区分具有对存储库的提交访问权限的人员,以及不具有...的人员,而CVS不提供任何工具来帮助接受来自人员的贡献(通过补丁)提交访问。



    Karl Fogel在生产开源软件在版本控制部分指出,最好不要对允许更改公共存储库的区域提供过于严格,严格和严格的控制;依靠(为此)社会限制(比如代码审查)而不是技术限制要好得多;分布式版本控制系统甚至可以进一步减少恕我直言...



    HTH (希望有所帮助)

    What is the difference between Git and CVS version control systems?

    I have been happily using CVS for over 10 years, and now I have been told that Git is much better. Could someone please explain what the difference between the two is, and why one is better than the other?

    解决方案

    The main difference is that (as it was already said in other responses) CVS is (old) centralized version control system, while Git is distributed.

    But even if you use version control for single developer, on single machine (single account), there are a few differences between Git and CVS:

    • Setting up repository. Git stores repository in .git directory in top directory of your project; CVS require setting up CVSROOT, a central place for storing version control info for different projects (modules). The consequence of that design for user is that importing existing sources into version control is as simple as "git init && git add . && git commit" in Git, while it is more complicated in CVS.

    • Atomic operations. Because CVS at beginning was a set of scripts around per-file RCS version control system, commits (and other operations) are not atomic in CVS; if an operation on the repository is interrupted in the middle, the repository can be left in an inconsistent state. In Git all operations are atomic: either they succeed as whole, or they fail without any changes.

    • Changesets. Changes in CVS are per file, while changes (commits) in Git they always refer to the whole project. This is very important paradigm shift. One of consequences of this is that it is very easy in Git to revert (create a change that undoes) or undo whole change; other consequence is that in CVS is easy to do partial checkouts, while it is currently next to impossible in Git. The fact that changes are per-file, grouped together led to invention of GNU Changelog format for commit messages in CVS; Git users use (and some Git tools expect) different convention, with single line describing (summarizing) change, followed by empty line, followed by more detailed description of changes.

    • Naming revisions / version numbers. There is another issue connected with the fact that in CVS changes are per files: version numbers (as you can see sometimes in keyword expansion, see below) like 1.4 reflects how many time given file has been changed. In Git each version of a project as a whole (each commit) has its unique name given by SHA-1 id; usually first 7-8 characters are enough to identify a commit (you can't use simple numbering scheme for versions in distributed version control system -- that requires central numbering authority). In CVS to have version number or symbolic name referring to state of project as a whole you use tags; the same is true in Git if you want to use name like 'v1.5.6-rc2' for some version of a project... but tags in Git are much easier to use.

    • Easy branching. Branches in CVS are in my opinion overly complicated, and hard to deal with. You have to tag branches to have a name for a whole repository branch (and even that can fail in some cases, if I remember correctly, because of per-file handling). Add to that the fact that CVS doesn't have merge tracking, so you have to either remember, or manually tag merges and branching points, and manually supply correct info for "cvs update -j" to merge branches, and it makes for branching to be unnecessary hard to use. In Git creating and merging branches is very easy; Git remembers all required info by itself (so merging a branch is as easy as "git merge branchname")... it had to, because distributed development naturally leads to multiple branches.

      This means that you are able to use topic branches, i.e. develop a separate feature in multiple steps in separate feature branch.

    • Rename (and copy) tracking. File renames are not supported in CVS, and manual renaming might break history in two, or lead to invalid history where you cannot correctly recover the state of a project before rename. Git uses heuristic rename detection, based on similarity of contents and filename (This solution works well in practice). You can also request detecting of copying of files. This means that:

      • when examining specified commit you would get information that some file was renamed,
      • merging correctly takes renames into account (for example if the file was renamed only in one branch)
      • "git blame", the (better) equivalent of "cvs annotate", a tool to show line-wise history of a file contents, can follow code movement also across renames
    • Binary files. CVS has only a very limited support for binary files (e.g. images), requiring users to mark binary files explicitly when adding (or later using "cvs admin", or via wrappers to do that automatically based on file name), to avoid mangling of binary file via end-of-line conversion and keyword expansion. Git automatically detects binary file based on contents in the same way CNU diff and other tools do it; you can override this detection using gitattributes mechanism. Moreover binary files are safe against unrecoverable mangling thanks to default on 'safecrlf' (and the fact that you have to request end-of-line conversion, although this might be turned on by default depending on distribution), and that (limited) keyword expansion is a strict 'opt-in' in Git.

    • Keyword expansion. Git offers a very, very limited set of keywords as compared to CVS (by default). This is because of two facts: changes in Git are per repository and not per file, and Git avoids modifying files that did not change when switching to other branch or rewinding to other point in history. If you want to embed revision number using Git, you should do this using your build system, e.g. following example of GIT-VERSION-GEN script in Linux kernel sources and in Git sources.

    • Amending commits. Because in distributed VCS such as Git act of publishing is separate from creating a commit, one can change (edit, rewrite) unpublished part of history without inconveniencing other users. In particular if you notice typo (or other error) in commit message, or a bug in commit, you can simply use "git commit --amend". This is not possible (at least not without heavy hackery) in CVS.

    • More tools. Git offers much more tools than CVS. One of more important is "git bisect" that can be used to find a commit (revision) that introduced a bug; if your commits are small and self-contained it should be fairly easy then to discover where the bug is.


    If you are collaboration with at least one other developer, you would find also the following differences between Git and CVS:

    • Commit before merge Git uses commit-before-merge rather than, like CVS, merge-before-commit (or update-then-commit). If while you were editing files, preparing for creating new commit (new revision) somebody other created new commit on the same branch and it is now in repository, CVS forces you to first update your working directory and resolve conflicts before allowing you to commit. This is not the case with Git. You first commit, saving your state in version control, then you merge other developer changes. You can also ask the other developer to do the merge and resolve conflicts.

      If you prefer to have linear history and avoid merges, you can always use commit-merge-recommit workflow via "git rebase" (and "git pull --rebase"), which is similar to CVS in that you replay your changes on top of updated state. But you always commit first.

    • No need for central repository With Git there is no need to have single central place where you commit your changes. Each developer can have its own repository (or better repositories: private one in which he/she does development, and public bare one where she/he publishes that part which is ready), and they can pull/fetch from each other repositories, in symmetric fashion. On the other hand it is common for larger project to have socially defined/nominated central repository from which everyone pull from (get changes from).


    Finally Git offers many more possibilities when collaboration with large number of developers is needed. Below there are differences between CVS in Git for different stages of interest and position in a project (under version control using CVS or Git):

    • lurker. If you are interested only in getting latest changes from a project, (no propagation of your changes), or doing private development (without contributing back to original projects); or you use foreign projects as a basis of your own project (changes are local and doesn't it make sense to publish them).

      Git supports here anonymous unauthenticated read-only access via custom efficient git://protocol, or if you are behind firewall blocking DEFAULT_GIT_PORT (9418) you can use plain HTTP.

      For CVS most common solution (as I understand it) for read-only access is guest account for 'pserver' protocol on CVS_AUTH_PORT (2401), usually called "anonymous" and with empty password. Credentials are stored by default in $HOME/.cvspass file, so you have to provide it only once; still, this is a bit of barrier (you have to know name of guest account, or pay attention to CVS server messages) and annoyance.

    • fringe developer (leaf contributor). One way of propagating your changes in OSS is sending patches via email. This is most common solution if you are (more or less) accidental developer, sending single change, or single bugfix. BTW. sending patches might be via review board (patch review system) or similar means, not only via email.

      Git offers here tools which help in this propagation (publishing) mechanism both for sender (client), and for maintainer (server). For people who want send their changes via email there is "git rebase" (or "git pull --rebase") tool to replay your own changes on top of current upstream version, so your changes are on top of current version (are fresh), and "git format-patch" to create email with commit message (and authorship), change in the form of (extended) unified diff format (plus diffstat for easier review). Maintainer can turn such email directly into commit preserving all information (including commit message) using "git am".

      CVS offer no such tools: you can use "cvs diff" / "cvs rdiff" to generate changes, and use GNU patch to apply changes, but as far as I know there is no way to automate applying commit message. CVS was meant to be used in client <-> server fashion...

    • lieutenant. If you are maintainer of separate part of a project (subsystem), or if development of your project follows "network of trust" workflow used in development of Linux kernel... or just if you have your own public repository, and the changes you want to publish are too large to send via email as patch series, you can send pull request to (main) maintainer of project.

      This is solution specific to distributed version control systems, so of course CVS doesn't support such way of collaboration. There is even a tool called "git request-pull" which help to prepare email to send to maintainer with request to pull from your repository. Thanks to "git bundle" you can use this mechanism even without having public repository, by sending bundle of changes via email or sneakernet. Some of Git hosting sites like GitHub have support for notifying that somebody is working (published some work) on your project (provided that he/she uses the same Git hosting site), and for PM-ing a kind of pull request.

    • main developer, i.e. somebody who directly publish his/her changes (to main/canonical repository). This category is broader for distributed version control systems, as having multiple developers with write access to central repository is not only possible workflow (you can have single maintainer who pushes changes to canonical repository, a set of lieutenants/subsystem maintainers from which he/she pulls, and broad range of leaf developers who send patches via mail either to maintainer/project mailing list, or to one of lieutenants/submaintainers).

      With Git you have choice of using SSH protocol (git protocol wrapped in SSH) to publish changes, with tools such as "git shell" (to help security, limiting access of shell accounts) or Gitosis (to manage access without requiring separate shell accounts), and HTTPS with WebDAV, with ordinary HTTP authentication.

      With CVS there is a choice between custom unencrypted (plain text) pserver protocol, or using remote shell (where you really should use SSH) to publish your changes, which for centralized version control system means committing your changes (creating commits). Well, you can also tunnel 'pserver' protocol using SSH, and there are thir party tools automating this... but I don't think this is as easy as e.g. Gitosis.

    In general distributed version control systems, such as Git, provide much wider selection of possible workflows. With centralized version control systems, such as CVS, by necessity you have to distinguish between people with commit access to repository, and those without... and CVS doesn't offer any tools to help with accepting contributions (via patches) from people without commit access.

    Karl Fogel in Producing Open Source Software in section about version control states that it is better to not provide too strict, rigid and rigorous controls on areas where one is allowed to make changes to public repository; it is much better to rely (for this) on social restrictions (such as code review) than on technical restrictions; distributed version control systems reduce that IMHO even further...

    HTH (Hope That Helps)

    这篇关于GIT和CVS的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆