Skip to content
This repository has been archived by the owner on May 2, 2019. It is now read-only.

Latest commit

 

History

History
265 lines (146 loc) · 19.4 KB

01-chapter1.markdown

File metadata and controls

265 lines (146 loc) · 19.4 KB

開始

本章介紹Git的相關知識。 先從講解一些版本控制工具的背景知識開始,然後試著在讀者的系統將Git跑起來,最後則是設定它。 本在章結束,讀者應瞭解為什麼Git如 此流行、為什麼讀者應該利用它、以及完成使用它的準備工作。

關於版本控制

什麼是版本控制? 以及為什麼讀者會在意它? 版本控制是一個能夠記錄一個或一組檔案在某一段時間的變更,使得讀者以後能取回特定版本的系統。 在本書的範例中,讀者會學到如何對軟體的原始碼做版本控制。 即使實際上讀者幾乎可以針對電腦上任意型態的檔案做版本控制。

若讀者是繪圖或網頁設計師且想要記錄每一版影像或版面配置(這也通常是讀者想要做的),採用版本控制系統(VCS)做這件事是非常明智的。 它允許讀者將檔案復原到原本的狀態、將整個專案復原到先前的狀態、比對某一段時間的修改、查看最後是誰在哪個時間點做了錯誤的修改導致問題發生,等。 使用版本控制系統一般也意謂著若讀者做了一些傻事、或者遺失檔案,讀者能很容易的回復。 更進一步,僅需付出很小的代價即可得到這些優點。

本地端版本控制

許多讀者採用複製檔案到其它目錄的方式來做版本控制(若他們夠聰明的話,或許會是有記錄時間戳記的目錄)。 因為它很簡單,這是個很常見的方法;但它也很容易出錯。 讀者很容易就忘記在哪個目錄,並不小心的把錯誤的檔案寫入、或者複製到不想要的檔案。

為了解決這問題,設式設計師在很久以前開發了本地端的版本控制系統,具備簡單的資料庫,用來記載檔案的所有變更記錄(參考圖1-1)。

Insert 18333fig0101.png 圖1-1。 本地端版本控制流程圖。

這種版本控制工具中最流行的是RCS,目前仍存在於許多電腦。 即使是流行的Mac OS X作業系統,都會在讀者安裝開發工具時安裝rcs命令。 此工具基本上以特殊的格式記錄修補集合(即檔案從一個版本變更到另一個版本所需資訊),並儲存於磁碟上。 它就可以藉由套用各修補集合産生各時間點的檔案內容。

集中式版本控制系統

接下來人們遇到的主要問題是需要多位其它系統的開發協同作業。 為了解決此問題,集中式版本控制系統被發展出來。 此系統,如:CVS、Subversion及Perforce皆具備單一伺服器,記錄所有版本的檔案,且有多個客戶端從伺服器從伺服器取出檔案。 在多年後,這已經是版本控制系統的標準(參考圖1-2)。

Insert 18333fig0102.png 圖1-2. 集中式版本控制系統

這樣的配置提供了很多優點,特別是相較於本地端的版本控制系統來說。 例如:每個人皆能得知其它人對此專案做了些什麼修改有一定程度的瞭解。 管理員可調整存取權限,限制各使用者能做的事。 而且維護集中式版本控制系統也比維護散落在各使用者端的資料庫來的容易。

然而,這樣的配置也有嚴重的缺點。 最明顯的就是無法連上伺服器時。 如果伺服器關閉一個小時,在這段時間中沒有人能進行協同開發的工作或者將變更的部份傳遞給其它使用者。 如果伺服器用來儲存資料庫的硬碟損毀,而且沒有相關的偏份資料。 除了使用者已取到自己的電腦的版本外,所有資訊,包含該專案開發的歷史都會遺失。 本地端版本控制系統也會有同樣的問題,只要使用者將整個專案的開發歷史都放在同一個地方,就有遺失所有資料的風險。

