Fork me on GitHub

版本控制


版本控制(Revision control)是維護工程藍圖的標準作法,能追蹤工程藍圖從誕生一直到定案的過程。此外,版本控制也是一種軟體工程技巧,藉此能在軟體開發的過程中,確保由不同人所編輯的同一程式檔案都得到同步。

為什麼使用版本控制?

在軟體開發的過程中,程式碼每天不斷地產出,過程中會發生以下情況:
  • 檔案被別人或自己覆蓋,甚至遺失
  • 想復原前幾天寫的版本
  • 想知道跟昨天寫的差在哪裡?
  • 是誰改了這段程式碼,為什麼 ?
  • 軟體發行,需要分成維護版跟開發版
因此,我們希望有一種機制,能夠幫助我們:
  • 可以隨時復原修改,回到之前的版本
  • 多人協作時,不會把別人的東西蓋掉
  • 保留修改歷史記錄,以供查詢
  • 軟體發行時,可以方便管理不同版本

定義

一個版本控制系統 Version Control System (VCS),通常有以下功能

  1. 建立 Repository,用來保存程式碼。
  2. 方便散佈程式給團隊,有效率協同開發
  3. 記錄誰改變什麼、在什麼時候、因為什麼原因
  4. Branch(分支),可因不同情境分開開發
  5. Tag(標籤) 重要里程碑,以便參照
那麼,什麼東西要存進 Repository 呢? 簡單來說,就是所有跑起來這個專案需要的東西,包括所有原始碼、範例設計檔、文件等等。而像是暫存檔、log 檔案、build files 等編譯後的產物則不需要存進 Repository。

演進歷史

版本控制系統從古至今,有幾種不同的模式:

  1. Local VCS
  2. Centralized VCS (Lock型,悲觀鎖定)
  3. Centralized VCS(Merge型,樂觀鎖定)
  4. Distributed VCS

Local VCS
在本地端使用 copy paste 進行資料夾管理,例如 rcs。當然,缺點是無法協同開發。

Centralized VCS (Lock型,悲觀鎖定)
有一中央團隊共用的Repository,當有人要編輯某個檔案時,進行鎖定,以避免其他人也同時編輯造成衝突。
雖然可以避免衝突,但是很不方便。其他人得排隊才能編輯檔案,萬一先取出的人寫很久或忘記 解除鎖定,後果將不堪設想。

Centralized VCS(Merge型,樂觀鎖定)
也是有一中央團隊共用的Repository,但是不用Lock來避免衝突,而是事後發現如果有別人也修改同一個檔案(稱作衝突),再進行手動編修解決。有非常多的VCS屬於這一型,包括CVS, Subversion, Perforce等等。Centralized VCS 的共同缺點是做什麼事都要跟伺服器連線,會比較慢。另外也有單點故障的風險(Single point of failure),只要伺服器壞掉,大家就不用作事了。

Distributed VCS
分散式版本控制系統讓本地端也擁有完整的Repository,就沒有上述集中式的問題,即使沒網路,照常可以 commit 和看 history log,也不用擔心server備份。例如 Git, Mercurial(Hg), Bazaar 等就是屬於分散式版本控制系統。
若要說有什麼缺點,就是能力越大,功能就越複雜,一開始學習上會比較辛苦一點。

Git 名詞解釋


物件模式(Object Mode)

Git 中一共有四種模式 : Blob﹑Tree﹑Commit﹑Tag。
  • Blob: 只是用來儲存檔案內容,連檔案名字都沒有。
  • Tree: Tree 可以儲存文件名,同時也允許儲存一組檔案。所有内容以 Tree 或 Blob儲存,其中 Tree 對應於 UNIX 中的目錄,Blob 則大致對應於 nodes 或檔案内容。
  • Commit: Commit 為你保存了關於誰、何時以及為何保存了這些快照的訊息。
  • Tag: Tag 非常像一個 Commit ——包含一個標籤,一组數據,一個消息和一個指针。最主要的區别就是 Tag指向一個 Commit 而不是一個 tree。它就像是一個分支引用,但是不會變化——永遠指向同一個 Commit,僅僅是提供一個更加友好的名字。
Note : 可以把Blob 看作是檔案,Tree 看作是資料夾,Commit 看作是每次的更新,Tag 為大事件

Git 參照 ( Git References )

你可以執行像
 git log 1a410e 
