[轉]Git入門與實踐(一)

git入門與實踐() 

linux

·        March 10th, 2010git

·        Posted in UNIX環境編程github

·        By ghosTM55算法

Write comment數據庫

什麼是版本控制 
要了解什麼是git,首先須要瞭解什麼是版本控制(Version Control),版本控制系統(Version Control System,簡稱VCS)是一種記錄一個或多個文件的變化的系統,這樣的系統可以方便你從此調用找回某個特定時期(或版本)的文件。 版本控制系統普遍地應用於程序開發等領域,它能夠協助你將某個指定的文件(甚至是一整個項目)返回至某個以前記錄的狀態,查看發生了哪些變化、對變化進行比較或者是修正致命錯誤。 版本控制系統主要經歷了本地版本控制,集中式版本控制到分佈式版本控制的發展: 

編程

·        本地版本控制(Local Version Control System)顧名思義就是本地化的版本控制系統,沒有網絡協做等較爲先進的版本控制的概念ubuntu

·        集中式版本控制意(Centralized Version Control System)爲有一臺版本控制服務器運行在那邊存放並提供一個項目中全部版本文件的服務,在很長一段時間內佔據主流,其中CVSSubversion(SVN)爲其表明小程序

·        分佈式版本控制(Distributed Version Control System)克服了集中式版本控制可能由於單點失敗形成的巨大損失的缺點,讓每一臺客戶端在每一次checkout操做後都徹底鏡像整個版本控制中的項目。在分佈式版本控制系統中,任何一臺機器均可以視爲版本控制服務器。即便有一臺服務器失去服務能力,其它機器與系統能夠繼續協做維持版本控制系統的正常運轉。git就是分佈式版本控制系統c#


git的歷史 
2005年,Linux內核開發團隊與其使用的分佈式版本控制系統BitKeeper的開發公司關係破裂,他們沒有了無償使用BitKeeper的特權。這直接催生了Linux開發社區本身開發一套分佈式版本控制系統的想法。 Linux開發社區借鑑了以前使用BitKeeper時看到的閃光點,並但願可以在版本控制系統的速度、架構設計與各種特性支持中做出較好的改進與提高,因而,git誕生了。 
基礎概念與機制 
git
與其它主流的VCS最大的區別就是,在項目版本更新的過程當中,git記錄的並不是是基於初始文件的變化數據,而是經過一系列快照(Snapshot,就像是個小型的文件系統)來保存記錄每一個文件。若是有些文件在版本更新後沒有發生任何變化,那麼在新的版本中它會是一個指向最近一次更新的文件版本的連接。 此外,幾乎全部git的操做都是在本地進行的,因此,沒有了延遲,幾乎全部的操做都是瞬間完成的。例如,當你想要查看項目歷史時,不須要特意去服務器上抓取歷史記錄,直接在本地瀏覽便可。這意味着,你能夠在本地對比兩個不一樣版本的文件的差異,能夠在本地查看過去有哪些人對指定文件做出了修改與更新,能夠……幾乎徹底本地化的操做也讓這樣一種場景成爲了可能當一我的在飛機、火車上,或者是任何因素致使沒有網絡鏈接條件可是又必須抓緊時間對本身的項目進行修改與開發,同時又須要有版本管理系統來記錄每次他commit的歷史,這時,git提供了他全部須要的便利。 
git
使用SHA-1 Hash算法加密生成的40位字符串(而不是文件名)來記錄表明git中的每樣東西。格式就像這樣: 

安全

6bafcdc09f3d6d416f6572f82082987a486d3098 

git中的文件主要會處於三種狀態,它們分別是: 

·        Committed文件或數據已經安全的存放在了git本地數據庫中

·        Modified文件或數據已經修改可是還沒有commit到數據庫

·        Staged文件或數據已被標記要放入到下一次commit

這樣的機制導致git的鏡像會由三個部分組成(假設有一個git目錄叫git-repo): 

·        Git directory存放項目中全部元數據以及對象的地方(git-repo/.git/)

·        Working directory在這裏是從git項目數據庫中checkout出的一個單獨的(默認狀況下是最新的)項目版本,用於對指定項目版本中的文件進行修改和編輯(git-repo/)

·        Staging area通常是存放在Git directory中的一個簡單的文件,裏面存放着下一次須要commit的文件的信息(git-repo/.git/)