分散式版本控制系統

這就是分散式版本控制系統被引入的原因。 在分散式版本控制系統,諸如:Git、Mercurial、Bazaar、Darcs。 客戶端不只是取出最後一版的檔案,而是複製整個儲存庫。 即使是整個系統賴以運作的電腦損毀,皆可將任何一個客戶端先前複製的資料還原到伺服器。 每一次的取出動作實際上就是完整備份整個儲存庫。(參考圖1-3)

Insert 18333fig0103.png 圖1-3. 分散式版本控制系統

更進一步來說,許多這樣子的系統皆能同時與數個遠端的機器同時運作。 因此讀者能同時與許多不同群組的人們協同開發同一個專案。 這允許讀者設定多種集中式系統做不到的工作流程,如:階層式模式。

Git 的簡史

如同許多生命中美好的事物一樣,Git從有一點創意的破壞及激烈的討論中誕生。 Linux kernel 是開放原始碼中相當大的專案。 在 Linux kernel 大部份的維護時間內(1991~2002),修改該軟體的方式通常以多個修補檔及壓縮檔流通。 在2002年,Linux kernel 開始採用名為 BitKeeper 的商業分散式版本控制系統。

在 2005年,開發 Linux kernel 的社群與開發 BitKeeper 的商業公司的關係走向決裂,也無法再免費使用該工具。 這告訴了 Linux 社群及 Linux 之父 Linus Torvalds,該是基於使用 BitKeeper 得到的經驗,開發自有的工具的時候。 這個系統必須達成下列目標:

  • 快速
  • 簡潔的設計
  • 完整支援非線性的開發(上千個同時進行的分支)
  • 完全的分散式系統
  • 能夠有效的處理像 Linux kernel 規模的專案(快速及資料大小)

自從 2005 年誕生後,Git已相當成熟,也能很容易使手,並保持著最一開始的要求的品質。 它不可思議的快速、處理大型專案非常有效率、也具備相當優秀足以應付非線性開發的分支系統。(參考第三章)

Git 基礎要點

那麼,簡單的說,Git是一個什麼樣的系統? 這一章節是非常的重要的。 若讀者瞭解什麼是Git以及它的基本工作原因,那麼使用垉來就會很輕鬆且有效率。 在學習之前,試著忘記以前所知道的其它版本控制系統,如:Subversion 及 Perforce。 這將會幫助讀者使用此工具時發生不必要的誤會。 Git儲存資料及運作它們的方式遠異於其它系統,即使它們的使用者介面是很相似的。 瞭解這些差異會幫助讀者更準確的使用此工具。

記錄檔案快照,而不是差異的部份

Git與其它版本控制系統(包含Subversion以及與它相關的)的差別是如何處理資料的方式。 一般來說,大部份其它系統記錄資訊是一連串檔案更動的內容。 如圖1-4所示。 這些系統(CVS、Subversion、Perforce、Bazaar等等)儲存一組基本的檔案以及隨時間遞增而更動這些檔案的資料。

Insert 18333fig0104.png 圖1-4. 其它系統傾向儲存每個檔案更動的資料。

Git並不以此種方式儲存資料。 而是將其視為小型檔案系統的一組快照。 每一次讀者提交更新時、或者儲存目前專案的狀態到Git時。 基本上它為當時的資料做一組快照並記錄參考到該快照的參考點。 為了講求效率,只要檔案沒有變更,Git不會再度儲存該檔案,而是記錄到前一次的相同檔案的連結。 Git的工作方式如圖1-5所示。

Insert 18333fig0105.png 圖1-5. Git儲存每次專案更新時的快照。

這是Git與所有其它版本控制系統最重要的區別。 它完全顛覆傳統版本控制的作法。 這使用Git更像一個上層具備更強大工具的小型的檔案系統,而不只是版本控制系統。 我們將會在第三章介紹分支時,提到採用此種作法的優點。

