最近來了一些newguys,版本控制工具所有開始遷移到Git上來.原來都是老CVS或SVN的用戶. 因此打算把內部Wiki上比較兩篇粗糙Git的入門文章操做重寫一遍.在本篇中全面解析git概念和基礎使用方法.php
在寫的這篇文章時.在思考.應該如何快速切入理解Git的基本使用?相對Linux操做系統下分佈式版本控制工具.不少操做中都直接採用命令的方式來作.可更多Windows 開發人員習慣的是直觀的用戶操做界面.複雜的指令是Git在Linux自己具備的特色.而Windows 上UI不足也可使用工具加以彌補.圖形化工具(不管是 git extentions ,仍是TortoiseGit),都只不過是命令行的封裝。就功能而言,命令行所有能夠作到;但命令行能作的,他們不必定能夠作到。命令行更加原生、本色,跨越平臺之間侷限.html
so。本篇就以git 命令行操做方式逐步切入.至於一些圖形化工具會在下篇講到.前端
Git—The Stupid Content Tracker-俗稱傻瓜內容跟蹤器.Linus Benedict Torvalds-Linus之父在官方的Wiki中自嘲的取了這個名字.官方給出解釋以下:git
I'm an egotistical bastard, and I name all my projects after myself. First Linux, now git. |
Git最初是用於Linux內核開發的一個版本控制工具.從2002年起,Linux 內核一直使用BitKeeper來進行版本管理,可是在2005年BitKeeper和Linux 內核開源社區的合做關係結束,BitKeeper不再能無償使用了,這迫使Linus決定開發一個開源界自已的版本控制系統.與經常使用的版本控制CVS、Subversion等均不一樣.它採用分佈式的版本庫控制方式.相對於CVS或SVN. Git並不須要服務器端軟件的支持.Git的速度很快.它的本地操做速度和本地文件系統在一個級別,遠程倉庫的操做速度和SFTP文件傳輸在一個級別.至於如何實現的能夠看看Git內部實現機制.Git is the next Unix.這對於諸如 Linux kernel 這樣的大項目來講天然很重要。 Git 最爲出色的是它的合併跟蹤[merge tracing]能力.算法
Git最初的開發動力來自於BitKeeper和Monotone[2][3]。 Git最初只是做爲一個能夠被其餘前端好比Cogito 或 StGIT[4]包裝的後端而開發的。不過,後來Git內核已經成熟到能夠獨立地用做版本控制[5]。不少有名的軟件都使用Git來進行版本控制[6],其中有Linux內核、X.Org服務器和OLPC內核開發.數據庫
其實若是你是一個原來使用過CVS到SVN.或是也經歷從VSS遷移到TFS.你會發現版本控制管理模式從集中向分散演變.這也是由於如今的不少開發團隊變得愈來愈分散,原來微軟的Visual SourceSafe和Team Foundation Server這樣的集中式源代碼控制系統很難保持其吸引力.而Git做爲分佈式版本控制工具.逐漸在.NET 社區開始普遍使用.windows
瞭解Git一些基礎概念.以下篇幅來了解Git在實際項目中使用.在使用Git以前須要安裝對應Git工具.相對於Windows 平臺.可選安裝軟件有兩個:後端
Windows 安裝工具:安全 Windows平臺有兩個模擬*nix like運行環境的工具:cygwin,msys;Git在cygwin,msys下都有相應的移植版本.工具下載:bash TortoiseGit-[http://code.google.com/p/tortoisegit/downloads/list] Msysgit-[http://code.google.com/p/msysgit/downloads/list] 注:前者是與Windows 資源管理器整合的Git管理工具.後者是Git的功能軟件.我的以爲msys平臺下的msysGit最好用.推薦使用. |
本篇Git操做演示均採用MsysGit工具.安裝過程沒什麼可提的.在設置Git Setup時:
因爲windows平臺的換行符(CRLF)和Linux(*nix)平臺的換行符(LF)不一樣,那麼在windows下開發最好選「Checkout as-is, commit as-is」這個選項,這樣,Git就不會修改你代碼的換行符風格。
安裝完成後須要配置Git.在Linux下,能夠在命令行裏直接使用git config進行配置, 而在windows下則要先打開「Git Bash」,進入msysGit命令行界面,再用git config命令進行相應的配置操做.打開Git Bash.首先須要配置的UserName用戶名和Email.這回在每次Git操做日誌出現:
Git的配置信息分爲全局和項目兩種,上面命令中帶了「--global"參數,這就意味是在進行全局配置,它會影響本機上的每一個一個Git項目.爲了演示目的這裏首先創建一個用來測試操做的倉庫,首先在默認路徑下建立一個倉庫目錄.並在該目錄下建立一個倉庫:
mkDir建立一個測試倉庫目錄demogitdir,Cd 則是進入該目錄. git init 指令在當前目錄下建立一個測試操做的倉庫.有了可操做的倉庫.能夠添加一個任意內容的文件到倉庫並提交:
echo 則是把」hello git tool」內容寫入到sayhello.txt文件中. git add則是把該文件添加暫存區. 經過git commit指令則提交到默認的當前的倉庫中.能夠經過Git Log查看當前的提交記錄.也能夠在記錄中看到Git設置的用戶名和Email.:
在log能看到Commit 後根據一段「8223db3b064a9826375041c8fea020cb2e3b17d1」 SHA1串.Git經過對提交內容進行 SHA1 Hash運算,獲得它們的SHA1串值,做爲每一個提交的惟一標識。根據通常的密碼學原理來講,若是兩個提交的內容不相同,那麼它們的名字就不會相同;反之,若是它們的名字相同,就意味着它們的內容也相同.如今修改一下剛建立的文件內容 並提交到倉庫中,在來查看該文件與第一個保存版本之間存在的不一樣:
在原來基礎上添加字符串chenkai modify.這時能夠提交併查看當前git 狀態和日誌.有具體的庫.在回過頭看看GitConfig具體的配置.在Git bash中能夠經過cat /Head指令獲取當前庫GitConfig中配置 好比獲取剛纔設置用戶名和Email:
不少剛操做對git config配置不熟悉.能夠直接找到對應根目錄下GitConfig文件直接修改也能夠達到一樣的效果.固然也能夠經過git config –list獲取所有配置信息.
經過如上Git 一些指令操做是即便你不瞭解Git原理前提下 是否有了一個感性的認識.以下來挖掘Git設計原則和工做原理.
其實要理解Git這個版本控制工具由來過程.以及演變到今天具備分佈式特色.從版本控制最原始角度來分析.它突顯特色最容易理解的角度.開發人員最容易在使用工具每每注重學會它如何去使用 而忽略這些創建功能背後所解決問題.若是咱們可以從Git自己設計原則上看到解決問題.就天然會理解Git版本工具優點特色在哪裏.纔不會在使用過程純粹爲了使用Git而學習.一樣要在使用過程當中理解其演變過程.知其因此然.用起來才能遊刃有餘.
什麼是版本控制?
版本控制是一種記錄若干文件內容變化,以便未來查閱特定版本修訂狀況的系統 |
嚴格意義來講版本控制文件能夠是任何文本文件.而咱們突出是對源代碼文本文件版本控制管理.
在最原始版本控制中.習慣用複製整個項目目錄的方式來保存不一樣的版本,或許還會更名加上備份時間以示區別.這樣的方式很簡單.但存在問題也很多.容易混淆工做目錄.版本之間沒有交互實現版本指教差別跟蹤等.未解決這個問題在最開始設計多種本地版本控制系統,大多都是採用某種簡單的數據庫來記錄文件的歷次更新差別,具體構成:
最流行的一種叫作 rcs,現今許多計算機系統上都還看獲得它的蹤跡。甚至在流行的 Mac OS X 系統上安裝了開發者工具包以後,也可使用 rcs 命令。它的工做原理基本上就是保存並管理文件補丁(patch)。文件補丁是一種特定格式的文本文件,記錄着對應文件修訂先後的內容變化。因此,根據每次修訂後的補丁,rcs 能夠經過不斷打補丁,計算出各個版本的文件內容。這個特色甚至影響後來的CVS和SVN設計.如今依然可以在SVN中看到,版本之間須要做出補丁包.
雖然解決了可以經過數據控制版本之間變化.但在實際操做又要面對新問題-如何讓在不一樣系統上的開發者協同工做?因而,集中化的版本控制系統( Centralized Version Control Systems,簡稱 CVCS )應運而生。這類系統,諸如 CVS,Subversion 以及 Perforce 等,都有一個單一的集中管理的服務器,保存全部文件的修訂版本,而協同工做的人們都經過客戶端連到這臺服務器,取出最新的文件或者提交更新。多年以來,這已成爲版本控制系統的標準作法,結構成圖:
這種作法的好處是:
相較於老式的本地 VCS 來講。如今,每一個人均可以必定程度上看到項目中的其餘人正在作些什麼。而管理員也能夠輕鬆掌控每一個開發者的權限,而且管理一個 CVCS 要遠比在各個客戶端上維護本地數據庫輕鬆容易得多 |
壞處以及遺留難以處理的問題是:
最顯而易見的缺點是中央服務器的單點故障。如果宕機一小時,那麼在這一小時內,誰都沒法提交更新,也就沒法協同工做。若是中央服務器的磁盤發生故障,而且沒作過備份或者備份得不夠及時的話,還會有丟失數據的風險。最壞的狀況是完全丟失整個項目的全部歷史更改記錄,被客戶端提取出來的某些快照數據除外,但這樣的話依然是個問題,你不能保證全部的數據都已經有人提取出來。本地版本控制系統也存在相似問題,只要整個項目的歷史記錄被保存在單一位置,就有丟失全部歷史更新信息的風險. |
well.新的需求出現老是不斷推進新的工具推出.緊接着.爲了解決集中化版本控制中存在種種問題.同時繼承原有的特色.分佈式版本控制系統( Distributed Version Control System,簡稱 DVCS )面世了。在這類系統中,諸如 Git,Mercurial,Bazaar 還有 Darcs 等,客戶端並不僅提取最新版本的文件快照,而是把原始的代碼倉庫完整地鏡像下來。這麼一來,任何一處協同工做用的服務器發生故障,過後均可以用任何一個鏡像出來的本地倉庫恢復。由於每一次的提取操做,實際上都是一次對代碼倉庫的完整備份,結構分析截圖:
well 有了Git這種分佈式工具.許多這類系統均可以指定和若干不一樣的遠端代碼倉庫進行交互。籍此,你就能夠在同一個項目中,分別和不一樣工做小組的人相互協做。你能夠根據須要設定不一樣的協做流程,比方說層次模型式的工做流,這在之前的集中式系統中是沒法實現的.
從05開始其Linux開源社區爲了避免重蹈覆轍.決定基於Linux操做系統開發一個新版版本控制工具.就是咱們今天見到的Git.當時開發團隊對Git工具 設計目標做了以下的設想:
Git 設計目標:
|
從05年至今.通過Linux開源社區推進.Git逐漸成熟.同時對演變對其餘Windows MAC平臺支持.
其實不少人從CVS或是SVN過渡而來的用戶,在使用指令操做方式依然可以粗類旁通.其實在原理層次2者之間並沒有可比性.反而從SVN過來而來用戶在理解老是存在一個對比的概念.Git 和其餘版本控制系統的主要差異在於,Git 只關心文件數據的總體是否發生變化,而大多數其餘系統則只關心文件內容的具體差別。這類系統(CVS,Subversion,Perforce,Bazaar 等等)每次記錄有哪些文件做了更新,以及都更新了哪些行的什麼內容,構圖吐下:
而Git在對基本文件操做徹底不一樣.Git 並不保存這些先後變化的差別數據。實際上,Git 更像是把變化的文件做快照後,記錄在一個微型的文件系統中。每次提交更新時,它會縱覽一遍全部文件的指紋信息並對文件做一快照,而後保存一個指向此次快照的索引。爲提升性能,若文件沒有變化,Git 不會再次保存,而只對上次保存的快照做一鏈接。Git 的工做方式以下:
這是 Git 同其餘系統的重要區別。它徹底顛覆了傳統版本控制的套路,並對各個環節的實現方式做了新的設計。Git 更像是個小型的文件系統,但它同時還提供了許多以此爲基礎的超強工具,而不僅是一個簡單的 VCS.
因Git在底層的設計.自己具備的操做特色也不一樣於其餘版本控制工具.具體表現以下幾點.
A:全部操做幾乎在本地運行.
Git 中的絕大多數操做都只須要訪問本地文件和資源,不用連網。但若是用 CVCS 的話,差很少全部操做都須要鏈接網絡。由於 Git 在本地磁盤上就保存着全部有關當前項目的歷史更新,因此這也就不難解釋Git的處理起來速度飛快特色.
Git這點能讓開發人員.在大的項目結構下.隨時隨地在不用鏈接服務器的狀況下查看版本之間差別.而不是採用SVN的方式經過請求服務器端運算獲取差別.引文每次版本更新都可以拿到本地存在最新代碼的快照.之後全部的操做均可以基於本地的Code進行.而無需請求服務器端.
這樣一來可讓開發人員隨意修改本地的Code.在存在網絡的狀況時經過Push操做吧更改上傳遠程的鏡像上.換做其餘版本控制系統,這麼作幾乎不可能,抑或很是麻煩,例如:Subversion 或 CVS,雖然能夠編輯文件,但沒法提交更新,由於數據庫在網絡上.
B:時刻保持數據完整性
在保存到 Git 以前,全部數據都要進行內容的校驗和(checksum)計算,並將此結果做爲數據的惟一標識和索引。換句話說,不可能在你修改了文件或目錄以後,Git 一無所知。這項特性做爲 Git 的設計哲學,建在總體架構的最底層。因此若是文件在傳輸時變得不完整,或者磁盤損壞致使文件數據缺失,Git 都能當即察覺.
Git 使用 SHA-1 算法計算數據的校驗和,經過對文件的內容或目錄的結構計算出一個 SHA-1 哈希值,做爲指紋字符串。該字串由 40 個十六進制字符(0-9 及 a-f)組成,看起來就像是:
1: 24b9da6552252987aa493b52f8696cd6d3b00373 |
Git 的工做徹底依賴於這類指紋字串,因此你會常常看到這樣的哈希值。實際上,全部保存在 Git 數據庫中的東西都是用此哈希值來做索引的,而不是靠文件名
C:多數操做僅僅添加數據
經常使用的 Git 操做大多僅僅是把數據添加到數據庫。由於任何一種不可逆的操做,好比刪除數據,要回退或重現都會很是困難。在別的 VCS 中,若還未提交更新,就有可能丟失或者混淆一些修改的內容,但在 Git 裏,一旦提交快照以後就徹底不用擔憂丟失數據,特別是在養成了按期推送至其餘鏡像倉庫的習慣的話。
這種高可靠性令咱們的開發工做安心很多,儘管去作各類試驗性的嘗試好了,再怎樣也不會弄丟數據.
D:Git文件中三種狀態
接下來要講的概念很是重要。對於任何一個文件,在 Git 內都只有三種狀態:已提交(committed),已修改(modified)和已暫存(staged)。已提交表示該文件已經被安全地保存在本地數據庫中了;已修改表示修改了某個文件,但尚未提交保存;已暫存表示把已修改的文件放在下次提交時要保存的清單中。
由此咱們看到 Git 管理項目時,文件流轉的三個工做區域:Git 的工做目錄,暫存區域,以及本地數據目錄:
每一個項目都有一個 git 目錄,它是 Git 用來保存元數據和對象數據庫的地方。該目錄很是重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄裏面的數據。
從項目中取出某個版本的全部文件和目錄,用以開始後續工做的叫作工做目錄。這些文件實際上都是從 git 目錄中的壓縮對象數據庫中提取出來的,接下來就能夠在工做目錄中對這些文件進行編輯。
所謂的暫存區域只不過是個簡單的文件,通常都放在 git 目錄中。有時候人們會把這個文件叫作索引文件,不過標準說法仍是叫暫存區域。
基本的 Git 工做流程以下所示:
因此,咱們能夠從文件所處的位置來判斷狀態:若是是 git 目錄中保存着的特定版本文件,就屬於已提交狀態;若是做了修改並已放入暫存區域,就屬於已暫存狀態;若是自上次取出後,做了修改但尚未放到暫存區域,就是已修改狀態.
其實如上三種裝當你在每次從建立文件到提交文件整個過程.一旦執行一條命令均可以經過Git Status來查看當前文件的狀態.就可以很清晰撲捉到一個文件從建立到提交過程在Git版本狀態的變化過程.我就不在此演示了.
着重寫本篇主要目的是爲了在使用Git解惑.清楚瞭解Git以前整個版本管理工具演化過程.以及相對其餘版本工具Git自身具備的特色.和工做原理.重要性不言而喻. 就像不少開發人員強迫本身學習GOF 23種模式同樣.大多的人只是關注如何快速熟練的使用GOF每種模式.力求使用可以精通.咱們願景是可以遇到問題時可以採用前人經驗去解決.惋惜是現實中使用效果老是與咱們設想效果差很遠.緣由很簡單.不少開發人員學習玩GoF 23模式後在碰到問題每每反而更迷茫了.由於他不知道採用哪一種模式來解決問題最簡單.或是換句話咱們只是知道 瞭解 並熟練掌握GOF模式使用而忽略GOF模式自己的價值.具體解決什麼樣問題. 適用在什麼問題場景最合適?這是否對學習對強迫本身學習GOF的同窗是一種悲哀呢/.
學習GIT也是如此.不要陷入細節的海洋沒法自拔.在處理問題上.多一點全局的觀念.每每可以帶來更多思考.至少咱們能肯定作事方向和路線是對的.有些開發人員每每從事行業多年.卻對不少專業技術都是略知.說白在創建自身知識系統完整性缺少. 這也是產生所謂行業多了不少」IT民工」角色 而少了真正的創新緣由之一.
這種現象是否值得咱們去反思這種問題的現狀呢?