安裝git 
在快速瞭解了git的概念與歷史後,咱們就要開始學習使用它了,天然而然的,第一步咱們須要將git安裝到咱們的系統中去。 衆所周知,不一樣的Linux發行版本有着不一樣的包管理模式,在大多數Linux發行版本的軟件源中,都會有現成的git包已經打好以提供yumaptitude之類的工具直接解決依賴問題下載與安裝。 固然,你也能夠手動下載最新的git源代碼包,自行編譯,不過須要注意一點的是,確保你已經解決了爲手動編譯git而須要解決的軟件依賴問題: 
使用yum工具先行解決包依賴問題(適用於RHEL,CentOS,Fedora):
# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel

使用aptitude工具先行解決包依賴問題(適用於Debian,ubuntu):
# aptitude install curl-devel expat-devel gettext-devel openssl-devel zlib-devel

完成這些依賴的安裝後,到這裏下載最新的git源代碼包,而後開始安裝: 
$ tar -zxf git-xxx.tar.gz # xxx
表明版本號
$ cd git-xxx/$ make prefix=/usr/local all$ sudo make prefix=/usr/local install

一旦git的安裝完成了,從此你可使用git自己來獲取git最新的updates: 
$ git clone git://git.kernel.org/pub/scm/git/git.git[/pre]git
一樣可以在Mac OS XWindows上使用,具體的操做請參考這裏這裏 
其餘Linux發行版本(例如archlinux,gentoo),可參照各發行版本的官方手冊與說明使用各自的包管理工具安裝。 


配置git 
完成git的安裝後,不要急着使用,首先你須要對git進行一些小小的配置,它在git的應用(通常是項目開發中)是必要的。git提供了config工具(你也能夠手動)來配置如下三份git配置文件: 


·        /etc/gitconfig: git的系統全局配置文件,該配置文件中的配置選項對操做系統上全部使用git的用戶產生影響,使用git config –system能夠針對此文件進行配置

·        ~/.gitconfig: git的用戶全局配置文件,該配置文件的配置選項對當前用戶產生影響,而且會覆蓋掉系統全局配置文件中已經存在的配置選項,使用git config –global能夠針對此文件進行配置

·        .git/config: 該文件存在每一個git鏡像下,其配置文件的配置選項僅對該git鏡像產生影響,它會覆蓋掉用戶全局配置文件中已經存在的配置選項

瞭解了配置git的文件位置與機制後,咱們首先就來嘗試配置一下git的用戶信息: 
$ git config --global user.name "Thomas"
$ git config --global user.email
 ghosthomas@gmail.com

