歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 版本控制發展及Git和Github的使用

版本控制發展及Git和Github的使用

日期:2017/2/28 14:36:12   编辑:Linux教程

源代碼管理系統(SCM)與版本控制

版本控制是一種記錄若干文件內容變化,以便將來查閱特定版本修訂情況的系統。

本地版本控制系統

許多人習慣用復制整個項目目錄的方式來保存不同的版本,或許還會改名加上備份時間進行區別。這麼做的唯一好處就是簡單,壞處也不少:有時候會混淆所在的工作目錄,一旦弄錯了文件數據就沒辦法撤銷恢復。為了解決這個問題,人們很久以前就開發了許多本地版本控制系統,大多是采用某種簡單的數據庫來記錄文件的歷次更新差異。

集中化的版本控制系統

接下來人們又遇到一個問題,如何讓在不同系統上的開發者協同工作?於是,集中化的版本控制系統(Centralized Version Control Systems)應運而生。這類系統,諸如CVS、Subversion等,都有一個單一的集中管理服務器,保存所有文件的修訂版本,而協同工作的人們都通過客戶端連到這台服務器,取出最新的文件或者提交更新。多年以來,這已成為版本控制系統的標准做法。

這麼做帶來了很多好處,特別是相對於本地版本控制系統來說。現在,每個人都可以在一定程度上看到項目中的其他人正在做什麼,管理員也可以輕松掌握每個開發者的權限,看到每個人每天的提交記錄。這樣做最大的缺點就是中央服務器的單點故障。如果宕機一小時,那麼在一小時內所有人都無法提交更新,也就無法協同工作。要是中央服務器的磁盤發生故障,碰巧沒有備份或者備份不及時,就會有丟失數據的風險。最壞的情況是徹底丟失整個項目的所有歷史更改記錄,而被客戶端提取出來的某些快照數據除外,但是不能夠保證所有的數據都已經有人事先完整的提取出來。

本地版本控制系統也存在類似問題,只要整個項目的歷史記錄被保存在單一位置,就有丟失所有歷史更新記錄的風險。

分布式版本控制系統

分布式版本管理系統就是為了解決這個單點問題,在這類系統中,像Git、Mercurial、Bazaar以及Darcs等,客戶端並不只是提取最新的文件快照,而是把原始的代碼倉庫完整地鏡像下來。這麼一來,任何一處協同工作用的服務器發生故障,事後都可以用任何一個鏡像出來的本地倉庫恢復。因為每一次的提取操作,實際上都是一次對代碼倉庫的完整備份。更進一步,這類系統都可以指定和若干不同的遠端代碼倉庫進行交互。因此,你就可以在同一個項目中,分別和不同工作小組的人相互協作。你可以根據需要設定不同的協作流程。

Git與SVN等常規版本控制軟件的區別

Git 是一個快速、可擴展的分布式版本控制系統,它具有極為豐富的命令集,對內部系統提供了高級操作和完全訪問。

Git誕生於2005年,起因是因為Linux內核開源項目使用的版本控制系統BitKeeper被收回,這就迫使Linux開源社區(特別是Linux的締造者Linus Torvalds)不得不吸取教訓,只有開發一套屬於自己的版本控制系統才不至於重蹈覆轍。他們對新系統制定的目標如下:

速度快,設計簡單,對非線性開發模式的強力支持(允許上千個並行開發的分支),完全分布式,有能力高效管理類似Linux內核一樣的超大規模項目(速度和數量)。

經過不斷的完善,Git始終保持著如下的特點:

1、直接記錄快照,而非差異比較。

Git和其他版本控制系統的主要差別在於,Git只關心文件數據的整體是否發生變化,而大多數其他系統則只關心文件內容的具體差異。這類系統(CVS、Subversion等)每次記錄都有哪些文件做了更新,以及更新了哪些行的什麼內容,如下圖:

Git 並不保存這些前後變化的差異數據。實際上,Git 更像是把變化的文件作快照後,記錄在一個微型的文件系統中。每次提交更新時,它會縱覽一遍所有文件的指紋信息並對文件作一快照,然後保存一個指向這次快照 的索引。為提高性能,若文件沒有變化,Git 不會再次保存,而只對上次保存的快照作一鏈接。Git 的工作方式就像下圖所示:

這是 Git 同其他系統的重要區別。它完全顛覆了傳統版本控制的套路,並對各個環節的實現方式作了新的設計。Git 更像是個小型的文件系統,但它同時還提供了許多以此為基礎的超強工具,而不只是一個簡單的 VCS。

2、支持離線工作(近乎所有操作都是本地執行),本地提交可以稍後提交到服務器上;

3、時刻保持數據完整性;

