1. 程式人生 > >版本控制:SVN和GIT的一些使用感受

版本控制:SVN和GIT的一些使用感受

背景:

         原本在學校跟隨導師做專案的時候,就一直在使用版本管理,主要是用來記錄專案的修改,專案成員之間的溝通和交流。使用的服務端是Visual SVN,客戶端是TortoiseSVN,常用的TortoiseSVN指令也僅限於SVN Update和SVN Commit,前者用來從伺服器更新,以期望檢視其他同學的修改,後者用來將自己的修改提交到伺服器,使得團隊共享修改。由於專案組中的成員比較少,主要的程式碼修改也只有我一人完成,因此TortoiseSVN也就淪為了記錄我修改原生代碼過程的工具。其實這與我平時寫工作日誌(word格式)、程式碼中添加註釋(註釋中一般會出現修改原因、修改者、修改時間、備註)的習慣有一些冗餘。

        隨後進入職場,接觸的專案越來越大、開發者越來越多,就慢慢開始瞭解TortoiseSVN的其它功能。例如檢視檔案修改日誌Show log、回滾已提交的修改操作Revert、建立分支Branch/Tag、建立補丁Create patch等。在逐漸熟悉和使用的情況下,逐漸感覺到TortoiseSVN似乎還缺少一點什麼功能?比如下述場景就經常發生:我從專案SVN伺服器拷貝自己負責的程式碼到我的本本,然後按照專案計劃開始修改自己的模組(此時就像在本地開發除錯一樣),但是突然臨時接到上級指示,有一個緊急的Bug要處理。此時我只能先建立補丁檔案(Create patch),然後將目前的修改回滾到初始狀態(即我從SVN伺服器拷貝時的版本),如是我才能開始修改緊急的bug。等待修補完成後,再將先前的patch檔案應用回來。這裡面我會同時做好相應的工作記錄(word文件),這裡面就會記錄我初始修改模組時的相關步驟和細節,記錄bug修補的過程,然後接著記錄模組的修改。如此,結合TortoiseSVN的提交日誌和我的word工作文件,我才能精確的定位我開發過程中的任意時刻——方便後續思路的整理和延續,如下圖所示:如果每次TortoiseSVN提交的時間粒度是按照黃色箭頭所示,那麼中間的紅色修改我只能在我的word工作日誌中檢視,但是word中畢竟記錄的是思路,具體的程式碼檔案我只能手動拷貝到word日誌中記錄的相應位置,或者建立patch檔案儲存到制定位置,如果TortoiseSVN提交的時間粒度是途中箭頭所示,那麼這與word日誌的工作幾乎重複,可以達到隨意定位修改的目的,但是需要注意的是,在團隊開發中,如此頻繁的TortoiseSVN提交時絕對不可能的,一是SVN伺服器要求完整的功能修改完成後才能提交,而是如此頻繁的提交會增加伺服器負擔,也會使得自己不完整的程式碼模組影響整個專案的功能。

image

        看到這裡,你是不是覺得好複雜,好麻煩,但是對於碼農來說,良好的記錄和註釋是必須的,這樣你才能更好的對自己的程式碼負責。這種開發狀態我已經堅持了多年,也習以為常了,直到某一天我接觸了Git後,我才恍然發現,原來還有一種所謂的分散式版本管理工具,可以記錄我的本地修改。真是令我喜大普奔。

        下面介紹一下怎麼利用Git來管理本地的程式碼修改。

Git管理原生代碼修改:

1)Git與SVN的區別:

        關於兩者的分析和討論早已遍佈各大論壇、貼吧,這裡我不評價兩者孰優孰劣。僅從自己實際的程式碼開發工作,從提高我本人程式碼開發效率的角度來說一下我對兩者的看法。正如背景中所述,SVN的使用已有多年,簡單的來說就是有一個伺服器會儲存你對程式碼的修改,這裡的修改必須是你確定提交(Commit)到伺服器的。對於兩次提交的間隔粒度完全取決於開發者本人,如果僅僅是利用SVN來管理自己的程式碼開發記錄,你完全可以隨意提交以期望來記錄自己完整的開發流程(這種方式在團隊合作中是堅決不允許的)。SVN的結構分為版本庫和工作副本,版本庫就是放在服務端的“資料庫”用來記錄你每次的提交,記錄的內容包括所有版本庫控制範圍內的檔案的改動;工作副本就是你自己本機中的程式碼工程,它是伺服器中程式碼工程的一個拷貝,SVN將版本庫和工作副本存放在不同的位置。具體的示意圖如下(自己思路的直接體現,可能不一定完全符合SVN的工作過程,但是大意是正確的,便於大家理解):

