Git介紹及其使用

Git是一個分佈式的版本控制工具,本篇文章從介紹Git開始,重點在於介紹Git的基本命令和使用技巧,讓你嘗試使用Git的同時,體驗到原來一個版本控制工具可以對開發產生如此之多的影響,文章分爲兩部分,第一部分介紹Git的一些常用命令,其中穿插介紹Git的基本概念和原理,第二篇重點介紹Git的使用技巧,最後會在Git Hub上創建一個開源項目開啓你的Git實戰之旅

  Git是什麼

  Git在Wikipedia上的定義:它是一個免費的、分佈式的版本控制工具,或是一個強調了速度快的源代碼管理工具。Git最初被Linus Torvalds開發出來用於管理Linux內核的開發。每一個Git的工作目錄都是一個完全獨立的代碼庫,並擁有完整的歷史記錄和版本追蹤能力,不依賴於網絡和中心服務器。

  Git的出現減輕了許多開發者和開源項目對於管理分支代碼的壓力,由於對分支的良好控制,更鼓勵開發者對自己感興趣的項目做出貢獻。其實許多開源項目包括Linux kernel, Samba, X.org Server, Ruby on Rails,都已經過渡到使用Git作爲自己的版本控制工具。對於我們這些喜歡寫代碼的開發者嘛,有兩點最大的好處,我們可以在任何地點(在上班的地鐵上)提交自己的代碼和查看代碼版本;我們可以開許許多多個分支來實踐我們的想法,而合併這些分支的開銷幾乎可以忽略不計。

  Git 1+1

  現在進入本篇文章真正的主題,介紹一下Git的基本命令和操作,會從Git的版本庫的初始化,基本操作和獨有的常用命令三部分着手,讓大家能夠開始使用Git。

  Git通常有兩種方式來進行初始化:

  git clone: 這是較爲簡單的一種初始化方式,當你已經有一個遠程的Git版本庫,只需要在本地克隆一份,例如'git clone git://github.com/someone/some_project.git some_project'命令就是將'git://github.com/someone/some_project.git'這個URL地址的遠程版 本庫完全克隆到本地some_project目錄下面

  git init和git remote:這種方式稍微複雜一些,當你本地創建了一個工作目錄,你可以進入這個目錄,使用'git init'命令進行初始化,Git以後就會對該目錄下的文件進行版本控制,這時候如果你需要將它放到遠程服務器上,可以在遠程服務器上創建一個目錄,並把 可訪問的URL記錄下來,此時你就可以利用'git remote add'命令來增加一個遠程服務器端,例如'git remote add origin git://github.com/someone/another_project.git'這條命令就會增加URL地址爲'git: //github.com/someone/another_project.git',名稱爲origin的遠程服務器,以後提交代碼的時候只需要使用 origin別名即可

  現在我們有了本地和遠程的版本庫,讓我們來試着用用Git的基本命令吧:

  git pull:從其他的版本庫(既可以是遠程的也可以是本地的)將代碼更新到本地,例如:'git pull origin master'就是將origin這個版本庫的代碼更新到本地的master主枝,該功能類似於SVN的update

  git add:是將當前更改或者新增的文件加入到Git的索引中,加入到Git的索引中就表示記入了版本歷史中,這也是提交之前所需要執行的一步,例如'git add app/model/user.rb'就會增加app/model/user.rb文件到Git的索引中

  git rm:從當前的工作空間中和索引中刪除文件,例如'git rm app/model/user.rb'

  git commit:提交當前工作空間的修改內容,類似於SVN的commit命令,例如'git commit -m "story #3, add user model"',提交的時候必須用-m來輸入一條提交信息

  git push:將本地commit的代碼更新到遠程版本庫中,例如'git push origin'就會將本地的代碼更新到名爲orgin的遠程版本庫中

  git log:查看歷史日誌

  git revert:還原一個版本的修改,必須提供一個具體的Git版本號,例如'git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20',Git的版本號都是生成的一個哈希值

  上面的命令幾乎都是每個版本控制工具所公有的,下面就開始嘗試一下Git獨有的一些命令:

  git branch:對分支的增、刪、查等操作,例如'git branch new_branch'會從當前的工作版本創建一個叫做new_branch的新分支,'git branch -D new_branch'就會強制刪除叫做new_branch的分支,'git branch'就會列出本地所有的分支

  git checkout:Git的checkout有兩個作用,其一是在不同的branch之間進行切換,例如'git checkout new_branch'就會切換到new_branch的分支上去;另一個功能是還原代碼的作用,例如'git checkout app/model/user.rb'就會將user.rb文件從上一個已提交的版本中更新回來,未提交的內容全部會回滾

  git rebase:用下面兩幅圖解釋會比較清楚一些,rebase命令執行後,實際上是將分支點從C移到了G,這樣分支也就具有了從C到G的功能

  

