Git是Linux Torvalds(Linux之父)為了協助管理Linux核心開發而開發的一個開放源碼的分布式版本控制軟體,它不同於Subversion、CVS這樣的集中式版本控制系統。在集中式版本控制系統中只有一個倉庫(Repository),許多個工作目錄(Working Copy),而在Git這樣的分布式版本控制系統中(其他主要的分布式版本控制系統還有BitKeeper、Mercurial、GNU Arch、Bazaar、Darcs、SVK、Monotone等),每一個工作目錄都包含一個完整倉庫,它們支援離線工作,本地提交可以稍後提交到伺服器上。
至於Git的參考文檔,我推薦Git Magic,這裡還有一個Git Magic的中文版。
因為Android是由Kernel、Dalvik、Bionic、Prebuilt、build等多重專案組成,如果我們分別使用Git來逐個擷取顯得很麻煩,所以Android項目編寫了一個名為Repo的Python的指令碼來統一管理這些項目的倉庫,使得項目的擷取更加簡單。
在Ubuntu 8.04上安裝Git只需要設定正確的更新源,然後使用apt-get就可以了,apt-get是一條Linux命令,主要用於自動從互連網的軟體倉庫中搜尋、安裝、升級、卸載軟體或作業系統。
apt-get命令一般需要root許可權執行,所以一般跟著sudo命令。
sudo apt-get install git-core curl
這條命令會從互連網的軟體倉庫中安裝git-core和curl。
其中curl是一個利用URL文法在命令列方式下工作的檔案傳輸工具,它支援很多協議,包括FTP、FTPS、HTTP、HTTPS、TELENT等,我們需要安裝它從網路上擷取Repo指令檔。
curl http://android.git.kernel.org/repo >~/bin/repo
這句命令會下載repo指令檔到當前主目錄的/bin目錄下,並儲存在檔案repo中。
最後我們需要給repo檔案可執行許可權
chmod a+x ~/bin/repo
接下來我們就可以利用repo指令碼和Git、curl軟體擷取Android的原始碼了:)
首先建一個目錄,比如~/android。
然後使用下面命令擷取源碼:
repo init –u git://android.git.kernel.org/platform/manifest.git
這個過程會持續很長的時間下載完畢後會看到repo initialized in /android這樣的提示,說明本地的版本庫已經初始化完畢。
在運行這個工具的時候,它首先會去檢查目前的目錄下的.repo目錄,然後從指令碼內建的(或命令列指定的)一個地址 git://android.kernel.org/tools/repo.git 去使用git clone一份最新的repo工具的完整的版本庫放置到 .repo/repo 目錄下,之後checkout出最新的代碼。這些代碼就是repo的其它部分的代碼。這其中的 main.py 就是repo構建工具的主幹入口代碼。
而在之前的構造過程中的調用命令 $ repo init -u git://android.git.kernel.org/platform/manifest.git 中,repo首先完成了前面所說的對自身的更新和初始化,然後通過調用後面補充進來的程式碼完成init的操作。在這個操作中, repo從 git://android.git.kernel.org/platform/manifest.git 這個地址下載了一份整個源碼倉庫的清單的版本庫,並checkout出一份最新的清單,即 .repo/manifests/default.xml 檔案。該檔案是一個xml檔案,在這個檔案中描述了擷取代碼的遠程版本庫地址、其中所涉及到的每個項目的地址等等。下面是其中一部分:
<manifest branch="master">
<remote name="korg"
fetch="git://android.git.kernel.org/"
review="review.source.android.com" />
<project path="bionic" name="platform/bionic" />
<project path="external/clearsilver" name="platform/external/clearsilver">
<import>
<remap strip="clearsilver-%version%/" />
<mirror url="http://android.git.kernel.org/pub/clearsilver-%version%.tar.gz" />
<snapshot version="0.10.5" check="ec5fff5d7367ddd29a619cf81ae264687fde94c8" />
</import>
</project>
... ...
</manifest>
這裡只是截取了其中一小部分的片段用來說明問題。
remote節點的fetch屬性描述了遠端版本庫的基本地址,之後是一系列的project節點。每一個project節點都有一個path和name屬性,path是該項目在本地的儲存地址,如bionic則是儲存在本地的 ./repo/projects/bionic 下面,而name屬性是遠程版本庫中的路徑,與remote的fetch的地址結合起來即可得到該項目的版本庫地址,如bionic的版本庫是在 git://android.git.kernel.org/platform/bionic
而有的project定義中有import節點,該import節點中定義的一般都是該項目所依賴的第三方的獨立項目,這些項目是沒有曆史版本資訊的,因此只是一個tar.gz的包。repo在同步的過程中會將其下載下來,解壓、加入到該項目的版本庫中,並打上一個tag標記。
通過這個資訊清單檔,repo可以實現整個源碼庫的隨時更新和同步,這也是基於git的版本控制的特性所帶來的獨特的優勢。
如果我們想拿某個分支版本的代碼,而不是主線代碼,需要使用-b參數指定branch的名字,比如:
repo init –u git://android.git.kernel.org/platform/manifest.git –b cupcake
如果我們只是想擷取某一個project的代碼,比如kernel/common,就不需要repo指令碼了,直接使用Git工具即可,如果仔細研究repo指令碼會發現,repo指令碼其實就是組織Git工具去擷取各個Project並把它們組織到同一個項目Android內。
git clone git://android.git.kernel.org/kernel/common.git
我們上面使用repo指令碼擷取了各個項目,那麼接下來就需要把整個Android代碼樹同步到本地,如下:
repo sync
這樣就獲得了我們所需要的Android源碼