dvcs (git/mercurial) 的分支和合并支持比 svn 更好吗?
许多关于 dvcs 系统的文章都声称卓越的分支和合并支持是从 svn 迁移到 dvcs 系统的原因之一。这些系统究竟如何以不同的方式进行分支和合并以使其更好?
Lots of articles on dvcs systems claim superior branching and merging support as one reason to move from svn to dvcs systems. How exactly do these systems do branching and merging differently that makes it better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
从历史上看,git 和 svn 中的合并跟踪之间的区别是:git 有合并跟踪,直到 1.5 版本,svn 才没有。完全没有。如果您想进行合并,则必须始终准确指定要合并的更改,并且如果您多次将一个分支合并到另一个分支中,则必须手动跟踪哪些修订已合并,哪些修订尚未合并,并仅手动选择尚未合并的更改,以避免冲突。如果您选择了任何更改,祝您好运。
从 1.5 版本(2008 年发布)开始,如果您的客户端、服务器和存储库都是最新的,那么 svn 能够更加智能地运行;它使用属性来跟踪分支的来源以及已合并到其中的更改。结果是,在许多情况下,您只需
svn merge BRANCHNAME
即可让正确的事情发生。但由于其“固定”性质,它仍然不是很快,并且并不完全健壮< /a>.另一方面,Git 由于其 DVCS 性质,必须能够很好地处理合并场景,而且它从一开始就根据数据结构(如它使用的特定类型的 DAG)和算法(如如递归合并和章鱼合并)适合该任务。Historically, the difference between merge-tracking in git and svn was this: git has merge-tracking, and until version 1.5, svn didn't. At all. If you wanted to make a merge you had to always specify exactly what changes were to be merged, and if you merged one branch into another more than once, you would have to manually keep track of which revisions had and hadn't been merged, and manually select only the changes that hadn't been merged yet, to avoid conflicts. Good luck with that if you ever cherry-picked any changes.
Beginning with version 1.5 (released in 2008), if your client, server, and repository are all up-to-date, then svn is capable of acting a lot more intelligently; it uses properties to keep track of where a branch came from and what changes have already been merged into it. The upshot is that in many cases you can just
svn merge BRANCHNAME
and have the right thing happen. But due to its "bolted on" nature it's still not very fast and not entirely robust. Git, on the other hand, has to handle merge scenarios well because of its DVCS nature, and it was designed from the beginning with data structures (like the particular kind of DAG it uses) and algorithms (such as recursive-merge and octopus-merge) that are suited to the task.与流行的看法相反,区别并不在于 DVCS 的分布式特性,而在于 Subversion 的集中式模型。集中式模型中没有任何固有的东西会导致分支和合并不合标准。
我的看法是,Subversion 决定在单个统一目录树中对代码库目录结构、分支和标记(以及所有其他代码管理模式)进行建模,从而造成了巨大的设计失误,这导致了可靠检测分支活动的问题比模型中明确分支的情况困难一百倍。
The difference is not, contrary to popular perception, due to the distributed nature of DVCS's, vs Subversion's centralised model. There is nothing inherent in a centralised model that entails that branching and merging will be substandard.
My take is that Subversion made a massive design gaffe by deciding to model code-base directory structure, branching and tagging (and all manner of other code management patterns) in a single, unified directory tree, which made the problem of reliably detecting branching activity one hundred times more difficult than it would have been if branching were explicit in the model.
不要忘记任何版本控制系统的人工组件。今天早些时候,我创建并删除了 3 个不同的本地 git 分支,因为这是完成清理主分支上问题的破坏性最小的方法。在集中式版本控制上尝试一下,如果您有权限这样做,您可能会收到服务器管理员的训诫或愤怒的电子邮件风暴。事实上,您可以在私人仓库中拥有分支,这一事实消除了有效使用分支的许多文化障碍。集中式系统使用的算法正在赶上 DVCS。这些人为因素将继续存在。
Don't forget the human components of any version control system. Earlier today I created and deleted 3 different local git branches, because that was the least disruptive way to accomplish cleaning up a problem on the main branch. Try that on centralized version control and you are likely to get a lecture from the server admin or a storm of angry emails, if you even have privileges to do it at all. The very fact that you can have branches in a private repo removes many cultural barriers to using branches effectively. The algorithms used by centralized systems are catching up to DVCS. Those human factors will remain.
来自 Joel 的 hginit:
From Joel's hginit:
SVN 中的分支或标记只是将特定目录及其子目录复制到同一存储库中的另一个位置。在 git 中,分支(和标签)被描述为元数据(很像 CVS),只不过它不会将所有这些数据放入单个文件中,而是将许多数据放入其中(允许更快的更新,因为您不必重写例如巨大的“foo.c,v”)。此外,git 大量使用了指针。 (http://eagain.net/articles/git-for-computer-scientists/)所以事实上,当某些事情发生变化时(例如进行提交),首先几乎没有什么需要更新的。
Branching or tagging in SVN is merely copying a particular directory and its subdirs to another location within the same repository. In git, branches (and tags) are instead described as metadata (much like CVS), except that it does not throw all this data in a single file, but many (allowing for much faster updates since you don't have to rewrite a huge "foo.c,v" for example). Furthermore, git makes heavy use of pointers. (http://eagain.net/articles/git-for-computer-scientists/ ) so there is in fact, few to update in the first place when something changes (e.g. a commit is made).
区别在于大多数 DVCS 使用的存储库格式 - 有向无环图。
SVN 只会将您的历史记录存储在一系列行中,每个分支都有自己的行。但 DVCS 会将其存储在 DAG 中,其中包含更好的合并信息。
The difference lies in the repository format used by most DVCS's - the Directed Acylic Graph.
SVN Will just store your history in a series of lines, each branch its own line. But a DVCS will store it in a DAG that contains much better information for merging.