這時,你就會發如今~/.gitconfig文件中,多出了與用戶信息相關的配置(2條賦值語句git的配置文件中,你能夠針對用戶名、郵件地址、編輯器、diff工具等進行配置,具體的配置參數與方法使用命令 
$ git help config
便可得到。 


開始git 
初始化/獲取 git鏡像 
要開始使用git,首先要作的就是建立或者獲取一個git鏡像,建立一個文件夾,將其初始化爲git鏡像: 
$ pwd/home/thomas/workspace/tmp
$ mkdir git-repo
$ cd git-repo/
$ git init
Initialized empty Git repository in /home/thomas/workspace/tmp/git-repo/.git/

在這裏能夠看到,我創建了一個名爲git-repo的文件夾,而且將它初始化成爲git鏡像目錄,初始化的命令爲git init完成初始化後,會在目錄下建立一個名爲.git的子目錄,對了,這就是前面提到的Git directory你也能夠經過git clone命令來獲取一個已存在的git鏡像: 
$ git clone git://github.com/schacon/grit.git

默認狀況下,clone命令執行後會根據服務器上git鏡像的目錄名建立目錄並進行git鏡像的clone,你也能夠在上述命令後加上本身但願看到的目錄名(好比repo123)來將遠程的git鏡像clone到該目錄下: 
$ git clone git://github.com/schacon/grit.git repo123

有了git鏡像後,咱們就能夠開始學習git的基本使用技巧了! 


Modify -> Stage -> Commit -> Track 
恭喜,如今你已經有一個git鏡像來學習、實驗或使用了。讓我從實際應用出發,一步步爲你介紹和解釋git的基本應用。 
git的世界裏,有兩類文件,分別是未追蹤(untracked)和已追蹤(tracked),已追蹤的文件是指已經放入了最新的git鏡像(snapshot)裏,已追蹤的文件又分爲三個狀態,分別是: 


·        Unmodified文件沒有作過任何修改

·        Modified文件已被修改更新

·        Staged文件已經修改更新,準備commit的狀態

而未追蹤的文件指的就是在git的工做目錄下,全部還沒有被提交放入git鏡像目錄中的文件。 
在學會提交文件至git鏡像前,先介紹一個很是重要的工具,git status,它會告訴你目前git鏡像的狀態,在使用git的過程當中,你將會始終依賴這個工具幫助你更出色的完成工做! 
$ git status
# On branch master
#
# Initial commit
#nothing to commit (create/copy files and use "git add" to track)

能夠看出,git status給出了至關詳細的信息,第一行中首先給出的是git的分支(branch)狀態信息,branch會在未來的文章中進一步爲你們介紹,它是git的王牌特性之一。接着,git會告訴你如今尚未東西提交到鏡像中,須要先使用命令git add來對文件進行追蹤。 
因此,假設咱們先在git的工做目錄中使用C語言寫一個helloworld的小程序,保存,咱們獲得一個文件: helloworld.c,而後,咱們但願將這個文件被git鏡像追蹤(track)到,那麼咱們須要: 
$ git add helloworld.c[/pre]
這樣,咱們就將helloworld.c加入到了git鏡像中去進行版本控制,再次使用git status來查看目前的鏡像狀態: 
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached ..." to unstage)#
#       new file:   helloworld.c#

注意這裏它提到了changes to be committed,意思是該文件已經處於staged狀態,接下去你能夠根據本身的須要將其提交(commit),或者若是你以爲這是一個誤操做,該文件不該當被提交,你能夠經過git rm –cached命令來取消它的staged狀態(你會發現status信息中做出了精確的提示) 
如今,咱們經過命令git commithelloworld.c提交: 
$ git commit

這時,會出現一個帶有status信息的文本給你編輯(使用什麼編輯器取決於你對git的配置),在以」#」開頭的註釋行下輸入一些文本,用於註釋這次提交,方便於其餘代碼協做者的維護與理解! 
你也能夠經過命令參數-m來直接輸入註釋內容,加快提交速度: 
$ git commit -m "comment here"

至此,你的文件helloworld.c已經處於tracked狀態!整個過程就是小標題中所說的從修改(建立)文件到最終提交的過程。 
接下來,咱們將會探討一些更爲有趣的git使用技巧! 


git應用進階 
在前一小節中,筆者舉出的只是helloworld式的git基礎應用,到這裏你們應該有一個可用的git鏡像以及一個已經被git追蹤管理的文件了吧,是否是很方便和快捷呢?這個小節中我會帶領你們瞭解更多git的工具與使用技巧。 
修改已提交文件 
如今,咱們有一個helloworld.c在鏡像中進行版本控制了,咱們發現這個文件有一個小錯誤,oh,有一個循環的條件寫錯了,趕忙修改一下這個不大不小的bug,針對文件完成修改更新後,咱們能夠經過git status看到: 
# On branch master
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   helloworld.c
#no changes added to commit (use "git add" and/or "git commit -a")

git status
告訴咱們,helloworld.c被修改過了,若是你想要提交,須要再次git add該文件,或者,你能夠直接使用git commit -a跳過add的步驟,直接提交(還沒有track的文件必須先git add才能進行提交) 
在提示中,還有提到說,若是你想撤銷對helloworld.c的修改,就可使用git checkout命令來實現,這裏的狀況會是: 
$ git checkout -- helloworld.c

若是你這麼作了,你就會發現,你的helloworld.c又回到了以前沒有被修改過的時候的狀態。 

git中的diff 
Unix/Unix-like系統中,幾乎都會有一個小巧的對比文件不一樣的工具叫作diff,在git中也有這麼一個工具,來詳細比較你修改後準備提交的文件與修改前的狀態的不一樣之處,恩,也許你猜到了,這個命令就是git diff 
如今咱們嘗試着再次修改一下helloworld.c,而後運行git diff: 
$ git diff
diff --git a/helloworld.c b/helloworld.c
index befc634..a86316b 100644
--- a/helloworld.c
+++ b/helloworld.c
@@ -1,3 +1,4 @@
+/* new comment line */
 
#include int main(void) {

經過gitdiff工具,咱們很容易發現,此次我在程序中新加入了一行註釋代碼。 

添加新文件 
恩,有了一個像樣的代碼文件後,我須要爲個人代碼寫些說明文檔,同時我也須要對這樣一篇文檔進行維護,那麼,就創建一個README.txt文件,而且將它trackgit鏡像中去,看到這裏讀者們能夠先自行嘗試一下: 
$ echo README > README.txt
$ ls
helloworld.c  README.txt
$ git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       README.txtnothing added to commit but untracked files present (use "git add" to track)[

至此,就有一個新的文件已經隨時待命準備提交了,你能夠清楚的看到git status很是聰明的將README.txt歸類爲了untracked files裏,如今咱們將它加入git鏡像: 
$ git add README.txt
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       new file:   README.txt
#

你能夠像以前那樣將README文件commit,可是此次咱們將會展現的是如何unstage一個文件,在git status信息中,它告訴用戶使用git reset HEAD命令來unstage一個文件,咱們嘗試一下: 
$ git reset HEAD README.txt
$ git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       README.txt
nothing added to commit but untracked files present (use "git add" to track)

看,README.txt又回到了untracked狀態! 

重命名git中的文件 
假設如今咱們須要修改README.txt的文件名,千萬要記得咱們的文件在git的鏡像中進行版本控制管理,因此,不要魯莽的直接使用unix命令mv或者rm來對git鏡像中的文件進行普通的文件操做,固然,若是你真的一不留神那麼作了,也沒關係。 
git
中,使用git mv工具來對文件進行重命名: 
$ git mv README.txt tutorial.txt
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       renamed:    README.txt -> tutorial.txt
#
$ git commit -a -m "renamed a file"
[master 55ce30d] renamed a file 1 files changed, 0 insertions(+), 0 deletions(-)
 rename README.txt => tutorial.txt (100%)
能夠看到,在提交變動後,README.txt在文件系統以及git鏡像中都被成功地重命名爲了tutorial.txt。一樣的,你能夠unstage來撤銷對該文件的重命名,the choice is yours 

刪除git中的文件 
若是咱們再也不須要tutorial.txt這個文件,咱們能夠將其從git鏡像中刪除,git中刪除文件的命令是git rm: 
$ git rm tutorial.txt
rm 'tutorial.txt'
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       deleted:    tutorial.txt
#
$ git commit -a -m " deleted a file"
[master 7d81981]  deleted a file 1 files changed, 0 insertions(+), 1 deletions(-)
 delete mode 100644 tutorial.txt

正如以前所提到的,這些操做都是能夠恢復的,由於git是版本控制系統,因此天然而然的就會有一套版本歷史管理機制。 

查看commit歷史 
工具git log提供了查看git鏡像的commit歷史: 
$ git log
commit 7d819818530ce89322019ba5000723c973eb0420
Author: ghosTM55
Date:   Sun Mar 14 15:26:22 2010 +0800
      deleted a file
 
commit 55ce30d88fb5c81d20bdf86e2034053613fed632
Author: ghosTM55
Date:   Sun Mar 14 15:11:39 2010 +0800
     renamed a file
 
commit 2ed9f1f9bd1a7561cd7e57dcdbd7f2cda54668fb
Author: ghosTM55
Date:   Sun Mar 14 14:58:11 2010 +0800
     a little change
 
commit dde0bab46a9d9f29c50d2996a9efe20253be9f15
Author: ghosTM55
Date:   Sun Mar 14 14:28:48 2010 +0800
     
新文件來了,舊文件改了
 
commit c06c4e5ebc3a5281a3400c31c20e95ebd43f1547
Author: ghosTM55
Date:   Sun Mar 14 13:36:02 2010 +0800
     
第一次提交

能夠看到,git詳細記錄了每次commit的信息(checksum值、提交者信息、提交時間) 


獲取命令幫助 
(系列)文只是guide,不是manual,因此不會爲讀者詳細解釋每個git命令的使用。當讀者想要詳細瞭解某命令的使用時,學會本身閱讀git自帶的manual文件是關鍵。 
例如,若是你想了解更多有關於git log的使用方法,輸入命令: 
$ git log help

便可。一樣的,你也能夠經過google等方法獲取更多有關git的使用技巧! 


總結 
本文是git入門與實踐系列的第一篇,對git進行了最爲基礎的介紹與入門引導,在之後的文章中,我會爲你們進一步講解git的應用與技巧。盡請期待! 
ghosTM55
 


參考資料: 


·        Pro Git 2009

·        Git Community Book

轉自:http://my.oschina.net/zhangqingcai/blog/39102

相關文章
相關標籤/搜索