Git使用基礎篇(圖一)

 

  git reset:將當前的工作目錄完全回滾到指定的版本號,假設如下圖,我們有A-G五次提交的版本,其中C的版本號是 bbaf6fb5060b4875b18ff9ff637ce118256d6f20,我們執行了'git reset bbaf6fb5060b4875b18ff9ff637ce118256d6f20'那麼結果就只剩下了A-C三個提交的版本

  

Git使用基礎篇(圖二)

 

  git stash:將當前未提交的工作存入Git工作棧中,時機成熟的時候再應用回來,這裏暫時提一下這個命令的用法,後面在技巧篇會重點講解

  git config:利用這個命令可以新增、更改Git的各種設置,例如'git config branch.master.remote origin'就將master的遠程版本庫設置爲別名叫做origin版本庫,後面在技巧篇會利用這個命令個性化設置你的Git,爲你打造獨一無二的 Git

  git tag:可以將某個具體的版本打上一個標籤,這樣你就不需要記憶複雜的版本號哈希值了,例如你可以使用'git tag revert_version bbaf6fb5060b4875b18ff9ff637ce118256d6f20'來標記這個被你還原的版本,那麼以後你想查看該版本時,就可以使用 revert_version標籤名,而不是哈希值了

  Git之所以能夠提供方便的本地分支等特性,是與它的文件存儲機制有關的。Git存儲版本控制信息時使用它自己定義的一套文件系統存儲機制,在代碼根目錄下有一個.git文件夾,會有如下這樣的目錄結構:

  

Git使用基礎篇(圖三)

 

  有幾個比較重要的文件和目錄需要解釋一下:HEAD文件存放根節點的信息,其實目錄結構就表示一個樹型結構,Git採用這種樹形結構來存儲版本信息,那麼HEAD就表示根;refs目錄存儲了你在當前版本控制目錄下的各種不同引用(引用指的是你本地和遠程所用到的各個樹分支的信息),它有heads、remotes、stash、tags四個子目錄,分別存儲對不同的根、遠程版本庫、Git棧和標籤的四種引用,你可以通過命令'git show-ref'更清晰地查看引用信息;logs目錄根據不同的引用存儲了日誌信息。因此,Git只需要代碼根目錄下的這一個.git目錄就可以記錄完整的版本控制信息,而不是像SVN那樣根目錄和子目錄下都有.svn目錄。那麼下面就來看一下Git與SVN的區別吧

  Git與SVN的不同

  SVN(Subversion)是當前使用最多的版本控制工具。與它相比較,Git最大的優勢在於兩點:易於本地增加分支和分佈式的特性。

  下面兩幅圖可以形象的展示Git與SVN的不同之處

  

Git使用基礎篇(圖四)

 

  

