我应该使用SVN还是Git?

326

我正在启动一个新的分布式项目。我应该使用SVN还是Git,为什么?


5
是的,Git 可以在 Mac 上使用。如果您使用 macports 安装它,甚至会安装一个 Mac 前端来进行提交和浏览接口。 - Seth Johnson
3
可能是 https://dev59.com/anVD5IYBdhLWcg3wXaid 的重复问题。 - user177800
3
@Andre - 因为你可以使用MonoDevelop,所以我从Vault切换到SVN,这样我就可以在我的Mac或PC上开发.NET软件。Vault没有客户端,但是SVN有 :-) - schmoopy
4
Github/Bitbucket与Sourcetree结合起来真是太棒了!-http://www.sourcetreeapp.com/ - thecodeassassin
错误:文件<file>大小为123.23 MB;这超过了GitHub的100 MB文件大小限制!!!! - Fuzzy Analysis
显示剩余6条评论
21个回答

256

SVN是一个仓库和多个客户端。Git则是一个包含许多客户端仓库的仓库,每个仓库都有一个用户。Git分散到一个地步,人们可以在本地跟踪自己的编辑而不必将事物推送到外部服务器。

SVN旨在更加中心化,而Git则基于每个用户拥有自己的Git仓库,这些仓库将更改推送回中心仓库。因此,Git提供了更好的本地版本控制。

与此同时,您可以在TortoiseGitGitExtensions之间进行选择(如果您将“中央”Git仓库托管在Github上,则可以使用他们自己的客户端-GitHub for Windows)。

如果您想要摆脱SVN,则可以考虑一下Bazaar。它是下一代版本控制系统之一,具有这种分布式元素。它不像git那样依赖POSIX,因此有原生的Windows版本,并且拥有一些强大的开源品牌支持。

但是,您可能甚至还不需要这些功能。请查看分布式版本控制系统的特点、优点和缺点。如果您需要比SVN更多的功能,请考虑使用其中一种。如果不需要,那么您可能希望坚持使用SVN(目前)更好的桌面集成。


25
可以看一下Hg(汞)。 - Joel
24
自2008年10月以来,情况好了很多。您可以安装TortoiseGit,获取最新的便携式MSysGit版本,并告诉TortoiseGit在哪里找到它。今天,我把我的大型svn存储库转移到了git,因为svn的重命名支持实在太差,让我非常生气。 - We Are All Monica
24
我们长期以来在Windows上大量使用Git,Git在Windows上表现非常出色。 - Charlie Flowers
13
@Oli 应该根据这里的评论和你的经验更新你的答案(特别是关于Windows git客户端的部分),这样会更好。由于已经过去了2-3年,当前的答案似乎有偏见。 - amit kumar
4
技术上讲,并没有所谓的“中央”git仓库,所有仓库都是平等的。只要你在相应的端点具有权限,就可以从任何仓库推送或拉取到另一个仓库。当然,你可以轻松地设置一个仓库作为集中式仓库,但实际上它与其他仓库并没有什么不同。 - naught101
显示剩余9条评论

116

我从未理解过"git在Windows下不好"这一概念;我专门在Windows下开发,从来没有遇到过任何与git有关的问题。

我绝对推荐git而非subversion;它更加多才多艺,可以以subversion做不到的方式进行“离线开发”。git适用于几乎所有想得到的平台,并且拥有比你可能会使用的功能还要多的功能。


9
相反,我在Windows上使用git时遇到了很多问题,它会对我的代码库做出非常奇怪的改变。我使用的是最近在Cygwin中下载的版本(大约一个月前)。 - Roman Plášil
7
@Roman: 嗯,Cygwin端口跟本地Win32端口几乎不一样。我预计Cygwin端口的测试要少得多... - SamB
50
在我看来,“比你可能永远都用不到的功能更多”是一个警告信号。 - B T
27
我不同意“红旗”(red flag)这个说法。我常常希望有一种方法可以做某些事情,经过一点搜索后,我发现有一些命令可以实现这个目标,而我之前并不知道。我也在我的Windows机器上使用GIT,但还没有遇到过什么大问题。 - testing123
@testing123,但它们不是“你可能永远都不会用到”的功能,因为你最终确实使用了它们。 - mulllhausen
我不确定你的评论为什么针对我 :). 我同意,这也是我评论的重点。我想你可能是指@BT。 - testing123