大部份的動作皆可在本地端完成

大部份Git的動作皆只需要本地端的檔案及資源即可完成。 一般來說並需要到網路上其它電腦提取的資訊。 若讀者使用集中式版本控制系統,大部份的動作皆包含網路延遲的成本。 這項特點讓你覺得Git處理資料的速度飛快。 因為整個專案的歷史皆存在你的硬碟中,大部份的運作看起來幾乎都是馬上完成。

例如:瀏覽器專案的歷史,Git不需要到伺服器下載歷史,而是從本地端的磁碟機讀出來並顯示。 這意謂著讀者幾乎馬上就可以看到專案的歷史。 若讀者想瞭解某個檔案一個月前的版本及現在版本的差別,Git可在本地端找出一個月前的檔案並在比對兩者的差異,而不是要求遠端的伺服器執行這項工作,或者從伺服器取回舊版本的檔案並在本地端比對。

這意謂著即使讀者已離線,或者切斷VPN連線後,也很少有讀者無法執行的動作。 若讀者在飛機或火車上,並想要做一些工作,讀者在取得可上傳的網路前仍可很快樂的提交更新。 若讀者回到家且無法讓VPN連線程式正常運作,讀者仍然可繼續工作。 在許多其它系統幾乎是無法做這些事或者必須付出很大代價。 以Perforce為例,在無法連到伺服器時讀者做不了多少事。以Subversion及CVS為例,雖然讀者能編輯檔案,但因為資料庫此時是離線的,讀者無法提交更新到資料庫。 這看起來可能還不是什麼大問題,但讀者可能驚訝Git有這麼大的不同。

Git能檢查完整性

在Git中所有的物件在儲存前都會被計算查核碼並以查核碼檢索物件。 這意謂著Git不可能不清楚任何檔案或目錄的內容已被更動。 此功能內建在Git底層並整合到它的設計哲學。 Git不可能偵測不出讀者在傳輸或取得有問題的檔案。

Git用來計算查核碼的機制稱為SHA1雜湊法。 它由40個十六進制的字母組成的字串組成,基於Git的檔案內容或者目錄結構計算。 查核碼看起來如下所示:

24b9da6552252987aa493b52f8696cd6d3b00373

讀者會Git中到處都看到雜湊值,因為它到處被使用。 事實上Git以檔案內容的雜湊值定址出放置資料的地方,而不是檔案名稱。

Git 通常只增加資料

當讀者使用Git,幾乎所有的動作只是增加資料到Git的資料庫。 很難藉此讓做出讓系統無法復原或者清除資料的動作。 在任何版本控制系統,讀者有可能會遺失或者搞混尚未提交的更新。 但是在提交快照到Git後,很少會有遺失的情況,特別是讀者定期將資料庫更新到其它儲存庫。

這讓使用Git可輕鬆的像在玩一樣,因為我們知道我們可以進行任何實驗而不會破壞任何東西。 在第九章的“底層細節”中,我們會進一步討論Git如何儲存資料,以及讀者如何復原看似遺失的資料。

三種狀態

現在,注意。 若讀者希望接下來的學習過程順利些,這是關於Git的重要且需記住的事項。 Git有三種表達檔案的狀態:已提交、已修改及已暫存。 已提交意謂著資料己安全地存在讀者的本地端資料庫。 己修改代表著讀者已修改檔案但尚未提交到資料庫。 已暫存意謂著讀者標記已修改檔案目前的版本到下一次提供的快照。

這帶領我們到Git專案的三個主要區域:Git目錄、工作目錄及暫存區域。

Insert 18333fig0106.png 圖1-6. 工作目錄、暫存區域及git目錄。

Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這是Git最重要的部份而且它是當讀者從其它電腦複製儲存庫時會複製過來的。

工作目錄是專案被取出的某一個版本。 這些檔案從Git目錄內被壓縮過的資料庫中拉出來並放在磁碟機供讀者使用或修改。

