這個教程之前是發在社區網站上,現在把它轉到自己部落格上:)
http://oss.lzu.edu.cn/artical.php?id=16
說明:該教程全部圖片都來自於《pro git》。以下所有的操作,除非特別聲明,都是基於Linux終端來進行的。如果你發現這篇文章有錯誤,或者其他問題,歡迎與我聯絡:wengpingbo@gmail.com
1、什麼是GIT
Git是一個強調速度的分布式版本控制軟體和原始程式碼控制系統(SCM,source code management)。Git最初是由Linus Torvalds為核心開發而設計的管理軟體。自從Git推出以來,已經被很多開源項目所採納。每一個Git工作目錄是一個帶有完全記錄和版本資訊的倉庫,不依賴於網路和中央伺服器。Git是一個免費的開源軟體,遵從GNU v2協議。
Git這個詞在英語中的原意是很笨拙,沒用的人。Linus自嘲說:“我是一個任性的笨蛋,所以我把我的所有的項目的名字都和我很相似。第一個是Linux,現在是Git。”Git的協助文檔中描述Git為:笨拙的內容跟蹤者(the stupid content tracker)。(翻譯自WIKI)
關於開發Git的一些曆史由來,可以看看這個網站:https://lkml.org/lkml/2005/4/6/121
2、為什麼要用GIT
更順暢的工作流程,開發過程中,完全可以離線操作 快速,Git分布式架構使得本地倉庫包含所有的曆史版本資訊,你可以在不同的版本之間快速切換 彈性的本地分支,在svn下,你建一個分支需要把原始碼複製到另外一個檔案夾,而在Git下,建立分支的代價是非常小的,只需一條命令 倉庫目錄結構簡潔,用Git複製一個項目,只會在項目根目錄建立一個.git的目錄,而其他目錄很乾淨 內容按中繼資料方式儲存,所有的版本資訊都位於.git目錄下 完整性好,更易於協作開發 使用者群大,現在已經有成千上萬個開源項目採用Git來做專案管理,github上更是有無數個代碼倉庫
3、GIT安裝與配置
a) 安裝
1.從源碼安裝
在安裝之前,你必須保證以下幾個依賴包已經安裝在你的系統上:curl, zlib, openssl, expat, libiconv。如果你的系統是Ubuntu,你可以這樣安裝:
apt-get install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
當所有的依賴項已經解決,就可以從http://git-scm.com/download上下載Git的源碼,然後編譯安裝,具體命令如下:
tar -zxf git-1.*.*.*.tar.gz
cd git-1.*.*
make prefix=/usr/local all
sudo make prefix=/usr/local install
2.在Linux上安裝
如果你的系統是Linux或者Fedora,你可以通過以下命令直接安裝Git:
yum install git-core (fedora)
apt-get install git-core (ubuntu)
3.在Windows上安裝
儘管Git是發源於Linux,但現在Windows上也有能夠正常使用Git,只不過不支援中文,在Windows下所有的中文都顯示問號,另外還有一些功能上的BUG。所以建議還是在Linux上去使用Git,如果你不得不工作在Windows上,你可以到http://msysgit.github.com/上下載msysgit的最新版,安裝過程和其他Windows程式差不多,基本上點下一步就OK了。Msysgit預設會安裝git bash和git GUI這兩個程式,一般用git bash就可以了,它支援常用的命令。如果對Linux命令列不熟,你也可以用用git GUI,但功能有限制。
b) 第一次使用GIT
在你安裝好Git之後,你需要修改一些配置,才能正常使用Git。
Git通過“git config”命令來配置Git,這個命令有2個選項:--system, --global, 加上預設選項,分別對應Git上3級設定檔。第一個是/etc/gitconfig檔案,和--system對應,這是全域設定檔,修改這個檔案,將會影響系統上所有的使用者,所有的倉庫。第二個是你家目錄下的/.gitconfig檔案,與--global對應,修改它會對你目前使用者的所有倉庫產生影響。第三個是你倉庫中的.git/.gitconfig檔案,這是“git config”預設修改的設定檔,它只會對你當前倉庫產生影響。
在第一次使用Git時,你需要告訴你的協同開發人員,你是誰以及你的郵箱,在你提交的時候,Git需要這兩個資訊。具體通過以下命令設定:
git config --global user.name “Test OSS”
git config --global user.email oss.lzu.edu.cn@gmail.com
當然你也可以不用--global選項,但這意味這你在每一個倉庫中都要這樣設定。
同時,你也可以指定你的編輯器,你的Diff工具:
git config --global core.editor vim
git config --global merge.tool vimdiff
你還可以通過”git config --list”命令來查看你的設定。
當你把Git設定好之後,如果你要和從Git伺服器上獲得倉庫,或者向Git伺服器提交你的代碼(比如github),你可能需要產生你自己的ssh金鑰組。Git支援4種與伺服器端通訊的協議:git、http、ssh和https。其中git只是一個唯讀協議,也就是說你只可以從伺服器端擷取倉庫,但是你不能提交你自己的代碼。而http和https用的很少,大部分都只支援ssh協議和Git協議。
當你通過ssh協議與遠端伺服器進行通訊的時候,你可以通過以下命令產生ssh金鑰組:
ssh-keygen -t rsa
如果你沒有指定密鑰名稱和存放路徑的話,它預設把兩個不對稱金鑰放在你的家目錄下的.ssh目錄下,密鑰檔案預設名稱為id_rsa和id_rsa.pub,前者是私密金鑰,後者是公開金鑰。中間可能會要你設定存取金鑰密碼,這個可以設,可以不設,但為了安全考慮,還是建議你設一個訪問密碼。否則,意味著任何持有你密鑰的人都可以使用該密鑰。
然後把你的公開金鑰發給Git倉庫管理員,然後你就可以通過ssh協議來訪問伺服器端,期間程式會自動進行金鑰組匹配,如果你設了訪問密碼,你可能需要輸入密碼。
更多關於ssh的內容,請訪問這裡:http://www.freebsd.org/doc/zh_CN/books/handbook/openssh.html
這些設定完之後,你可以通過獲得任何一個公開的代碼倉庫來檢測你的git是否工作正常。比如下面這個:
git clone git://git2.kernel.org/pub/scm/git/git.git
4、GIT倉庫
Git做為一個資源管理和跟蹤系統,如果想要把自己的檔案託管在Git上,那麼首先你得讓Git知道你需要管理的檔案在哪。比如說現在我有一個項目,它在test檔案夾裡,我想讓Git管理這個項目,這個時候你需進入到這個目錄,然後運行“git init”命令。這個時候Git就會在該目錄下產生一個.git的隱藏目錄,Git用來進資料列版本設定和內容跟蹤的所有檔案都在該檔案夾下。
處於git跟蹤下的檔案只具有三種狀態:
Modified(working directory):被修改過的檔案 Staged(staging area):通過git add添加到暫存地區的檔案 Committed(git directory):通過git commit提交到倉庫的檔案
所以,一般的git工作流程可能是這樣:修改過某些檔案,然後把這些檔案添加都暫緩區,再提交到倉庫中形成一個版本或快照,最後提交到git伺服器上。而在中間,可能伴隨著分支管理,分支切換,撤消與合并。
可能有些人會覺得很奇怪,為什麼git會有暫存地區這個概念,直接提交到倉庫中不就ok了。其實這是git為了做版本控制用的,試想如果沒有暫存地區,每修改一個檔案,就會形成一個版本,太過頻繁,不易於管理。暫存地區其實就是下一個版本的檔案清單,你可以自由控制該往倉庫中提交什麼檔案,這也可以避免在一個版本中包含一些中間檔案,比如編譯後的檔案。
5、GIT基本流程
1.初始化倉庫
初始化倉庫有兩種情況,一種是直接在一個空目錄裡建立一個項目,這時候你可以這樣幹:
git init
另一種是從其他機器複製一個倉庫,比如這樣:
git clone git://git2.kernel.org/pub/scm/git/git.git (遠程倉庫)
git clone https://github.com/jquery/jquery.git (遠程倉庫)
git clone git@github.com:wengpingbo/MicroBlog.git (遠程倉庫)
git clone /home/oss/test.git (本地倉庫)
第一次從伺服器上複製一個倉庫,可能比較慢,因為git要把所有的記錄和版本全部複製下來,這也算git的一個弊端吧。
複製完後,就會在目前的目錄下產生一個工作目錄,名字以倉庫名字命名。如果你不想指定目錄,那就在上面的命令後加一個目錄就ok了。比如我想把test倉庫放到oss倉庫中:git clone /home/oss/test.git oss
之後,你就可以開始你的工作啦。
2.添加檔案
在編輯了幾個文檔之後,你可能突然想起來,好像檔案還沒有讓git跟蹤。Git並不會即時的跟蹤你的檔案,只在你明確讓它記錄你的檔案時,它才會把指定的檔案的目前狀態記錄到倉庫中去,然後又撒手不管了。我想這就是說git笨的原因吧。這個時候,你需要手動添加你的檔案當暫存地區:
git add filename1 filename2
如果你懶得一個一個加,你可以試試這個:
git add -A
它會把目前的目錄下所有的檔案都添加到暫存地區。
3.添加一個版本
在添加完檔案後,你可能覺得應該建立一個commit了。
git commit
怎麼樣。是不是有點不對勁,好像這個命令並沒有按你想象的那樣跳出一個提交成功的提示,而是直接跑到了你在配置中指定的編輯器中了。仔細看一下,原來是讓你給這個版本做一些備忘,隨便寫點什麼,然後儲存退出就ok了。如果你不想這麼麻煩,可以這麼幹:
git commit -m ‘initial version’
可能你覺得之前講的太羅嗦了,提交一個commit還這麼麻煩,其實有一個捷徑可以使你跳過添加檔案這個過程:
git commit -a -m ‘initial version’
大功告成,這個命令會把之前所有的已經添加的檔案都加入到這個版本中。
可能你又有疑問了,之前添加的檔案不是自動會加入到下一個版本中嗎,問什麼還加這個-a參數。
其實git add命令只是把指定檔案的目前狀態添加到暫存地區,並不代表一個檔案一旦添加,就會一直存在每個版本中。如果你添加一個檔案後對這個又進行了修改,在你commit時候,只會commit這個檔案添加時的狀態,不會把之後的修改也commit進去,除非你再次添加。
4.推送變更
在你commit完之後,你可能想把自己的代碼提交到github或者其他git伺服器上,與他人交流共用,這時候就需要和遠程伺服器打交道了。
如果你是在本地建立起的倉庫,預設情況下是沒有任何伺服器位址的,如果你是從其他伺服器複製過來的倉庫,這個伺服器位址會自動添加到你的倉庫中,你可以這樣查看:
git remote -v
如果只輸入”git remote”,就只會列出伺服器端的別名,不會列出地址來。
一個倉庫可以有多個伺服器位址,這就意味著,你可以從不同的人手中複製同一個倉庫,但這並不會打亂你自己的分支,哪怕雙方的分支名字都一樣。假如你現在在和另外兩個人做同一個項目中的同一個分支,你發現A的一個模組正是你想要的,你想把他的代碼合并到你現在的版本中,這時候你可以這樣做:
git remote add code_a git://url/test.git //添加對方的地址,code_a是別名
git fetch code_a //複製對方的倉庫到本地,但不合并,git pull會自動合并
git merge code_a/master //把對方master分支合并到自己目前的版本下
合并完之後,你可能想提交你的代碼到其他的伺服器上,這時候你可以先把要提交的伺服器位址添加進來,然後這樣做:
git push origin master
上面的命令就是把自己master的分支提交到名字為origin的伺服器上
5.建立並管理分支
在做項目的時候,你可能會想寫一些擴充性的功能,或者做一些小實驗,但是你又不想影響你現在的項目。這時候,你可以建立一個分支,然後在這個分支裡寫東西,當覺得不好的時候,你可以把這個分支刪除掉,對你之前的主分支沒有任何影響。或者你覺得這個新特性超出了自己的預想,可以合并到主分支裡,這時候你只要把工作轉回主分支,然後合并分支,最後刪除分支,然後就跟那個分支沒建立一樣。具體操作如下:
git branch test //建立一個test分支
git checkout test //轉到test分支
edit something...commit something...
git checkout master //轉到master分支
git merge test //合并test分支
git checkout -b test2 //建立test2分支,並轉到test2分支
git branch -d test //刪除test分支
git branch //列出分支列表
git branch -v //列出分支列表和當前commit
Git merge的實質是把兩個版本合在一起,然後在當前分支建立一個新的commit,如果你在兩個分支的同一個檔案的同一個地方都做了修改,這時候merge就會失敗,git就不會自動建立一個新的commit,而是直接停住。你需要手動修改這些衝突的檔案,選擇這兩個分支中的一個版本,或者自己重寫這個部分,然後手動添加這些檔案到暫存地區,再commit一下就ok了。要查看哪些檔案衝突了,可以用”git status”查看。
6.撤消改動
是人就會犯錯。當你執行某個命令之後,突然發現,自己寫錯了,或者漏了一個檔案,這時候怎麼辦。
如果你提交得太早,忘了添加某些檔案,你可以這樣做:
git commit -m ‘add something ’
git add file1
git commit --amend
最後一個命令會把你當前暫存地區最為上一次的commit。如果你commit以後,馬上amend,這時候git會直接跳到編輯commit備忘裡面,這樣你可以修改你上次commit的備忘。
如果你添加了不該添加的檔案,你可以這樣挽回:
git add . //把所有的檔案都添加進去
git reset HEAD readme //把readme檔案從暫存地區去除
如果你發現你編輯錯了一個檔案,你想把它恢複到上一個版本的狀態,這時候你可以這樣:
git checkout -- filename1 //只撤消這一個檔案
如果你覺得這個版本糟糕透了,想完全復原到上一個版本,你可以幹如下事情:
git reset --hard HEAD^
HEAD是指向目前的版本,^指目前的版本的父版本,這個操作無法撤消。你可以把--hard換成--soft,這隻會回退commit資訊。還有一個--mixed預設選項,大家可以參考官方文檔,查看這3個選項的具體區別。
6、GIT常用命令
Git add
Git clone
Git commit
Git push
Git checkout
Git reset
Git pull
Git status
Git branch
//advanced
Git tag
Git log
Git merge
7、學習GIT相關資料
《pro git》 :http://git-scm.com/book/zh
《git magic》 :http://www.csc.kth.se/utbildning/kth/kurser/DD2385/material/gitmagic.pdf
Git manual :http://git-scm.com/docs