4、多數操作僅添加數據;

文件的三種狀態

對於任何一個文件,在 Git 內都只有三種狀態:已提交(committed),已修改(modified)和已暫存(staged)。已提交表示該文件已經被安全地保存在本地數據庫 中了;已修改表示修改了某個文件,但還沒有提交保存;已暫存表示把已修改的文件放在下次提交時要保存的清單中。由此我們看到 Git 管理項目時,文件流轉的三個工作區域:Git 的工作目錄,暫存區域,以及本地倉庫。

每個項目都有一個 Git 目錄(譯注:如果 git clone 出來的話,就是其中 .git 的目錄;如果git clone --bare 的話,新建的目錄本身就是 Git 目錄。),它是 Git 用來保存元數據和對象數據庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄裡面的數據。

從項目中取出某個版本的所有文件和目錄,用以開始後續工作的叫做工作目錄。這些文件實際上都是從 Git 目錄中的壓縮對象數據庫中提取出來的,接下來就可以在工作目錄中對這些文件進行編輯。

所謂的暫存區域只不過是個簡單的文件,一般都放在 Git 目錄中。有時候人們會把這個文件叫做索引文件,不過標准說法還是叫暫存區域。

基本的 Git 工作流程如下:

1. 在工作目錄中修改某些文件。 2. 對修改後的文件進行快照,然後保存到暫存區域。 3. 提交更新,將保存在暫存區域的文件快照永久轉儲到 Git 目錄中。

所以,我們可以從文件所處的位置來判斷狀態:如果是 Git 目錄中保存著的特定版本文件,就屬於已提交狀態;如果作了修改並已放入暫存區域,就屬於已暫存狀態;如果自上次取出後,作了修改但還沒有放到暫存區域,就 是已修改狀態。

Git的使用

Git 支持許多數據傳輸協議,包括本地傳輸、 git://協議、http(s):// 或者 SSH傳輸協議 user@server:/path.git,除了HTTP協議之外,其他所有協議都要求在服務器端安裝並運行Git。

一、使用本地倉庫

對於本地的項目管理,一些具體的操作方法可以參考這篇文章:Git基礎 裡面詳細的講解了Git每個操作的使用方法和效果。因為本文主要目的在於演示如何利用GitHub參與開源項目,對於使用細節就不再花時間描述了,不過我認為仔細的看看這些使用方法對於提高工作效率非常有幫助。

使用本地倉庫,用戶只是自己一個人,所以不存在協同工作的問題,不管怎麼玩兒,一般不會出問題。使用遠程倉庫,情況就會復雜、有趣的多。

二、使用遠程倉庫

要參與任何一個 Git 項目的協作,必須要了解該如何管理遠程倉庫。遠程倉庫是指托管在網絡上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協作開發某 個項目時,需要管理這些遠程倉庫,以便推送或拉取數據,分享各自的工作進展。管理遠程倉庫的工作,包括添加遠程庫,移除廢棄的遠程庫,管理各式遠程庫分 支,定義是否跟蹤這些分支,等等。

以現在比較流行的GitHub為例,如果我在上面創建了一個項目,實際上相當於使用 git init 新建了一個服務器端的倉庫。如果我想在本地進行開發,那麼我就需要 git clone 到我的本地。做了一些開發之後,我可以 git push 將本地的修改推送到服務器倉庫中。隨著項目發展,有其他人想要參與到這個項目中來,他可以在GitHub上Fork我這個項目,這樣他對這個項目才有寫權限,而且可以將他的工作保存到GitHub的服務器上。如果他希望將自己的工作提交給我,首先他需要在本地開發環境中添加我的遠程倉庫 git remote add。然後 git push remotename master 發起推送的請求,如果我接受了,他的工作就可以合並到主干中了。因為我們此時是並行開發,如果他想看我的工作,可以采用 git pull remotename 的方式將我所做的修改拉取到本地,非常的方便。

上面這段話,描述了我們在使用遠程倉庫以及與其他人協作過程中的大體流程,需要用到的一些遠程倉庫的操作如下:

1、查看當前配置的遠程倉庫

可以使用 git remote -v 來查看當前項目中都添加了哪些遠程倉庫

其中Origin一般是自己在服務器上的遠程倉庫,其他的為他人的遠程倉庫。

2、添加新的遠程倉庫

要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用,運行 git remote add [shortname] [url]

git remote add pb git://github.com/paulboone/ticgit.git

3、抓取遠程倉庫的信息

git fetch [remote-name]