76

这是我在2009年九月关于Git与SVN的回答一些后来被删除的重复问题的副本的副本。

更好了吗?除了常规链接为什么Git比X更好之外,它们是不同的:

一个是基于便宜分支和标记的中央版本控制系统, 另一个(Git)则是基于修订版本图的分布式版本控制系统。 另请参见VCS的核心概念


第一部分引发了一些误解的评论,声称这两个程序(SVN和Git)的基本目的相同,但它们实现方式非常不同。
为澄清SVN和Git之间的根本区别,让我重新表述一下:

  • SVN是修订控制的第三个实现:RCS,然后是CVS,最后是SVN 管理版本化数据的目录。 SVN提供VCS功能(标记和合并),但其标记只是目录副本(像分支一样,除了您不“应该”触摸标记目录中的任何内容),而其合并仍然很复杂,目前基于添加的元数据来记住已合并了什么。

  • Git是一个文件内容管理(用于合并文件的工具),进化成真正的版本控制系统,基于提交的DAG(有向无环图),其中分支是数据历史的一部分(而不是数据本身),而标记是真正的元数据。

说它们在"根本上"没有不同,因为您可以实现相同的事情,解决相同的问题是...纯粹错误的。

  • 如果您有许多复杂的合并操作,使用SVN会更加耗时且容易出错。如果需要创建许多分支,使用Git比使用SVN更容易管理和合并它们,特别是在涉及大量文件时(速度变得重要)。
  • 如果您正在进行某个工作的部分合并操作,可以利用Git的暂存区(索引)只提交您需要的内容,将其余部分存储起来,然后转到另一个分支。
  • 如果您需要离线开发......那么使用Git,您始终处于“在线”状态,拥有自己的本地仓库,无论您想遵循其他仓库的工作流程如何。

尽管那个旧答案已被删除,但评论仍然坚称:

VonC:您混淆了实现中的基本差异(这些差异非常基础,我们显然都同意这一点)和目的上的差异。
它们是用于相同目的的工具:这就是为什么许多以前使用 SVN 的团队已经成功地放弃它转而使用 Git。
如果它们没有解决相同的问题,这种可替代性就不存在。

对此我回答道:

"可替代性"…有趣的术语(在计算机编程中使用)。
当然,Git 绝不是 SVN 的子类型。

虽然两者都可以实现相同的技术特性(标签、分支、合并),但 Git 不会妨碍你,且允许你专注于文件内容,而不必考虑工具本身。

当然,并不是总能够只通过使用 Git 替换 SVN "而不改变该程序的任何理想属性(正确性、执行的任务等)"(这引用了上述可替代性定义):

  • 其中一个是扩展的修订工具,另一个是真正的版本控制系统。
  • 其中一个适用于简单合并工作流程和(不太多)并行版本的小型到中型单块项目。SVN已经足够满足这个目的,您可能不需要所有Git功能。
  • 另一种允许基于多个组件(每个组件一个存储库)的中大型项目,涉及大量文件在复杂的合并工作流程、分支中进行合并,并行版本、回归合并等。您可以使用SVN来完成,但使用Git会更好。
    SVN无法管理任何大小,任何合并工作流程的项目。Git可以。

再次强调,它们的本质根本不同(这导致了不同的实现方法,但这不是重点)。
其中一种将修订控制视为目录和文件,而另一种只看文件内容(如此之多,以至于空目录在Git中甚至都不会被注册!)。

总体目标可能是相同的,但是您不能以相同的方式使用它们,也不能解决相同类别的问题(在范围或复杂性上)。