暫存區域是一個單純的檔案,一般來說放在Git目錄,儲存關於下一個提交的資訊。 有時稱為索引,但現在將它稱為暫存區域已開始成為標準。

基本Git工作流程大致如下:

  1. 讀者修改工作目錄內的檔案。
  2. 讀者將檔案的快照新增到暫存區域。
  3. 做提交的動作,這會讓存在暫存區域的檔案快照永久的儲存在Git目錄。

在Git目錄內特定版本的檔案被認定為已提交。 若檔案被修改且被增加到暫存區域,稱為被暫存。 若檔案被取出後有被修改,但未被暫存,稱為被修改。 在第二章讀者會學到更多關於這些狀態以及如何利用它們的優點或者整個略過暫存步驟。

安裝Git

Let’s get into using some Git. First things first—you have to install it. You can get it a number of ways; the two major ones are to install it from source or to install an existing package for your platform. 讓我們開始使用Git。 首先讀者要做的事是安裝Git。 讀者有很多取得它們的方法。 主要的兩種分別是從原始碼安裝或者從讀者使用平台現存的套件安裝。

從原始碼安裝

若讀者有能力的話,從原始碼安裝是非常有用的。 因為讀者能取得最新版本。 每一版Git通常都會包含有用的UI改善。 因此取得最新版本通常是最好的,只要讀者覺得編譯軟體的原始碼是很容易的。 許多Linux發行套件通常都是附上非常舊的套件。 除非讀者使用的發行套件非常新或者使用向後相容的移植版本。 從原始碼安裝通常是最好的選擇。

要安裝Git,讀者需要先安裝它需要的程式庫:curl、zlib、openssl、expat及libiconv。 例如:若讀者的系統有yum(如:Fedpra)或apt-get(如:以Debian為基礎的系統),讀者可使用下列任一命令安裝所有需要的程式庫:

$ yum install curl-devel expat-devel gettext-devel \
  openssl-devel zlib-devel

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
  libz-dev

當讀者安裝所有必要的程式庫,讀者可到Git的網站取得最新版本:

http://git-scm.com/download

接著,編譯及安裝:

$ tar -zxf git-1.6.0.5.tar.gz
$ cd git-1.6.0.5
$ make prefix=/usr/local all
$ sudo make prefix=/usr/local install

在這些工作完成後,讀者也可以使用Git取得Git的更新版:

$ git clone git://git.kernel.org/pub/scm/git/git.git

在Linux系統安裝

若讀者想使用二進位安裝程式安裝Git到Linux,一般來說讀者可經由發行套件提供的套件管理工具完成此工作。 若讀者使用Fedora,可使用yum:

$ yum install git-core

若讀者在以Debian為基礎的發行套件,如:Ubuntu。 試試apt-get:

$ apt-get install git

在Mac系統安裝

有兩種很容易將Git安裝到Mac的方法。 最簡單的是使用圖形化界面的Git安裝程式,可從Google Code下載)圖1-7):

http://code.google.com/p/git-osx-installer

Insert 18333fig0107.png 圖1-7. Git OS X 安裝程式。

藉由MacPorts安裝Git是另一種主要的方法。 若讀者已安裝MacPorts,使用下列命令安裝Git

$ sudo port install git-core +svn +doc +bash_completion +gitweb

讀者完全不需要安裝所有的額外套件,但讀者可能會想要加上+svn參數,以利於使用Git讀寫Subversion儲存庫(參考第8章)

在Windows系統安裝

在Windows系統安裝Git相當的容易。 msysGit專案已提供相當容易安裝的程序。 只要從GitHub網頁下載安裝程式並執行即可:

http://msysgit.github.com/

在安裝完畢後,讀者同時會有命令列版本(包含SSH客戶端程式)及標準的圖形界面版本。

初次設定Git

