在現代軟件開發項目中,要成為一個有效的軟件開發人員,我們必須能夠與其他項目貢獻者並行進行開發。源代碼管理(SCM)系統不是什麼新思想。為了編寫一些能夠更快速、簡單地開發以後軟件項目的軟件,已經進行了很多嘗試。最新的源代碼解決方案都包含了版本控制系統,它可以對源代碼的修改進行回滾,從而將有害的代碼剔除出項目之外,或者簡單地跟蹤哪些人修改了代碼的哪些行的內容。版本控制系統試圖解決開發人員在試圖同時對某個文件進行修改時所出現的沖突問題,可以防止用戶覆蓋其他人所作的修改。源代碼管理使用的很多流行解決方案都試圖解決以前 SCM 解決方案中的失效問題。
集中化的版本控制系統通常采用兩種方式
有些提供了文件鎖來防止多個用戶的並行訪問。這些系統對文件進行加鎖,這樣在某個時間只有一個開發人員對中心倉庫具有寫入權限。
另外一些工具,例如 CVS,允許多個開發人員同時對相同的文件進行編輯,並提供了一些機制稍後合並這些修改。
流行的版本控制系統包括
CVS Subversion Arch Bazaar BitKeeper
什麼是 Git?
現在切換到包含新下載的內核的目錄中:
$ cd linux-2.6
現在,我們應該在本地機器上有一個可以工作的 Linux 2.6 倉庫了!此時我們就可以對這個倉庫進行一些基本的操作了。
更新本地 Git 倉庫
在使用 Git 時,我們通常可以假設自己的倉庫可能比 kernel.org 的倉庫有些滯後。因此我們通常都是首先將自己的倉庫更新成最新的上游內核樹。這個過程有時稱為快速合並(fast-forward merge)。嚴格來說,我們現在並不需要執行這個過程,因為我們剛剛安裝了自己的倉庫,它應該還沒有過期。但是檢查一下畢竟沒有壞處:
$ cd linux-2.6
$ git-pull git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
...
如果成功,我們就應該會看到類似於下面的輸出結果:
receiving file list ... done sent 130 bytes received 21677 bytes 14538.00 bytes/sec total size is 127865858 speedup is 5863.52 Already up-to-date. $>
如果我們的倉庫不是最新的,就會看到有些內容通過網絡傳輸到本地機器上了。
從倉庫中導出文件
我們需要將文件從 Git 倉庫(隱藏目錄中的那些文件)中導出到工作目錄中才能開始自己的 hack 過程。下面的命令會在當前目錄中寫入沒有隱藏的目錄,其中包含了 Linux 的源代碼:
$ git-checkout
如果您希望覆蓋本地修改,可以使用 -f 選項導出文件,這樣就可以將您帶回到一個干淨的狀態:
$ git-checkout -f
現在在當前工作目錄中,我們應該就可以看到熟悉的 Linux 源代碼目錄結構了,然後我們可以對這些源代碼任意進行修改。
修改現有文件
我們現在可以修改所選擇的任何文件。舉一個簡單的例子來說,我們將修改 docs 目錄中的一些內容:添加一條以後可以很容易識別的信息。為了讓我的例子更容易試驗,我沒有選擇修改源代碼;不過只要您希望,歡迎繼續重寫整個內核的子系統。
首先,讓我們在編輯器中打開一個文件:
$ vi ./Documentation/ManagementStyle
顯然,我使用的是 vi;不過您當然可以使用自己喜歡的任何編輯器來完成這項工作。在編輯文件時,我在第一段前面添加了一行:“Eli shall be in charge of managing sandwich consumption. See Documentation/Sandwiches for more.”
如果您對自己所做的修改非常滿意,並且覺得自己已經准備好將其作為倉庫的一個永久部分了,就需要使用下面的命令導入您的修改:
$ git-commit Documentation/ManagementStyle
您會被提示說要求提供一個提交消息,它是一個用戶生成的注釋,用來幫助其他開發人員(也可能是您自己以後)理解剛才的實現到底進行了哪些修改。在我們的例子中,提交消息是一個描述剛才對文檔所做修改的短句。
如果您希望檢查一下到目前為止工作的狀態,可以執行 git-log 來查看本地倉庫的歷史(它繼承了所克隆的倉庫的信息)。您的提交消息應該在日志的最上面。
添加或刪除文件
但是請等一下!我們還沒有添加 Documentation/Sandwiches 文件呢,因此我們需要將其添加到工作目錄中,並告訴 Git 何時這個文件已經准備好了。我使用 echo 命令創建了想要添加的文件,因為這只是一個簡單的例子而已。同樣,您也可以使用自己喜歡的工具。
$ echo "Turkey is superior" > Documentation/Sandwiches
現在我們已經添加了一個文件,接下來需要將這個文件添加到 Git 中,從而讓 Git 了解這種變化,然後才能提交這個版本。我們可以通過執行下面的命令來完成這些任務:
$ git-add Documentation/Sandwiches
$ git-commit Documentation/Sandwiches
如果您添加了多個文件,可以在同一行中的 git-add 命令後面列出這些文件,不過您也不必一次將它們全部添加到倉庫中去。如果要刪除某個文件,並且沒有 git-add 之類的特殊命令;您只需要刪除這個文件,然後提交就可以了。
現在應該查看一下 git-log,從而確保到現在為止所做的事情都是正確的。這一次,我們將使用 -p 選項來以單獨的補丁格式查看日志。
$git-log -p
創建 diff 文件
最後,我們希望生成一個包含您修改後的文件和原文件之間區別的文本文件。這個文件通常是使用 diff 工具創建的,因此就稱為 diff 文件。diff 可以幫助我們創建補丁文件(patch file),後者是我們向很多開放源碼軟件項目發送代碼提交時通常使用的方法。有關 diff 的更多內容,請參看下面 參考資料 部分中有關 Kernel.org 的鏈接。
Git 還可以干什麼?
我們可以使用 Git 來管理本地倉庫,而不用鏡像其他人的工作。例如,如果我們喜歡使用 Git 來管理自己個人對某個開放源碼項目貢獻的文件,就可以從項目快照中生成一個 Git 倉庫。
假設我們已經有了一個名為 release.tar.gz 的標准 release tarball,可以執行下面的命令來創建一個本地的 Git 倉庫:
$ tar -zxvf release.tar.gz
$ cd release
$ git init-db
我們可以看到消息說 Git 是 “默認於本地存儲區域的”。這些消息都是正常的,說明我們有一個 Git 倉庫。
現在我們已經對工作目錄進行了初始化,接下來在項目目錄中應該會看到一個新目錄 .git。為了告訴 Git 我們希望對這個項目中的每個文件都進行跟蹤,請執行下面的命令:
$ git add .
最後,使用下面的命令將所監視的文件提交到倉庫中:
$ git commit -a
同樣,系統會提示我們輸入提交消息。從現在開始,我們就可以在自己的 Git 倉庫中使用 Git 所提供的完整功能了,例如對實驗特性進行分支,為了追蹤回歸測試問題而將代碼一分為二,並使用常見的版本歷史功能。
有關 Git 的分支管理和其他有趣特性的更多信息,請參看 Kernel.org 上給出的 Git 的優秀教程(參見 參考資料 中的鏈接)。
結束語
現在我們已經知道如何使用 Git 來獲取 Linux 內核源代碼和其他 Git 管理的項目了,接下來可以選擇使用 Git 來管理下一個開發項目。 Git 仍然相對較新,仍然處於不斷開發中。其他腳本和工具正在實現用來簡化 Git 的使用;請參看 參考資料 中給出的例子。
非常簡單地說,Git 是 Linus Torvalds 最近實現的源代碼管理軟件。正如所提供的文檔中說的一樣,“Git 是一個快速、可擴展的分布式版本控制系統,它具有極為豐富的命令集,對內部系統提供了高級操作和完全訪問。”
Torvalds 開始著手開發 Git 是為了作為一種過渡方案來替代 BitKeeper,後者之前一直是 Linux 內核開發人員在全球使用的主要源代碼工具。開放源碼社區中的有些人覺得 BitKeeper 的許可證並不適合開放源碼社區的工作,因此 Torvalds 決定著手研究許可證更為靈活的版本控制系統。盡管最初 Git 的開發是為了輔助 Linux 內核開發的過程,但是我們已經發現在很多其他自由軟件項目中也使用了 Git。例如,X.org 最近就遷移到 Git 上來了,很多 Freedesktop.org 的項目也遷移到了 Git 上。
Git 目前主要由尋找 CVS 或專有代碼管理解決方案替代物的軟件開發人員所使用。Git 與 CVS 有很多區別:
分支更快、更容易。
支持離線工作;本地提交可以稍後提交到服務器上。
Git 提交都是原子的,且是整個項目范圍的,而不像 CVS 中一樣是對每個文件的。
Git 中的每個工作樹都包含一個具有完整項目歷史的倉庫。
沒有哪一個 Git 倉庫會天生比其他倉庫更重要。
安裝
要安裝當前版本的 Git,我們可以使用供應商在 Linux 發行版中提供的包,或者從最新的穩定快照開始手工進行編譯。我建議下載包含最新 Git 源代碼穩定快照的 tarball;截止到撰寫本文時這個版本是 v1.4.0。我們可以在下面的 參考資料 一節中找到鏈接。
有了這個 tarball 之後,請確保初始安裝所依賴的包都已經安裝了。系統中必須包含以下包,以及相應的開發頭文件:
zlib
libcurl
libcrypto(OpenSSL)
rsync(2.6.0 或更高版本)
這些條件滿足之後,我們就可以開始編譯初始的 Git 安裝系統了。這個過程對於大部分一直使用 Linux 的開發人員來說應該非常熟悉了。首先使用對應下載的包格式的命令將包展開:
$ tar -jxvf git-1.4.0.tar.bz2或
$ tar -zxvf git-1.4.0.tar.gz
然後切換到適當的目錄中,並執行 make 命令。(注意目錄名取決於我們下載的快照的日期。)
$ cd git-1.4.0/ $ make prefix=/usr/local install $ sudo make prefix=/usr/local install
您會被提示輸入 sudo 密碼才能繼續安裝。現在就已經准備好使用 Git 工具了。
獲得最新的內核源代碼樹
在使用 Git 管理源代碼倉庫時,我們可以使用兩種方法開始我們的工作。我們可以使用現有代碼的一個本地目錄,然後從中生成一個倉庫;也可以映射其他人發布的倉庫。
對於本文的目的來說,我們將獲得 Torvalds 發布的 Git 倉庫的一個鏡像。下面的命令將創建一個名為 linux-2.6 的 Git 倉庫。這個目錄包含了一個隱藏目錄 .git/ 。
$ git-clone \
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \linux-2.6
這個步驟會執行很長時間,因為 Git 正在將內核源代碼(這有數百兆大)從 kernel.org 傳輸到本地機器上。輸出結果可能有些晦澀難懂,但是如果您有一個快速的 Internet 鏈接,卷屏的速度應該相當快。輸出結果應該類似於圖 1 所示。