Git使用基礎篇(圖五)

 

  對於易於本地增加分支,圖中Git本地和服務器端結構都很靈活,所有版本都存儲在一個目錄中,你只需要進行分支的切換即可達到在某個分支工作的效果。而SVN則完全不同,如果你需要在本地試驗一些自己的代碼,只能本地維護多個不同的拷貝,每個拷貝對應一個SVN服務器地址。舉一個實際的例子,以前我所在的小組使用SVN作爲版本控制工具,當我正在試圖增強一個模塊,工作做到一半,由於會改變原模塊的行爲導致代碼服務器上許多測試的失敗,所以並沒有提交代碼。這時候上級對我說,現在有一個很緊急的Bug需要處理, 必須在兩個小時內完成。我只好將本地的所有修改diff,並輸出成爲一個patch文件,然後回滾有關當前任務的所有代碼,再開始修改Bug的任務,等到修改好後,在將patch應用回來。前前後後要完成多個繁瑣的步驟,這還不計中間代碼發生衝突所要進行的工作量。可是如果使用Git, 我們只需要開一個分支或者轉回到主分支上,就可以隨時開始Bug修改的任務,完成之後,只要切換到原來的分支就可以優雅的繼續以前的任務。只要你願意,每一個新的任務都可以開一個分支,完成後,再將它合併到主分支上,輕鬆而優雅。

  分佈式對於Git而言,你可以本地提交代碼,所以在上面的圖中,Git有利於將一個大任務分解,進行本地的多次提交,而SVN只能在本地進行大量的一次性更改,導致將來合併到主幹上造成巨大的風險。Git的代碼日誌是在本地的,可以隨時查看。SVN的日誌在服務器上的,每次查看日誌需要先從服務器上下載下來。我工作的小組,代碼服務器在美國,每次查看小組幾年前所做的工作時,日誌下載就需要十分鐘,這不能不說是一個痛苦。後來我們遷移到Git上,利用Git日誌在本地的特性,我用Ruby編寫了一個Rake腳本,可以查看某個具體任務的所有代碼歷史,每次只需要幾秒鐘,大大方便我的工作。當然分佈式並不是說用了Git就不需要一個代碼中心服務器,如果你工作在一個團隊裏,還是需要一個服務器來保存所有的代碼的。

  總結

  本篇介紹了Git的基本概念、一些常用命令和原理,大家可以嘗試動手體會一下,下一篇會重點介紹Git命令的使用技巧,Git附帶的工具,最後會在Git Hub上創建一個開源項目,敬請期待

