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的最佳實踐
就是集中式和分佈式的差別。