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

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

问题描述

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

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

我已经愉快地使用 CVS 超过 10 年了,现在我被告知 Git 好多了.有人可以解释一下两者之间的区别是什么,为什么一个比另一个更好?

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?

推荐答案

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

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

但是即使你对单个开发者使用版本控制,在单机(单个账户)上,Git 和 CVS 还是有一些区别的:

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

  • 设置存储库.Git 将存储库存储在项目顶层目录的 .git 目录中;CVS 需要设置 CVSROOT,这是一个用于存储不同项目(模块)版本控制信息的中心位置.对于用户来说,这种设计的结果是将现有源导入版本控制就像 Git 中的git init && git add . && git commit"一样简单,而它是 在 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.

原子操作.因为 CVS 一开始是围绕每个文件的 RCS 版本控制系统的一组脚本,所以提交(和其他操作)在 CVS 中不是原子的;如果对存储库的操作在中间中断,则存储库可能会处于不一致状态.在 Git 中,所有操作都是原子的:要么整体成功,要么不做任何更改就失败.

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.

变更集.CVS 中的更改是针对每个文件的,而 Git 中的更改(提交)总是指整个项目.这是非常重要的范式转变.这样做的后果之一是,在 Git 中很容易恢复(创建一个可撤销的更改)或撤消整个更改;另一个后果是在 CVS 中很容易进行部分检出,而目前在 Git 中几乎不可能.更改是按文件分组的,这一事实导致了 CVS 中提交消息的 GNU Changelog 格式的发明;Git 用户使用(和一些 Git 工具期望的)不同的约定,用单行描述(总结)更改,然后是空行,然后是更详细的更改描述.

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.

命名修订/版本号.还有一个与 CVS 更改是每个文件有关的问题:版本号(正如您有时在 关键字扩展 中所见,见下文)如 1.4 反映给定文件已更改的次数.在 Git 中,项目的每个版本作为一个整体(每个提交)都有由 SHA-1 id 给出的唯一名称;通常前 7-8 个字符足以识别提交(您不能对分布式版本控制系统中的版本使用简单的编号方案——这需要中央编号权限).在 CVS 中,要让版本号或符号名称作为一个整体来引用项目的状态,您可以使用 标签;如果您想对某个项目版本使用v1.5.6-rc2"之类的名称,那么在 Git 中也是如此……但 Git 中的标签更易于使用.

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.

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

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.

重命名(和复制)跟踪.CVS 不支持文件重命名,手动重命名可能会将历史记录一分为二,或者导致无效历史记录,您无法在重命名前正确恢复项目的状态.Git 使用启发式重命名检测,基于内容和文件名的相似性(此解决方案在实践中效果很好).您还可以请求检测文件的复制.这意味着:

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:

  • 当检查指定的提交时,你会得到一些文件被重命名的信息,
  • 正确合并会考虑重命名(例如,如果文件仅在一个分支中重命名)
  • git blame",(更好的)等价于cvs annotate",一种显示文件内容逐行历史的工具,也可以跨重命名跟踪代码移动

二进制文件.CVS 对二进制文件(例如图像)的支持非常有限,需要用户在添加时显式标记二进制文件(或稍后使用cvs admin",或通过包装器根据文件名自动执行此操作),以避免对二进制文件进行修改通过行尾转换和关键字扩展的二进制文件.Git根据内容自动检测二进制文件,方法与CNU diff和其他工具相同;您可以使用 gitattributes 机制覆盖此检测.此外,由于safecrlf"的默认设置(以及您必须请求行尾转换的事实,尽管这可能在默认情况下根据发行版而被打开),以及那个(有限的)关键字,二进制文件对于不可恢复的修改是安全的扩展是 Git 中严格的选择加入".

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.

关键字扩展.与 CVS(默认情况下)相比,Git 提供的关键字集非常非常有限.这是因为两个事实:Git 中的更改是针对每个存储库而不是针对每个文件的,并且 Git 避免修改在切换到其他分支或回滚到历史记录的其他点时没有更改的文件.如果你想使用 Git 嵌入修订号,你应该使用你的构建系统来做到这一点,例如以下是 Linux 内核源代码和 Git 源代码中的 GIT-VERSION-GEN 脚本示例.

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.

修改提交.因为在诸如 Git 之类的分布式 VCS 中,发布 的行为与创建提交是分开的,因此可以更改(编辑、重写)未发布的部分历史记录,而不会给其他用户带来不便.特别是如果您注意到提交消息中的错字(或其他错误),或提交中的错误,您可以简单地使用git commit --amend".这在 CVS 中是不可能的(至少在没有大量黑客的情况下不可能).

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.

更多工具.Git 提供的工具比 CVS 多得多.更重要的一个是git bisect" 可用于查找引入错误的提交(修订版);如果您的提交很小并且是独立的,那么应该很容易发现错误所在.

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.

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

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

  • 在合并前提交 Git 使用 commit-before-merge 而不是像 CVS 一样,merge-before-commit(或更新然后提交).如果在您编辑文件、准备创建新提交(新修订)时,其他人在同一分支上创建了新提交并且它现在在存储库中,CVS 会强制您首先更新您的工作目录并解决冲突,然后再允许您提交.这不是 Git 的情况.您首先提交,在版本控制中保存您的状态,然后合并其他开发人员更改.您也可以要求其他开发者进行合并并解决冲突.

  • 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.

如果你更喜欢线性历史并避免合并,你总是可以通过git rebase"(和git pull --rebase")使用 commit-merge-recommit 工作流,这很相似到 CVS,因为您可以在更新的状态之上重放更改.但你总是先提交.

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.