10
我不反对你说git和svn在根本上是不同的,但我对你的很多观点持不同意见。虽然svn可能是为取代cvs而写的,但除此之外它与cvs没有任何关系;相比之下,cvs最初是建立在RCS基础上的脚本,因此两者有直接关联。然而,你引用的那个人完全正确,它们都根本上管理文件的版本,实现和过程(或其执行方式)是实现细节。这就像CRC和SHA1之间的区别,根本上非常不同,但它们做的事情却相同。 - Erik Funkenbusch

38

SVN的两个很少被提到的优点:

  1. 大文件支持。除了代码,我使用SVN来管理我的主目录。 SVN是唯一一个不会在TrueCrypt文件上出现问题(如果有其他能够有效处理500MB +文件的VCS,请纠正我)。这是因为差异比较是流式传输的(这是一个非常重要的点)。 Rsync不可接受,因为它不支持双向传输。

  2. 局部存储库(子目录)的检出/签入。Mercurial和bzr不支持此功能,git的支持也有限。这在团队环境中很糟糕,但如果我想从我的主目录中的另一台计算机检查某些内容,则非常宝贵。

以上是我的经验。


7
如果有其他有效处理500MB+文件的版本控制系统,请纠正我,当然是Perforce! - James Creasy
8
Perforce是非免费软件。此外,Perforce并不支持所有平台。 - WhyNotHugo
4
为什么不将SVN仓库放在TrueCrypt容器内部?你还可以通过SSH隧道传输,配置服务器将该特定仓库存储在另一个TrueCrypt文件中。这样做的额外优点是,你可以对该仓库进行部分检出。 - WhyNotHugo
1
据我所知,Perforce客户端可用于Windows、Unix、Linux变种、Mac、Amiga、BeOS、Cygwin、HPUX、IBM AS/400、OS/2、DEC VMS和Novell文件服务器。这个列表中是否有一些相关的平台遗漏了? - eis
1
是的,OpenBSD不支持(我从经验中知道这一点,不需要谷歌)。我猜它在maemo上也行不通,虽然我可能错了(是的,我在maemo上使用git)。 - WhyNotHugo
显示剩余2条评论

25
在进行更多研究并查看以下链接后:https://git.wiki.kernel.org/articles/g/i/t/GitSvnComparison_cb82.html(以下是一些摘录):
  • 速度非常快。 我使用过很多版本控制软件,包括Subversion、Perforce、darcs、BitKeeper、ClearCase和CVS,但没有任何一个能够与Git相比。
  • 完全分布式。 仓库所有者不能规定我的工作方式。我可以在我的笔记本电脑上创建分支和提交更改,然后稍后将其与任意数量的其他仓库同步。
  • 同步可以通过多种媒介进行。 通过SSH通道、通过WebDAV进行HTTP、通过FTP或通过发送包含补丁的电子邮件来进行同步。中央仓库不是必需的,但也可以使用。
  • 分支甚至比Subversion中的分支更便宜。 创建分支就像将一个41字节的文件写入磁盘一样简单。删除分支就像删除该文件一样简单。
  • 与Subversion不同,分支携带着它们的完整历史记录。 无需执行奇怪的复制和遍历操作。当我在Subversion上查看发生在分支创建之前的文件历史时,我总觉得很尴尬。 来自#git: spearce:我不理解关于页面中的SVN的一件事。我在SVN中创建了一个分支并浏览了文件的历史记录,显示了分支之前的整个历史记录
  • 在Git中,分支合并更简单、更自动化。 在Subversion中,您需要记住上次合并的最后修订版本,以便生成正确的合并命令。Git会自动执行此操作,并始终正确执行。这意味着合并两个分支时犯错的机会更少。
  • 分支合并记录为仓库的正式历史记录的一部分。 如果我将两个分支合并在一起,或者将一个分支合并回它来自的主干,那么该合并操作将被记录为由我执行的操作及其时间戳。当记录在日志中时,很难争论是谁执行了合并操作。
  • 创建仓库是一个微不足道的操作: mkdir foo; cd foo; git init 就这样了。这意味着我现在几乎每件事都创建一个Git仓库。我倾向于每个类使用一个仓库。那些仓库大多数只有不到1 MB的磁盘空间,因为它们只存储讲义、作业和我的LaTeX答案。
  • 仓库的内部文件格式非常简单。 这意味着修复非常容易,但更好的是,因为它如此简单,所以很难被损坏。我认为没有任何人遇到过Git仓库的损坏。我曾经看到Subversion的fsfs自己损坏了。我也看到Berkley DB多次损坏,以至于不再信任我的代码将其分配给Subversion的bdb后端。
  • 尽管是一种非常简单的格式,但Git的文件格式非常擅长压缩数据。 Mozilla项目的CVS仓库约为3 GB;在Subversion的fsfs格式下约为12 GB,在Git中约为300 MB。