上一篇介紹了Git的基本概念和一些基本命令,本篇的重點在如下三個部分:個性化定製你的Git,更酷更巧妙的使用Git,以及如何在Git Hub上開啓你自己的開源項目。在所有技巧中,最重要的技巧是學會查看Git的幫助,因爲Git是一個相對複雜的版本控制工具,如果你熟悉它的命令,那麼給你帶來的價值是不言而喻的,所以要學會掌握那根金手指─查看Git的幫助,在任何Git命令後加上'--help'就會顯示該命令的幫助文檔,例如 'git log --help'你就可以看到命令'git log'的所有使用方法。接下來,從打扮Git開始吧。

  Git梳妝

  我們可以利用Git的config命令或者直接編輯~/.gitconfig文件(如果沒有的話創建它)來爲自己打造獨一無二的Git。我建議直接編輯用戶目錄下得.gitconfig文件,拿我本地的文件爲例,一一爲大家解說,完整的文件內容如下:

  [user]

  name = Phoenix

  email = [email protected]

  [alias]

  co = checkout

  ci = commit -a

  st = status

  br = branch

  oneline = log --pretty=oneline --since='2 days ago'

  onelog = log -p -1

  [color]

  status = auto

  branch = auto

  ui = auto

  該文件主要包含三個部分的內容:

  用戶基本信息:可以設置你的名字和email,這樣在你提交代碼的時候就會顯示出你的名字

  命令別名:這是.gitconfig文件中,我最喜歡的部分,它可以大大減少你敲擊鍵盤的次數(俗話說優秀的程序員都很懶麼)。在該文件中,我將co設置爲checkout的別名,那麼下次我只要用'git co new_branch'就可以切換到new_branch分支下了,簡潔而優雅;將ci設置爲commit -a的別名,-a選項表示我不需要將修改和刪除的文件通過'git add'命令來加入索引,這樣設置在使用'git ci -m"message"'這樣的命令時,相當於連續執行了'git add 被修改和刪除的文件'和'git commit -m"message"'兩條命令,再一次節省了我們寶貴的時間;最酷的是最後兩行,後面的章節會一一介紹。Git提供許多優雅、人性化的選項,我們如果再結合別名的設置,可以發揮你最大的想象力,真的讓你自己的Git活起來

  顏色:每次看diff時是不是挺痛苦的?那麼爲什麼不給我們的Git加上顏色呢?只需要加上那三行,就可以讓紅色和綠色的提示出現在你的控制檯中

  Git靈動

  現在來講講'git log','git stash','git formate-patch'三個命令的用法和技巧:

  git log:不同於SVN,Git將代碼的歷史記錄全部在本地克隆了一份,所以這就使得'git log'這樣的命令使用起來非常的迅速,也是我最常使用的Git命令之一。在使用'git log'的時候,你可以加入很多的後綴。'-p'表示查看修改的具體內容,例如'git log -p'它不但會打印出提交的時間、版本號、人員等,還會將具體的代碼修改部分打印出來;'-n'其中n表示一個數字,這表示打印出具體的幾個日誌,例如 'git -p -1'正如我的Git配置文件中設置的onelog別名的內容一樣,就表示打印出當前最新的一次日誌記錄及具體修改內容;'--since="時間/日期"','--until="時間/日期"'表示你希望查找某個日期段的日誌記錄,例如'git log --since="2 days ago" --until="1 hour ago"'就表示你希望查找兩天前到一小時前的日誌記錄,Git是足夠聰明的,它可以將類似於'2 days ago'和'1 hour ago'這種表示時間的英語轉化爲具體的時間數字;有的時候,你不希望翻很多頁纔可以看到所有的日誌,你只希望看到簡短的說明,那麼Git爲你提供打印格式的定製'git --pretty=格式種類',其中格式種類有full、short、oneline等,例如'git log pretty=oneline'就會將每條代碼歷史記錄放在一行裏,看起來簡單明瞭

  git stash:在第一篇中,我舉了一個使用branch解決緊急任務切換的問題,其實stash命令也可以很好的解決這樣的問題。當你不想提交當前完成了一半的代碼,但是卻不得不修改一個緊急Bug,那麼使用'git stash'就可以將你當前未提交到本地(和服務器)的代碼推入到Git的棧中,這時候你的工作區間和上一次提交的內容是完全一樣的,所以你可以放心的修 Bug,等到修完Bug,提交到服務器上後,再使用'git stash apply'將以前一半的工作應用回來。也許有的人會說,那我可不可以多次將未提交的代碼壓入到棧中?答案是可以的。當你多次使用'git stash'命令後,你的棧裏將充滿了未提交的代碼,這時候你會對將哪個版本應用回來有些困惑,'git stash list'命令可以將當前的Git棧信息打印出來,你只需要將找到對應的版本號,例如使用'git stash apply stash@{1}'就可以將你指定版本號爲stash@{1}的工作取出來,當你將所有的棧都應用回來的時候,可以使用'git stash clear'來將棧清空

  git format-patch:當你想給一個開源項目(例如Rails)提交一段代碼的時候,或者你想給小組成員展示一段你並不想提交的代碼,那麼你還是需要 patch的,Git的'format-patch'命令良好的支持了這個功能。我來基本描述一下使用這個命令的步驟和方法:第一,利用branch命令創建一個分支;第二,修改你的代碼;第三,在該分支上提交你的修改;第四,使用'git format-patch'命令來生成一個patch文件,例如:'git format-patch master --stdout > ~/Desktop/tmp.patch'就是將工作分支與master主幹的不同,存放在'~/Desktop'文件夾下,生成一個叫做 tmp.patch的文件(另一種簡單的版本是利用diff命令,例如'git diff ..master > ~/Desktop/tmp.patch'),這樣就生成了patch文件。那麼別人就可以使用'git apply'命令來應用patch,例如'git apply ~/Desktop/tmp.patch'就是將patch打在當前的工作分支上

  Git親友團

  Git的使用技巧還包括利用Git包含的和附加的一些強大工具,這些工具主要包括git svn、git citool、gitk和Git的自動提示腳本:

  git svn:Git和SVN可以很方便的集成在一起,這就大大減少了從SVN向Git遷移的學習成本,這也是我特別建議大家首次接觸Git的使用方式。git svn是一個Git內置的工具,你安裝了Git也就安裝了它,譬如說你們團隊有一個SVN服務器,但是你想利用Git本地的一些強大特性,那麼你依然可以安裝Git,使用Git的branch功能,只不過再更新代碼和提交代碼的時候,使用git svn命令即可。在這裏我簡單的講講最常使用和需要注意的兩個命令,其餘的命令讀者可以通過'git svn --help'來查看:'git svn rebase'命令取代了'svn update'用於將服務器代碼更新到本地;'git svn dcommit'取代了'svn ci',需要注意的是,本地必須用Git提交了代碼之後,再使用'git svn dcommit'。只需要這樣,你就可以輕鬆地從SVN轉向Git了。

  git citool:這是我個人使用率最頻繁的一個工具,上一篇文章也提到了,Git可以本地提交代碼,那麼你自然可以本地修改你的提交了,這個工具就是可視化界面,用於修改你本地的提交。只要在你的工作區間輸入'git citool',就會出現如下的界面

  

