84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
为什么别人总说 linus 反感SVN,是因为他必须连网才能使用,所以不用他,说得好像GIT不联网就能使用一样,不联网他咋提远程服务器啊?
诚然,最终肯定要联网才能与他人的代码合并。
但那句话的意思是说Git不需要总是联网就能进行版本管理,因为它有本地仓库。你可以无需联网,在本地就能进行很多版本管理相关的工作,例如创建分支、提交、回滚代码等
Git
总是
对始终坐在一间办公室,使用局域网工作的常规的小规模团队,可能无法充分体会到Git的好处,换句话说,对于一般的情况,SVN已经足够胜任了。
SVN
然而对项目成员可能分布在任何地方的“非常规”团队来说,Git可能要更优秀一些。
本来想在评论里直接回复你的,但内容有点多,所以还是加到这里吧。
从你的疑惑中能看出来,你可能还不太理解版本管理的本质。版本管理中的版本并不单单指软件最终的发行版,0.8、1.0、2.0这些只不过是面向最终用户的版本而已。版本管理中的版本是泛指那些在开发过程中程序的中间状态。这些版本有些需要合并到公共版本里去,有些可能最终就丢弃了,甚至从此就演化出了另一个项目也不一定。可以说,你每按下一次Ctrl+S就创建了一个版本。
版本管理
版本
Ctrl+S
为了更好地说明版本管理的本质,我再举几个例子,这些都是我们平时经常遇到的,体会一下吧。
我对目前正在开发的这个功能有一个思路,但不知道是否可行,于是准备先尝试一下,可视我不想直接在工作空间里改(SVN里工作空间往往直接对应主版本),因为这样会污染现有的代码,万一后来发现这种方法不可行,就要删除所有与此相关的代码,但可能那时候已经不记得哪些是需要删除的了。
在SVN这种集中式的版本控制工具中也可以实现(所以说很多功能和特性只是更方便而已),那就是使用分支,但这样一来我仍然必须经常与服务器打交道,创建分支、删除分支、合并分支、提交代码到分支,等等。但是实际上这些事情我在本地就完全可以做了(还是那句话,局域网中这可能不是个大问题),在本地仓库中创建一个分支,编码、试验,可行就合并到主版本上去,不可行也没什么关系。
我发现某一次提交中有个程序是不正确的(例如某个功能只改了一半,无法使用,甚至编译都无法通过),此时我只能赶紧对服务器进行回滚操作,但可能已经晚了,别人可能已经check了你的代码,你不得不群发邮件说明这个问题(或者如果大家都在一起的话就直接吼一嗓子)。
但在Git中,由于是先提交到本地,这样就给了提交行为一个缓冲时间,让我能够及时撤销而不会影响到其他人(如果你发现的太晚那也是没办法)。
还有就是“本地”回滚能力,一个功能比较复杂,要开发好几天,但我不想在没开发完就提交到服务器上去,因为我不想因为编译或运行错误影响到其他人。于是我就想全部在本地改好再提交,但这样一来,这些程序就没有了保障,如果我想回滚、与以前的代码进行比较等等都不好做。
有些工具也提供了本地历史的功能,但并不好用,本地历史无法和版本相提并论,你的每一次Ctrl+S可能形成一个本地历史,也可能不会形成。换句话说,本地历史无法按照你的意愿来保存记录。很可能你亟需的一个历史记录它却没有保存,你只能望码兴叹了(这个问题确实不那么罕见)
说了这么多,都只是集中式和分布式之间的一些侧面例子而已。其实这个问题就像面向对象和面向过程一样,没有绝对的好与坏,复杂程序用面向对象可能更好,但面向过程也不是一无是处。工具的选择还是看团队和个人的决策吧
题主过分拘泥于git的这个可以单人离线使用的优点了,git是分布式结构,意味着它的数据完整性注定要比svn好很多,题主肯定是没有碰到过svn仓库文件损坏的事情(很容易发生!比如断电),用svndump导出来的所有历史提交也有莫名其妙的问题。
另外题主可能接触的项目规模都还比较小,基本上还在把git当成svn一样的使用,所以才会着重看到冲突和合并的问题。我想说的是有冲突当然要解决,但版本管理的根本目的不仅仅在于合并代码解决冲突这件事上,最重要的可能是让所有人都能干活,并且不影响到别人和发布
我司的git使用遵循git flow的做法,master用于主干发布(web项目,所以是不断迭代的稳定版本),develop用于测试,每个人开始开发一个新需求都是从develop分支创建一个feature分支,干完活后合并回develop,做一个release到测试环境中进行测试,如果一切OK,那么把release合并到master中,等待下次发布说这些的目的就是为了提,在自己的feature分支上干活时,其实并不需要太太关心develop分支上发生的事情的(也就没有和中央服务器交互的太大需求),但是对于版本管理的需求仍然是存在的,完成一个feature需要你很多次的提交才可以解决如果是要紧急修复的补丁,从master上创建一个hotfix分支,改完之后merge回master(以及develop)
通过这些手段,主要是解决了
一个新功能的开发,不会影响到别的新功能的开发(每个feature都是独立分支)
新版本的升级(在develop上)和对旧版本(master)的bug修复,不会互相冲突和影响,不会因为说有人在开发新版本了,那个旧版本master的bug就必须要等到新版本开发完了才能一次上
我可以说这事SVN虽然也能干,但它的分支功能本质上是仓库中的一个另外的目录,合并与否实际上是通过一个属性来保存的,绝对算不上好用
补充:
可以看下 http://git-scm.com/book/zh/v1/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E4%B8%BA%E9%A1%B9%E7%9B%AE%E4%BD%9C%E8%B4%A1%E7%8C%AE 介绍了很多git的最佳实践
就是集中式和分布式的区别。
诚然,最终肯定要联网才能与他人的代码合并。
但那句话的意思是说
Git
不需要总是
联网就能进行版本管理,因为它有本地仓库。你可以无需联网,在本地就能进行很多版本管理相关的工作,例如创建分支、提交、回滚代码等对始终坐在一间办公室,使用局域网工作的常规的小规模团队,可能无法充分体会到
Git
的好处,换句话说,对于一般的情况,SVN
已经足够胜任了。然而对项目成员可能分布在任何地方的“非常规”团队来说,
Git
可能要更优秀一些。本来想在评论里直接回复你的,但内容有点多,所以还是加到这里吧。
从你的疑惑中能看出来,你可能还不太理解
版本管理
的本质。版本管理中的版本并不单单指软件最终的发行版,0.8、1.0、2.0这些只不过是面向最终用户的版本而已。版本管理
中的版本
是泛指那些在开发过程中程序的中间状态。这些版本有些需要合并到公共版本里去,有些可能最终就丢弃了,甚至从此就演化出了另一个项目也不一定。可以说,你每按下一次Ctrl+S
就创建了一个版本。为了更好地说明版本管理的本质,我再举几个例子,这些都是我们平时经常遇到的,体会一下吧。
情景1
我对目前正在开发的这个功能有一个思路,但不知道是否可行,于是准备先尝试一下,可视我不想直接在工作空间里改(SVN里工作空间往往直接对应主版本),因为这样会污染现有的代码,万一后来发现这种方法不可行,就要删除所有与此相关的代码,但可能那时候已经不记得哪些是需要删除的了。
在SVN这种集中式的版本控制工具中也可以实现(所以说很多功能和特性只是更方便而已),那就是使用分支,但这样一来我仍然必须经常与服务器打交道,创建分支、删除分支、合并分支、提交代码到分支,等等。但是实际上这些事情我在本地就完全可以做了(还是那句话,局域网中这可能不是个大问题),在本地仓库中创建一个分支,编码、试验,可行就合并到主版本上去,不可行也没什么关系。
情景2
我发现某一次提交中有个程序是不正确的(例如某个功能只改了一半,无法使用,甚至编译都无法通过),此时我只能赶紧对服务器进行回滚操作,但可能已经晚了,别人可能已经check了你的代码,你不得不群发邮件说明这个问题(或者如果大家都在一起的话就直接吼一嗓子)。
但在Git中,由于是先提交到本地,这样就给了提交行为一个缓冲时间,让我能够及时撤销而不会影响到其他人(如果你发现的太晚那也是没办法)。
情景3
还有就是“本地”回滚能力,一个功能比较复杂,要开发好几天,但我不想在没开发完就提交到服务器上去,因为我不想因为编译或运行错误影响到其他人。于是我就想全部在本地改好再提交,但这样一来,这些程序就没有了保障,如果我想回滚、与以前的代码进行比较等等都不好做。
有些工具也提供了本地历史的功能,但并不好用,本地历史无法和版本相提并论,你的每一次
Ctrl+S
可能形成一个本地历史,也可能不会形成。换句话说,本地历史无法按照你的意愿来保存记录。很可能你亟需的一个历史记录它却没有保存,你只能望码兴叹了(这个问题确实不那么罕见)总结
说了这么多,都只是集中式和分布式之间的一些侧面例子而已。其实这个问题就像面向对象和面向过程一样,没有绝对的好与坏,复杂程序用面向对象可能更好,但面向过程也不是一无是处。工具的选择还是看团队和个人的决策吧
题主过分拘泥于git的这个可以单人离线使用的优点了,git是分布式结构,意味着它的数据完整性注定要比svn好很多,题主肯定是没有碰到过svn仓库文件损坏的事情(很容易发生!比如断电),用svndump导出来的所有历史提交也有莫名其妙的问题。
另外题主可能接触的项目规模都还比较小,基本上还在把git当成svn一样的使用,所以才会着重看到冲突和合并的问题。我想说的是有冲突当然要解决,但版本管理的根本目的不仅仅在于合并代码解决冲突这件事上,最重要的可能是让所有人都能干活,并且不影响到别人和发布
我司的git使用遵循git flow的做法,master用于主干发布(web项目,所以是不断迭代的稳定版本),develop用于测试,每个人开始开发一个新需求都是从develop分支创建一个feature分支,干完活后合并回develop,做一个release到测试环境中进行测试,如果一切OK,那么把release合并到master中,等待下次发布
说这些的目的就是为了提,在自己的feature分支上干活时,其实并不需要太太关心develop分支上发生的事情的(也就没有和中央服务器交互的太大需求),但是对于版本管理的需求仍然是存在的,完成一个feature需要你很多次的提交才可以解决
如果是要紧急修复的补丁,从master上创建一个hotfix分支,改完之后merge回master(以及develop)
通过这些手段,主要是解决了
一个新功能的开发,不会影响到别的新功能的开发(每个feature都是独立分支)
新版本的升级(在develop上)和对旧版本(master)的bug修复,不会互相冲突和影响,不会因为说有人在开发新版本了,那个旧版本master的bug就必须要等到新版本开发完了才能一次上
我可以说这事SVN虽然也能干,但它的分支功能本质上是仓库中的一个另外的目录,合并与否实际上是通过一个属性来保存的,绝对算不上好用
补充:
可以看下 http://git-scm.com/book/zh/v1/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E4%B8%BA%E9%A1%B9%E7%9B%AE%E4%BD%9C%E8%B4%A1%E7%8C%AE 介绍了很多git的最佳实践
就是集中式和分布式的区别。