此命令會到遠程倉庫中拉取所有你本地倉庫中還沒有的數據。運行完成後,你就可以在本地訪問該遠程倉庫中的所有分支,將其中某個分支合並到本地,或者只是取出某個分支,一探究竟。如果是克隆了一個倉庫,此命令會自動將遠程倉庫歸於 origin 名下。所以,git fetch origin 會抓取從你上次克隆以來別人上傳到此遠程倉庫中的所有更新(或是上次 fetch 以來別人提交的更新)。有一點很重要,需要記住,fetch 命令只是將遠端的數據拉到本地倉庫,並不自動合並到當前工作分支,只有當你確實准備好了,才能手工合並。

4、 從遠程倉庫抓取信息並合並

git pull [remote-name]

可以使用 git pull 命令自動抓取數據下來,然後將遠端分支自動合並到本地倉庫中當前分支。在日常工作中我們經���這麼用,既快且好。實際上,默認情況下git clone 命令本質上就是自動創建了本地的 master 分支用於跟蹤遠程倉庫中的 master 分支(假設遠程倉庫確實有 master 分支)。所以一般我們運行git pull,目的都是要從原始克隆的遠端倉庫中抓取數據後,合並到工作目錄中的當前分支。

5、推送數據到遠程倉庫

git push [remote-name] [branch-name]

項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的數據推送到遠程倉庫。實現這個任務的命令很簡單: git push [remote-name] [branch-name]。如果要把本地的 master 分支推送到origin 服務器上(再次說明下,克隆操作會自動使用默認的 master 和 origin 名字),可以運行下面的命令:

git push origin master

只有在所克隆的服務器上有寫權限,或者同一時刻沒有其他人在推數據,這條命令才會如期完成任務。如果在你推數據前,已經有其他人推送了若干更新,那 你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合並到自己的項目中,然後才可以再次推送。

6、查看遠程倉庫信息

git remote show [remote-name]

7、遠程倉庫的刪除和重命名

git remote rename [old name] [new name]

git remote rm [remote-name]

Git與GitHub

GitHub是一個利用Git提供免費的代碼托管服務的網站(類似的網站還有老牌的SourceForge),很多著名的項目都托管在上面。

要想在GitHub上參與開源項目,根據Git的使用方法,有兩種途徑可以實現。

第一種是項目的創建人將你添加到項目的合作貢獻者列表中,這樣你就可以直接向這個項目推送代碼。

第二種是Fork一份代碼到自己的空間下,這樣的一份代碼自己具有推送的權限。如果開發的進展很好,項目的創建者可以將Fork的這些項目添加為Remote倉庫,在他認為合適的時候將代碼fetch到自己的倉庫中進行合並,也可以由我們發起請求,請創始人將代碼合並。GitHub上提倡的就是使用這種方式進行開發合作。

下面以PHP-Daemon這個項目為例,演示一下如何參與到GitHub中托管的開源項目中。

0、安裝配置Git

1、首先注冊一個GitHub的帳號。

2、選擇一個自己喜歡的項目,進行Fork。

3、建立本地的資源池(Local Repo)。

可以使用下面的命令將項目復制到本地,復制的地址可以是SSH的也可以是HTTP形式的,具體的地址在項目頁面中可以看到。

git clone [email protected]:cocowool/PHP-Daemon.git

4、配置源項目地址。

項目克隆完成後,默認有一個名為“origin”的遠端指向了我在GitHub上的項目,而並非原始的項目。為了能夠及時獲取原始項目上的更新,我們需要再增加一個遠端,命名為“upstream”。

git remote add upstream https://github.com/shaneharter/PHP-Daemon.git

git fetch upstream

5、接下來可以做的事情。

推送提交 Push Commits

一些小Tips

Mac OS X Lion 中自帶了Git的命令行和圖形化界面,雖然他的圖形化界面簡陋到吐血。

Mac下還有一個gitk,提供了圖形化工具來進行歷史的查閱。它是用 Tcl/Tk 寫成的,基本上相當於 git log 命令的可視化版本,凡是git log 可以用的選項也都能用在 gitk 上。

在項目目錄下輸入 /Developer/usr/bin/gitk 就可以看到。

推薦閱讀

如何在 GitHub 建立組織 http://www.linuxidc.com/Linux/2013-08/88197.htm

GitHub Linux下使用方法 http://www.linuxidc.com/Linux/2013-06/86417.htm

Windows下Eclipse搭建GitHub開發環境圖文教程 http://www.linuxidc.com/Linux/2013-06/85372.htm

R語言 3.0.1 源碼已經提交到 GitHub http://www.linuxidc.com/Linux/2013-05/84425.htm

從GitHub將Maven項目導入Eclipse4.2 http://www.linuxidc.com/Linux/2013-04/83082.htm

Copyright © Linux教程網 All Rights Reserved