現在讀者的系統已安裝了Git,讀者可能想要做一些客製化的動作。 讀者應只需要做這些工作一次。 這些設定在更新版本時會被保留下來。 讀者可藉由再度執行命令的方式再度修改這些設定。

Git附帶名為git config的工具,允許讀者取得及設定組態參數,可用來決定Git外觀及運作。 這些參數可存放在以下三個地方:

  • 檔案 /etc/gitconfig: 包含給該系統所有使用者的儲存庫使用的數值。 只要讀者傳遞 --system 參數給 git config,它就會讀取或者寫入參數到這個檔案
  • 檔案 ~/.gitconfig: 給讀者自己的帳號使用。 傳遞 --global 參數給 git config,它就會讀取或者寫入參數到這個檔案。
  • 儲存庫內的設定檔,也就是 .git/config: 僅給所在的儲存庫使用。 每個階級的設定會覆寫上一層的。 因此.git/config內的設定值的優先權高過/etc/config。

在Windows系統,Git在$HOME目錄(對大部份使用者來說是C:\Documents and Settings\$USER)內尋找.gitconfig。 它也會尋找/etc/gitconfig,只不過它是相對於Msys根目錄,取決於讀者當初在Windows系統執行Git的安裝程式時安裝的目的地。

設定識別資料

讀者安裝Git後首先應該做的事是指定使用者名稱及電子郵件帳號。 這一點非常重要,因為每次Git提交會使用這些資訊,而且提交後不能再被修改:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

再說一次,若讀者有指定 --global 參數,只需要做這工作一次。 因為在此系統,不論Git做任何事都會採用此資訊。 若讀者想指定不同的名字或電子郵件給特定的專案, 只需要在該專案目錄內執行此命令,並確定未加上 --global 參數。

指定編輯器

現在讀者的識別資料已設定完畢,讀者可設定預設的文書編輯器,當Git需要讀者輸入訊息時會叫用它。 預設情況下,Git會使用系統預設的編輯器,一般來說是Vi或Vim。 若讀者想指定不同的編輯器,例如:Emacs。可執行下列指令:

$ git config --global core.editor emacs

指定合併工具

另外一個對讀者來說有用的選項是設定解決合併失敗時,讀者慣用的合併工具。 假設讀者想使用vimdiff:

$ git config --global merge.tool vimdiff

Git能接受kdiff3、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff、ecmerge及opendiff做為合併工具。 讀者可設定自訂的工具。 詳情參考第七章。

檢查讀者的設定

若讀者想確認設定值,可使用 git config --list 命令列出所有Git能找到的設定值:

$ git config --list
user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

讀者可能會看到同一個設定名稱出現多次,因為Git從不同的檔案讀到同一個設定名稱(例如:/etc/gitconfig及~/.gitconfig)。 在這情況下,Git會使用最後一個設定名稱的設定值。

使用者也可以下列命令 git config 設定名稱,檢視Git認為該設定名稱的設定值:

$ git config user.name
Scott Chacon

取得說明文件

若讀者在使用Git時需要幫助,有三種方法取得任何Git命令的手冊:

$ git help 命令
$ git 命令 --help
$ man git-命令

例如:讀者可以下列命令取得config命令的手冊

$ git help config

這些命令對讀者是很有幫助的,因為讀者可在任意地方取得它們,即使已離線。 若手冊及這本書不足以幫助讀者,且讀者需要更進一步的協助。 讀者可試著進入Freenode IRC伺服器(irc.freenode.net)的#git或#github頻道。 這些頻道平時都有上百位對Git非常瞭解的高手而且通常樂意協助。

總結

目前讀者應該對於Git有一些基本的瞭解,而且知道它與其它集中式版本控制系統的不同,其中有些可能是讀者正在使用的。 讀者的系統現在也應該有一套可動作的Git且已設定好讀者個人的識別資料。 現在正是學習一些Git的基本的操作的好時機。