阅读完所有这些内容之后,我相信Git是正确的选择(尽管存在一点学习曲线)。我也在Windows平台上使用过Git和SVN。

在阅读以上内容后,我很想听听其他人的意见。


15
Git的某些操作速度非常快,主要因为这些操作只影响到本地代码库。举例来说,Git的提交操作不应该被公正地与SVN的提交操作做比较,因为SVN的提交操作还需要将修改推送到团队的暂存库中,这需要进行网络传输。这个过程需要进行网络通信,因此将Git的无需网络提交与需要网络传输的操作进行比较是不合适的。如果你使用Git进行提交,然后又不小心删除了硬盘上的代码库,那么你的修改也会一同丢失。如果你已经习惯了这种情况,这样做也没问题,但这在非分布式版本控制系统中并不是预期的结果。 - Edwin Buck
1
@EdwinBuck 不考虑Waqar所做的事情,在测试中即使考虑了网络时间,Git倾向于更快:http://git-scm.com/about/small-and-fast - Sqeaky
你的“创建存储库是一个微不足道的操作”一点非常重要,特别是在Windows上:与SVN相比,使用Git可以更轻松地快速模拟一堆互相连接的分布式存储库,所有这些存储库都连接到一个中央(--bare)存储库,而使用SVN则需要安装Windows SVN服务器应用程序等。此外(奇怪的是),我发现Git在各个操作系统上更加一致:命令行设计非常好,因此大多数情况下足以胜任(并且在各个操作系统之间几乎完全相同),而SVN则需要使用各种本机客户端/服务器应用程序... - Shivan Dragon
1
你所提到的维基百科文章充满了错误,因此你的回答是错误的。我给你点了踩。维基百科上有一个讨论页面,引用了http://www.svnvsgit.com/,解释了为什么这个比较是错误的。 - bahrep
非常快?我已将ciforth项目从本地cvs移至github。这是一个简单的项目,但有一个大的主源文件,共有10,000行。如果我尝试在此文件上使用blame,github会超时。如果一个人不满足于说“快”,并坚持使用这样的限定词,那么这就不是一个平衡的观点,让我对你所说的一切都感到怀疑。Groetjes Albert - Albert van der Horst
创建一个仓库对于rcs来说是一个微不足道的操作,只需mkdir RCS,甚至这也不是必要的。我经常为讲座、欧拉问题的解决方案以及在我的脑海中弹出的每个简单程序想法而制作“新的存储库”。因此,如果您想要简单的东西,那么您可以使用更少的内容。最后一个错误已经在20年前被修复了。Groetjes Albert - Albert van der Horst

12

我会建立一个Subversion代码库。这样做的好处是,个别开发人员可以选择使用Subversion客户端或Git客户端(使用git-svn)。虽然使用git-svn不能获得完整的Git解决方案的所有优势,但它确实给了个别开发人员对其自己工作流程的很大控制力。

我相信不久的将来,Git在Windows上将会和在Unix和Mac OS X上一样好用(因为你问了这个问题)。

Subversion有优秀的Windows工具,如TortoiseSVN对Explorer的集成以及AnkhSVN对Visual Studio的集成。