Git使用技巧篇(圖一)

 

  你可以用它來提交代碼,可以用它來將你本地的修改追加在上一次提交的代碼中,你還可以用它來修改你上次提交的信息等等。這個工具可以大大幫助你完成以前SVN不可能完成的任務

  gitk:是一個查看主幹/分支情況的工具,它主要用於觀察整個項目的分支狀況,使用'gitk'命令就會出現一個圖形化界面供你查看,本篇就簡單的說一下,大家回去試試就知道了

  Git 的自動提示腳本:它是Shawn O. Pearce爲了讓Git使用起來更方便而寫得Shell腳本,你可以在http://gitweb.hawaga.org.uk/ 找到一個叫做gitcompletion的腳本,下載下來,並按照該腳本中指導的方式進行配置,你就具有了Git自動提示(敲入部分Git命令,再按 Tab鍵)的功能,而且有了這個腳本,你也可以看到你當前工作在哪個branch下。惟一的不足是,它只支持Linux、Unix、Mac操作系統(推薦大家都用Mac進行開發)

  Git實戰─Git Hub

  經過這麼長時間理論知識的薰陶,想必大家早已躍躍欲試了,那麼我們在Git Hub上建立一個開源項目作爲實戰演習吧。Git Hub是全球最大的Git服務器供應商,每個帳號有100M的免費使用空間,網址是:https://github.com/

  首先我們在Git Hub上創建一個帳號,按照上面指導的方法設置好你的認證信息(每次提交代碼都會需要這個認證信息)

  然後,如下圖新建一個項目(選擇Create a New Repository),名叫git usage

  

Git使用技巧篇(圖二)

 

  在服務器端,你可以看到這個項目的信息,包括項目源代碼的URL,如下圖

  

Git使用技巧篇(圖三)

 

  在本地使用如下的命令,就可以完成你的第一次提交了:

  mkdir git-usage(創建項目目錄) cd git-usage(進入項目目錄) git init(Git初始化) touch README(創建一個README文件) git add README(增加該文件到索引) git commit -m 'first commit'(本地提交) git remote add origin [email protected]:phoenixtoday/git-usage.git(增加遠程服務器代碼庫地址) git push origin master(將本地代碼提交到遠程服務器上)

  總結

  我所在的項目小組自從使用Git後,發現Git提供的種種特性大大提高了我們的開發效率,在認識Git前我們無法想象一個版本控制工具可以讓開發任務切換變得如此自然流暢。所以我強烈推薦大家使用Git,你付出的學習絕對物有所值



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章