image        從上圖可以看出,SVN版本管理的基本流程,服務端儲存的是你每次對工程進行的修改,當然第一次提交時記錄的就是你的初始工程檔案。那麼從上圖SVN服務端的目錄結構中我們並未直接看到我們提交的工程檔案,而利用TortoiseSVN (本地伺服器)和VisualSVN(遠端伺服器)的Repo-browse卻可以看到我們具體的專案檔案,如下圖。那麼我們提交的檔案又存到哪裡了呢?直觀猜測的話應該是db目錄下的某些檔案,因為隨著提交次數的增加,該檔案的大小也在變化。搜尋一下相關資料,找到了如下的回答:

“svn有兩種儲存方式:BDB和FSFS,目前用的最多的是FSFS方式,這種方式的話,一般是儲存在\db\revs資料夾下,裡面有一堆以版本號命名的檔案,如:0、1、2、3、4......,那個就是我們的工程檔案。svn先把0版本的狀態壓縮成1個檔案,然後每次版本更新時就針對變動的部分做一個壓縮檔案,每次都是增加一個增量包,最後在伺服器上能看到檔名為從0開始到最終版本的一系列檔案”

“SVN伺服器端不是簡單將上傳的檔案一個一個存放起來的,SVN伺服器端預設採用的FSFS格式是將每次commit的內容增量方式存放的,每個增量包存成1個檔案,這個增量包中包括了這次commit的全部資料。也就是說你不可能在伺服器端存放該版本庫的資料夾下找到你上傳的某個檔案”。

        至此我們就明白了SVN服務端的結構。至於客戶端就沒什麼難的了。就是通過網路協議將服務端的版本庫下載到本地,儲存在.svn目錄下,除此以外的就是自己的工程檔案了(如果你是從遠端SVN伺服器下載的別人的工程,那麼就是別人的工程檔案)。.svn中記錄的是你從SVN伺服器下載時刻時伺服器工程檔案的狀態,再下一次提交時刻,會與SVN伺服器通訊來檢視伺服器和你本地兩端的修改狀況。

image        由此我們可以看出要想對本地的修改進行記錄,必須要與SVN伺服器進行通訊,無法只是單純的儲存本地的修改。這也是我尋求Git的主要目的。百度百科對Git的描述是:“Git是一個開源的分散式版本控制系統,用以有效、高速的處理從很小到非常大的專案版本管理。分散式和集中式的最大區別在於開發者可以本地提交。每個開發者機器上都有一個伺服器的資料庫。”——反正就是一句話,Git可以完成上述我想要的本地修改記錄。

2)Git管理原生代碼修改

        第一步,Git的版本庫和工作副本在同一目錄下,叫做.git。安裝完Git後,可以直接在任意目錄下單擊右鍵,選擇Git Init Here,建立Git版本庫,即.git資料夾。(謹記:這是我們在本地建立的版本庫,壓根兒沒有伺服器毛關係啊,^_^。)

image

        第二步,直接將我們需要管理的本地工程拷貝到.git同目錄下。隨後我們想正常開發一樣開啟工程進行操作即可,直到我想儲存一下修改狀態時,我們就可以轉到第三步。

        第三步,在工程資料夾中右鍵,選擇Git Gui,會彈出管理視窗,這裡會顯示我們所做的修改,在紅色框中列出的是我們做過修改的檔案,橙色框中可以看到所做的修改。綠色框中顯示的是修改的緩衝區,通過在紅色框中選擇指定檔案進入到綠色的緩衝區後,我們可以單擊黃色按鈕“提交”,至此本次我們對本地檔案的修改記錄就已經提交了。

image

        第四步,在工程資料夾右鍵,選擇Git History,我們既可以看到本地的此次修改記錄。

imageimage

         至此我們就很容易的實現了對原生代碼修改的記錄,而這整個過程中,根本沒出現伺服器。這是與SVN最大的區別。

        今天就記錄到這裡,明天會對背景中的場景的進行詳細的介紹,給出Git的解決方案。

(未完待續……)