這樣的指令來查看完整的紀錄,但是這樣你就要記得 1a410e 是你最後一次 commit,這樣才能在 commit history 中找到這些物件。你需要一個檔案來用一個簡單的名字來記錄這些 SHA-1 值,這樣你就可以用這些 pointer 而不是原來的 SHA-1 值去搜尋了。在 Git 中,我們稱之為 reference(references or refs),以下是 Git 中常用的 reference 介紹。
  1. head: 是一個指向你當前所在分支的引用標示符號。
  2. tag: tag 是一個物件也是一個引用,我們在之前已經做過了詳細的說明。
  3. remote: 是一個標示符號指向你最後一次和伺服器的通訊的分支。
  4. branch: 是一個指向每個分支最前面 commit 的指標,告訴使用者分支名稱。

Git 基本結構


Github 教學


簡介


Github 是一個 git 的托管網站,可以讓開發者將自己的專案儲存到網路上,與全世界分享,我們可以方便的使用 Git 在本機進行專案管理。
GitHub 同時提供付費帳號和為了開放原始碼程式提供的免費帳號。根據 2009 年的 Git 使用者調查,GitHub 是最熱門的 Git 分享網站。它提供了如 feeds、followers 和顯示開發者們如何在他們版本庫上的版本工作的圖表。 GitHub 也提供類似剪貼簿的功能,issue tracker 和網頁使用 Wiki,通過一個 git repository 即可對這些頁面進行編輯。


建立帳號



建立新repository


在和本機的 repository 連動之前,先給自己的專案取個名字吧,這會是你專案之後的名字,也會是其他人搜尋你專案的時候的關鍵字,好的專案一定有一個好的名字。


綁定機器的 SSH KEY


因為要讓 Github 知道是我們這台電腦上傳的專案,所以我們要和 Github 之間建立一種默契,這個默契就是使用 ssh 協定時的 public key,我們給 Github 我們本機的 ssh public key ,告訴 Github 拿著這個 key 的電腦才是這個帳號的使用者, 如此一來就只能由這台電腦進行管理,才不會造成其他人來我們的帳號亂上傳東西的窘境。

首先,點選右上角的工具按鈕,進入帳號設定頁面,在頁面的左下角點選 SSH KEY


這個時候需要打開終端機產生本機的 SSH KEY,並將產生的 SSH KEY 加入到 Github 的帳號之中,若是不知道產生 SSH KEY的方法,可以參考以下的 網頁


將本機 repository 和 Github repository 同步


打開空的 repository,Github 會指示你如何將本機 repository remote 到 Git 的 repository 進入到本機的 repository 資料夾之中,並輸入以下指令,即可連線並把目前的 repository 同步到 Github 上面了。

								    git remote add origin git@github.com:your_account/sandbox.git
git push -u origin master
之後只需要
 
									git push
即可


Folk 其他使用者的專案

Fork 是一個較為特殊的稱呼方式,意思是將其他使用者的 repository 複製到本機,我也可以直接透過他的 repository 來自己修改這個專案,讓這個專案更好。
如果你有寫入權限的話(被加入成Collaborators),就可以用 SSH 協定 Clone 下來:

									git clone git@github.com:Username/repository.git 

如果沒有寫入權限 (Collaborators)的話,因為這個專案是公開的,所以你還是可以用 Git 協定 Clone 下來:
									git clone git://github.com/Username/repository.git

如果有防火牆問題,改用 HTTPS 協定:
									git clone https://github.com/Username/repository.git
								


Pull - 從遠端更新


									git pull 或 git pull origin master
實際作用是先 git fetch 遠端的 branch,然後與本地端的 branch 做 merge,產生一個 merge commit 節點


Push - 將 Commit 送出去


									git push 或 git push origin master
實際的作用是將本地端的 master branch 與遠端的 master branch 作 fast-forward 合併。如果出現 [rejected] 錯誤的話,表示你必須先作 pull。


Git 的應用


Linux kernel

Git 是由 Linux 的發明人 Linus Torvalds 所發明的,其目的就是為了更好的管理 Linux Kernel,所以 Linux kernel 可以算是應用方面最有說服力的例子了



Linux kernel on Github:
									https://github.com/torvalds/linux
							

台灣零時政府


政策瞎,官員混,立委貪,政府爛,總統笨…… 除了生氣翻桌,到底還能做什麼?讓我們來寫程式改造社會!
g0v.tw 是一個致力於打造資訊透明化的社群。g0v.tw 的參與者來自四方, 有程式開發者、設計師、社會運動工作者、教育工作者、文字工作者、 公民與鄉民等來自各領域的人士。這些人聚在一起, 希望資訊透明化可以更進一步的改善台灣的公民環境。 只要有心想用自己的專業及能力來參與,就可以加入 g0v.tw。
有心想要參與的同學們,可以參考這個網站 ,看看可以為我們的社會付出什麼。

g0v.tw 的 Github Repository:
									https://github.com/g0v