无需中央存储库 使用 Git,您无需在单一的中央位置提交更改.每个开发人员都可以拥有自己的存储库(或更好的存储库:他/她在其中进行开发的私有存储库,以及她/她发布准备好的部分的公共裸存储库),并且他们可以从彼此的存储库中提取/获取对称时尚.另一方面,大型项目通常具有社会定义/指定的中央存储库,每个人都从中提取(从中获取更改).

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).

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

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 支持此处匿名未经身份验证通过自定义高效git://协议的只读访问,或者如果您在防火墙阻止之后DEFAULT_GIT_PORT (9418) 你可以使用纯 HTTP.

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.

对于 CVS,只读访问的最常见解决方案(据我所知)是 guest account 用于 CVS_AUTH_PORT 上的pserver"协议(2401),通常称为匿名"且密码为空.凭据默认存储在 $HOME/.cvspass 文件中,因此您只需提供一次;尽管如此,这还是有点障碍(您必须知道访客帐户的名称,或者注意 CVS 服务器消息)和烦恼.

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.

边缘开发者(叶子贡献者).在 OSS 中传播更改的一种方法是通过电子邮件发送补丁.如果您是(或多或少)意外开发人员、发送单个更改或单个错误修复,这是最常见的解决方案.顺便提一句.可以通过审查委员会(补丁审查系统)或类似方式发送补丁,而不仅仅是通过电子邮件.

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 在这里提供了一些工具,可以帮助发送者(客户端)和维护者(服务器)实现这种传播(发布)机制.对于想要通过电子邮件发送更改的人,有git rebase"(或git pull --rebase")工具在当前上游版本之上重放您自己的更改,因此您的更改位于当前版本之上(是新鲜的),并且git 格式-patch" 以创建带有提交消息(和作者身份)的电子邮件,以(扩展的)统一差异格式的形式进行更改(加上 diffstat 以便于查看).维护者可以使用git am".

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 没有提供这样的工具:您可以使用cvs diff"/cvs rdiff"来生成更改,并使用 GNU 补丁来应用更改,但据我所知,没有办法自动应用提交消息.CVS 旨在用于客户端 <->服务器时尚...

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...

中尉.如果您是项目(子系统)独立部分的维护者,或者您的项目的开发遵循 Linux 内核开发中使用的信任网络"工作流程……或者您拥有自己的公共存储库,并且您的更改想要发布太大而无法通过电子邮件作为补丁系列发送,您可以将拉取请求发送给项目的(主要)维护者.

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.

这是专用于分布式版本控制系统的解决方案,因此CVS当然不支持这种协作方式.甚至还有一个名为git request-pull"的工具,它有助于准备电子邮件以发送给维护者,并请求从您的存储库中提取.感谢git bundle",即使没有公共存储库,您也可以通过电子邮件或运动鞋网发送更改包来使用此机制.一些 Git 托管站点,例如 GitHub 支持通知有人正在您的项目上工作(发布了一些工作)(前提是他/she 使用相同的 Git 托管站点),并用于 PM-ing 一种拉取请求.

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).

对于 Git,您可以选择使用 SSH 协议(SSH 中包装的 git 协议)来发布更改,使用诸如git shell"之类的工具(帮助安全,限制 shell 帐户的访问)或Gitosis(无需单独的 shell 帐户即可管理访问),以及带有 WebDAV 的 HTTPS,以及普通的 HTTP 身份验证.

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.

使用 CVS 可以选择自定义未加密(纯文本) pserver 协议,或使用远程外壳(您真正应该使用的地方)SSH) 发布您的更改,对于集中 版本控制系统而言,这意味着提交您的更改(创建提交).好吧,您也可以使用 SSH 隧道pserver"协议,并且有第三方工具可以自动执行此操作……但我认为这并不像例如Gitosis.

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.

在一般的分布式版本控制系统中,例如 Git,提供了更广泛的可能工作流选择.使用集中的版本控制系统,比如 CVS,你必须区分对存储库有提交访问权限的人和没有...提交访问.

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 在 生产开源软件软件在版本控制部分指出,对于允许对公共存储库进行更改的区域,最好不要提供过于严格、死板和严格的控制;依靠(为此)社会限制(例如代码审查)比技术限制要好得多;分布式版本控制系统进一步减少了恕我直言......

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 (希望有帮助)

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

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