GIT 和 CVS 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/802573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between GIT and CVS
提问by jay
What is the difference between Git and CVS version control systems?
Git 和 CVS 版本控制系统有什么区别?
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 超过 10 年了,现在我被告知 Git 好多了。有人可以解释一下两者之间的区别是什么,为什么一个比另一个好?
回答by Jakub Nar?bski
The main difference is that (as it was already said in other responses) CVS is (old) centralized version control system, while Git is distributed.
主要区别在于(正如在其他回复中已经说过的那样)CVS 是(旧的)集中式版本控制系统,而 Git 是分布式的。
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 和 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 complicatedin 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 wholechange; 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 publishingis 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.
设置存储库。Git将存储库存储在
.git
项目顶级目录的目录中;CVS 需要设置 CVSROOT,这是一个用于存储不同项目(模块)版本控制信息的中心位置。对于用户来说,这种设计的结果是将现有源导入版本控制就像 Git 中的“git init && git add . && git commit”一样简单,而在 CVS 中则更复杂。原子操作。因为 CVS 一开始是围绕每个文件的 RCS 版本控制系统的一组脚本,所以提交(和其他操作)在 CVS 中不是原子的;如果对存储库的操作在中间中断,则存储库可能会处于不一致的状态。在 Git 中,所有操作都是原子的:要么整体成功,要么失败而不做任何更改。
变更集。CVS 中的更改是针对每个文件的,而 Git 中的更改(提交)总是指整个项目。这是非常重要的范式转变。这样做的后果之一是,在 Git 中很容易恢复(创建可撤销的更改)或撤消整个更改;另一个后果是在 CVS 中很容易进行部分检出,而目前在 Git 中几乎不可能。更改是按文件分组的,这一事实导致了 CVS 中提交消息的 GNU Changelog 格式的发明;Git 用户使用(和一些 Git 工具期望)不同的约定,用单行描述(总结)更改,然后是空行,然后是更详细的更改描述。
命名修订/版本号。还有一个与 CVS 中每个文件的更改有关的问题:版本号(有时您可以在关键字扩展中看到,见下文),如 1.4 反映给定文件已更改的次数。在 Git 中,整个项目的每个版本(每次提交)都有其唯一的名称,由 SHA-1 id 给出;通常前 7-8 个字符足以识别提交(您不能对分布式版本控制系统中的版本使用简单的编号方案——这需要中央编号权限)。在 CVS 中要有版本号或符号名称来指代整个项目的状态,你使用标签; 如果您想为某个项目版本使用“v1.5.6-rc2”之类的名称,那么在 Git 中也是如此……但 Git 中的标签更易于使用。
容易分支。CVS 中的分支在我看来过于复杂,难以处理。您必须标记分支以获得整个存储库分支的名称(如果我没记错的话,即使在某些情况下也会失败,因为每个文件处理)。再加上 CVS 没有合并跟踪这一事实,因此您必须记住或手动标记合并和分支点,并手动为“cvs update -j”提供正确的信息以合并分支,这有助于分支不必要的难以使用。在 Git 中创建和合并分支非常容易;Git 自己记住所有需要的信息(所以合并一个分支就像“git merge branchname”一样简单)......它必须这样做,因为分布式开发自然会导致多个分支。
这意味着您可以使用主题分支,即在单独的功能分支中的多个步骤中开发单独的功能。
重命名(和复制)跟踪。CVS 不支持文件重命名,手动重命名可能会将历史记录一分为二,或者导致无效的历史记录,您无法在重命名前正确恢复项目的状态。Git 使用启发式重命名检测,基于内容和文件名的相似性(此解决方案在实践中效果很好)。您还可以请求检测文件的复制。这意味着:
- 在检查指定的提交时,你会得到一些文件被重命名的信息,
- 正确合并会考虑重命名(例如,如果文件仅在一个分支中重命名)
- “gitblame”,(更好的)相当于“cvs annotate”,一种显示文件内容逐行历史的工具,也可以在重命名时跟踪代码移动
二进制文件。CVS 对二进制文件(例如图像)的支持非常有限,需要用户在添加时显式标记二进制文件(或稍后使用“cvs admin”,或通过包装器根据文件名自动执行此操作),以避免对二进制文件进行修改通过行尾转换和关键字扩展的二进制文件。Git 会根据内容自动检测二进制文件,方法与 CNU diff 和其他工具相同;您可以使用 gitattributes 机制覆盖此检测。此外,由于“safecrlf”的默认设置(以及您必须请求行尾转换的事实,尽管这可能在默认情况下根据发行版而被打开),以及那个(有限的)关键字,二进制文件对于不可恢复的修改是安全的扩展是 Git 中严格的“选择加入”。
关键字扩展。与 CVS(默认情况下)相比,Git 提供了非常非常有限的关键字集。这是因为两个事实:Git 中的更改是针对每个存储库而不是针对每个文件的,并且 Git 避免修改在切换到其他分支或回滚到历史记录中的其他点时没有更改的文件。如果你想使用 Git 嵌入修订号,你应该使用你的构建系统来做到这一点,例如在 Linux 内核源代码和 Git 源代码中的 GIT-VERSION-GEN 脚本示例。
修改 commits。因为在诸如 Git 之类的分布式 VCS 中,发布行为与创建提交是分开的,因此可以更改(编辑、重写)未发布的部分历史记录,而不会给其他用户带来不便。特别是如果您注意到提交消息中的错字(或其他错误),或提交中的错误,您可以简单地使用“git commit --amend”。这在 CVS 中是不可能的(至少在没有大量黑客的情况下不可能)。
更多工具。Git 提供的工具比 CVS 多得多。其中一个更重要的是“ git bisect”,它可用于查找引入错误的提交(修订版);如果您的提交很小并且是独立的,那么发现错误所在应该相当容易。
If you are collaboration with at least one other developer, you would find also the following differences between Git and CVS:
如果您与至少一位其他开发人员合作,您还会发现 Git 和 CVS 之间的以下差异:
Commit before mergeGit uses commit-before-mergerather 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-recommitworkflow 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 repositoryWith 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 sociallydefined/nominated central repository from which everyone pull from (get changes from).
在合并之前提交Git 使用提交前合并,而不是像 CVS 一样,在提交前合并(或更新然后提交)。如果在您编辑文件、准备创建新提交(新修订)时,其他人在同一分支上创建了新提交并且它现在在存储库中,CVS 会强制您首先更新您的工作目录并解决冲突,然后再允许您提交。这不是 Git 的情况。您首先提交,在版本控制中保存您的状态,然后合并其他开发人员更改。您还可以要求其他开发人员进行合并并解决冲突。
如果您更喜欢线性历史记录并避免合并,您始终可以通过“git rebase”(和“git pull --rebase”)使用commit-merge-recommit工作流,这与 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):
最后,当需要与大量开发人员合作时,Git 提供了更多的可能性。下面是 Git 中 CVS 之间针对项目中不同阶段和位置的差异(在使用 CVS 或 Git 的版本控制下):
lurker. If you are interested only in getting latest changes from a project, (no propagation of your changes), or doing privatedevelopment (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 unauthenticatedread-only access via custom efficient
git://
protocol, or if you are behind firewall blockingDEFAULT_GIT_PORT
(9418) you can use plain HTTP.For CVS most common solution (as I understand it) for read-only access is guest accountfor '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 requestto (main) maintainer of project.
This is solution specific to distributedversion 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 GitHubhave 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 publishhis/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 pusheschanges 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 HTTPSwith WebDAV, with ordinary HTTP authentication.
With CVS there is a choice between custom unencrypted (plain text)pserverprotocol, or using remote shell(where you really should use SSH) to publish your changes, which for centralizedversion 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 在这里通过自定义高效协议支持匿名未经身份验证的只读访问
git://
,或者如果您在防火墙阻止DEFAULT_GIT_PORT
(9418)后面,您可以使用普通 HTTP。对于 CVS,只读访问的最常见解决方案(据我所知)是(2401)上的“pserver”协议的来宾帐户
CVS_AUTH_PORT
,通常称为“匿名”且密码为空。凭据默认存储在$HOME/.cvspass
文件中,因此您只需提供一次;尽管如此,这还是有点障碍(您必须知道访客帐户的名称,或者注意 CVS 服务器消息)和烦恼。边缘开发人员(叶子贡献者)。在 OSS 中传播更改的一种方法是通过电子邮件发送补丁。如果您是(或多或少)意外开发人员、发送单个更改或单个错误修复,这是最常见的解决方案。顺便提一句。发送补丁可能是通过委员会(补丁系统)或类似方式,而不仅仅是通过电子邮件。
Git 在这里提供了一些工具,这些工具有助于发送者(客户端)和维护者(服务器)的这种传播(发布)机制。对于想要通过电子邮件发送更改的人,有“ git rebase”(或“ git pull --rebase”)工具可以在当前上游版本之上重放您自己的更改,因此您的更改位于当前版本之上(是新鲜的) ) 和“ git format-patch”以创建带有提交消息(和作者身份)的电子邮件,以(扩展的)统一差异格式(加上 diffstat 以便于)的形式进行更改。维护者可以使用“ git am”将此类电子邮件直接转换为保留所有信息(包括提交消息)的提交。
CVS 没有提供这样的工具:您可以使用“cvs diff”/“cvs rdiff”来生成更改,并使用 GNU 补丁来应用更改,但据我所知,没有办法自动应用提交消息。CVS 旨在以客户端 <-> 服务器方式使用...
中尉。如果您是项目(子系统)独立部分的维护者,或者您的项目的开发遵循 Linux 内核开发中使用的“信任网络”工作流程……或者您拥有自己的公共存储库,并且您的更改想要发布太大而无法作为补丁系列通过电子邮件发送,您可以向项目的(主要)维护者发送拉取请求。
这是特定于分布式版本控制系统的解决方案,所以当然 CVS 不支持这种协作方式。甚至还有一个名为“git request-pull”的工具,它有助于准备电子邮件以发送给维护者,并请求从您的存储库中提取。感谢“git bundle”,即使没有公共存储库,您也可以通过电子邮件或运动鞋网发送更改包来使用此机制。一些 Git 托管站点(如GitHub)支持通知某人正在您的项目上工作(发布了一些工作)(前提是他/她使用相同的 Git 托管站点),并支持 PM-ing 一种拉取请求。
主要开发人员,即直接发布他/她的更改(到主要/规范存储库)的人。这个类别对于分布式版本控制系统更广泛,因为拥有多个对中央存储库具有写访问权限的开发人员不仅是可能的工作流程(您可以有一个维护者将更改推送到规范存储库,他/她可以从中获得一组副官/子系统维护者拉,以及广泛的叶开发人员,他们通过邮件将补丁发送到维护者/项目邮件列表,或中尉/子维护者之一)。
使用 Git,您可以选择使用SSH 协议(包含在 SSH 中的 git 协议)来发布更改,使用诸如“git shell”(帮助安全,限制 shell 帐户的访问)或Gitosis(无需单独的 shell 帐户即可管理访问)之类的工具),以及带有 WebDAV 的HTTPS,带有普通的 HTTP 身份验证。
使用 CVS 可以选择自定义未加密(纯文本)pserver协议,或者使用远程 shell(您真正应该使用SSH 的地方)来发布您的更改,这对于集中式版本控制系统意味着提交您的更改(创建提交)。好吧,您也可以使用 SSH 隧道“pserver”协议,并且有第三方工具可以自动执行此操作……但我认为这不像 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.
通常,分布式版本控制系统(例如 Git)提供了更广泛的可能工作流选择。使用集中的版本控制系统,比如 CVS,你必须区分对存储库有提交访问权限的人和没有的人……而且 CVS 不提供任何工具来帮助接受来自没有提交访问权限的人的贡献(通过补丁)提交访问。
Karl Fogel in Producing Open Source Softwarein 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...
Karl Fogel 在Producing Open Source Software中关于版本控制的部分指出,最好不要对允许对公共存储库进行更改的区域提供过于严格、严格和严格的控制;依靠(为此)社会限制(例如代码)比技术限制要好得多;分布式版本控制系统进一步减少了恕我直言......
HTH (Hope That Helps)
HTH (希望有帮助)
回答by millimoose
The Git websiteexplains this best probably.
Git 网站可能最好地解释了这一点。
My pet feature is being able to do commits when offline. And the speed, the sheer blazing speed at which everything except pushing and pulling happens. (And these operations are by design nondestructive, so you can push/pull when you go grab a coffee if your central repo is lagged.) Another nice thing is that it comes batteries included: the builtin gitk
is a good enough history viewer; git gui
is a good enough commit tool; with output colorization, git add -i
, git add -p
, git rebase -i
are good enough interactive interfaces; git daemon
and git instaweb
are good enough for ad-hoc collaboration if you don't want to / can't fiddle with your central repo.
我的宠物功能是能够在离线时进行提交。还有速度,除了推拉之外的一切都发生的绝对惊人的速度。(这些操作设计为非破坏性的,因此如果您的中央存储库滞后,您可以在去喝咖啡时推/拉。)另一个gitk
好处是它包含电池:内置是一个足够好的历史查看器;git gui
是一个足够好的提交工具;具有输出着色、git add -i
、git add -p
、git rebase -i
是足够好的交互界面;如果您不想/不能摆弄您的中央存储库,git daemon
并且git instaweb
对于临时协作来说已经足够了。
回答by Anton Gogolev
Git is a DVCS, as opposed to CVS being a centralized one. Simplistic description will be: you get all benefits of version control when you're not connected to anyof multiple possible repositories, plus operations are faster.
Git 是一个DVCS,而 CVS 是一个集中式的。简单的描述是:当您没有连接到多个可能的存储库中的任何一个时,您将获得版本控制的所有好处,而且操作速度更快。
回答by smcameron
I'm also a 10+ year mostly happy user of cvs, though I also like git, and with time will come to prefer it, though most of the projects I work on currently use cvs, or svn, and we can't seem to get the bureacracy where I work convinced to let us punch a git-hole through the firewall.
我也是 cvs 的 10 年多的快乐用户,虽然我也喜欢 git,随着时间的推移会更喜欢它,尽管我目前从事的大多数项目都使用 cvs 或 svn,我们似乎无法为了让我工作的官僚机构说服我们在防火墙上打一个漏洞。
A couple of things that make cvs nicer than it might otherwise be are cvsps, and another is either Andrew Morton's patch scripts, or quilt. Cvsps lets you reconstitute the multiple files of a commit into a single patch (and thus extract "changesets" from CVS) while quilt, or Andrew Morton's patch scripts allow you to commit sensible "changesets" into cvs pretty easily and comfortably, allowing you to work on mutliple things simultaneously while still keeping them separated prior to committing. CVS has its quirks, but I'm used to most of them.
使 cvs 比它可能更好的一些东西是 cvsps,另一个是 Andrew Morton 的补丁脚本或被子。Cvsps 允许您将提交的多个文件重组为单个补丁(从而从 CVS 中提取“变更集”),而 quilt 或 Andrew Morton 的补丁脚本允许您非常轻松舒适地将合理的“变更集”提交到 cvs,允许您同时处理多项事情,同时在提交之前仍将它们分开。CVS 有它的怪癖,但我已经习惯了其中的大部分。
回答by Chris Huang-Leaver
"happily using CVS for over x years", is an interesting idea :-) It's a huge step up from keeping lots of copies, but ...
“愉快地使用 CVS 超过 x 年”,是一个有趣的想法 :-) 与保留大量副本相比,这是一个巨大的进步,但是......
I'm guessing you have got used to all it's quirks, or don't do much branching and merging. There is a worse possibility;
我猜你已经习惯了它的所有怪癖,或者不做太多分支和合并。有更坏的可能性;
People in your organisation have got used to cvs limitations and your work practises have adapted accordingly;
你组织中的人已经习惯了 cvs 的限制,你的工作实践也相应地适应了;
for example never having more than one developer work on one package at a time, only using branching in emergencies etc.
例如,永远不要让一个以上的开发人员一次处理一个包,只在紧急情况下使用分支等。
The basic principle is the more difficult something is, the less people do it.
基本原则是越难做的事,做的人越少。