11
有趣的是:我使用Subversion Repos托管项目,但通过Git克隆命令访问它们。
请阅读在Google Code项目中使用Git进行开发 尽管Google Code本地支持Subversion,但您可以在开发过程中轻松使用Git。搜索“git svn”表明这种做法很普遍,我们也鼓励您尝试使用它。
在Svn存储库上使用Git使我受益:
  1. 我可以在多台机器上分布式工作,并从它们提交和拉取
  2. 我有一个用于检出的中央备份/公共svn存储库
  3. 他们可以自由使用Git

4
请注意:自2011年7月起,Google Code 原生支持 Git。 - Jeremy Salwen

9

虽然我并没有回答你的问题,但是如果你想要享受分布式版本控制的好处——看起来你确实需要这个功能——而且你使用的是Windows操作系统,那么我认为你最好使用Mercurial而不是Git,因为Mercurial在Windows上的支持更好。Mercurial也有Mac版本。


9
如果你的团队已经熟悉像cvs或svn这样的版本和源代码控制软件,那么对于一个简单而小型的项目(就像你所说的那样),我建议你坚持使用SVN。我非常熟悉svn,但是对于我正在django上进行的当前电子商务项目,我决定使用git(我在svn模式下使用git,也就是说,我有一个集中式的repo,我从中推送和拉取以与至少另一个开发人员进行协作)。另一位开发人员熟悉SVN,尽管其他人的经验可能不同,但我们两个在为这个小项目拥抱git时遇到了很多问题。(我们都是Linux用户,如果这有关系的话。)
当然,你的情况可能会有所不同。

8
主要的区别是,Git是一种分布式版本控制系统,而Subversion是一种集中式版本控制系统。分布式版本控制系统比较难理解,但具有许多优点。如果您不需要这些优点,Subversion可能是更好的选择。
另一个问题是工具支持。您计划使用哪种版本控制系统更好支持您的工具?
编辑:三年前我是这样回答的:
Git目前只能通过Cygwin或MSYS在Windows上运行。 Subversion从一开始就支持Windows。由于Git的解决方案可能适用于Windows,但也可能存在问题,因为大多数Git开发人员使用Linux,并没有从一开始就考虑可移植性。目前,在Windows下进行开发时,我更喜欢使用Subversion。在未来几年,这可能无关紧要。

现在世界发生了一些变化。Git在Windows上有了良好的实现。虽然我没有在Windows上进行全面测试(因为我不再使用这个系统),但我非常自信,所有主要的版本控制系统(SVN、Git、Mercurial、Bazaar)现在都有适当的Windows实现。这对SVN的优势已经消失了。其他方面(集中式与分布式以及工具支持检查)仍然有效。


是的,可能只需要一年时间。Git拥有一个充满活力的开发社区。但是Subversion也是如此。再过一两年,你将不得不重新审视这个问题并回答它。 - Mnementh
1
现在已经过去了一两年。情况怎么样? :) - Merlyn Morgan-Graham
已经超过三年了。:-) 我更新了我的回答。 - Mnementh
3
Git缺乏将分布式SCM模型扩展到软件开发流程的其他阶段的扩展。我们没有一个良好的模型来分布式构建系统、分布式自动化测试、质量控制、发布控制等。我们只是在进行一些分布式备份的实验性支持,而这是经过几十年的研究之后才有的。因此,Git对开发人员提供了更多帮助,但对软件开发流程提供的帮助较少。所有Git实现最终都会赞扬一个库作为中心库,这简化了最有趣的Git功能成了SVN功能的类似品。 - Edwin Buck
1
Git 没有集中式存储库,每个存储库都是平等的(由于其分布式的设计)。这意味着您要么重新设计您的生产流水线以可能平等处理所有存储库,要么人为地赋予其中一个存储库“人为提高”的地位(也称为“中央存储库”)。如果选择前者,则没有人知道如何构建可以从任何开发人员的桌面发布的并行流水线;如果选择后者,则分布式处理的承诺被集中式约定所欺骗。 - Edwin Buck
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接