一個很小的HTML項目,使用。Git來記錄和跟蹤這個項目。包括以下內容:
創建版本庫。
添加與修改文件。
創建新分支。
打標簽並整理版本庫。
克隆版本庫。
創建版本庫 Creating a Repository
在Git中,版本庫(.git目錄)是與工作目錄樹並排放在同一個目錄中的。
本例中,要創建一個HTML頁面,給這個項目取名為mysite。
首先創建一個同名目錄“mysite”,並進入到這個目錄,然后輸入命令git init。
prompt> mkdir mysite
prompt> cd mysite
prompt> git init
創建完成。
代碼修改
往空版本庫里面添加文件:
創建一個名為index.html的文件,並添加文本:
<html> <body> <h1>Hello World</h1> <p>My first paragraph.</p> </body> </html>
創建了一個簡單的HTML文件后(把它放在mysite路徑下),就可以開始跟蹤版本了。
要想讓Git跟蹤這個文件,須先讓它知道這個文件,要分兩步走:
首先使用git add命令把該文件添加到版本庫的索引(index);然后使用git commit命令提交。
prompt> git add index.html
prompt>git commit –m "add in hello world HTML"
文件或文件列表可以作為git add命令的參數。
git commit命令創建一個提交記錄。
提交記錄是存儲在版本中的歷史記錄,每提交一次創建一個記錄,並標記出代碼的演進。
Git把提交者的姓名和郵件地址,以及提交留言,都添加到提交記錄中。
參數-m,告訴Git本次提交的留言為"add in hello world HTML"。
運行命令git log可以看到這個提交相關的信息:
prompt> git log
輸出的第一行顯示提交名稱,是Git自動產生的SHA-1碼。Git通過它來跟蹤提交,使用該哈希碼可以保證每個提交的名稱都是獨一無二的。
在項目中工作
修改HTML文件如下:
<html> <head> <title>Hello World in Git</title> </head> <body> <h1>Hello World</h1> <p>My first paragraph.</p> </body> </html>
修改完畢,Git可以檢測到文件被修改。
命令git status會顯示工作目錄樹的狀態,即當前的視圖狀態。
prompt> git status
上面的結果表明Git監測到了修改,但還不知道如何處理它們。
如果要提交,需要暫存(stage)修改,以准備把修改提交到版本庫。
Git有三個地方可以存放代碼。
第一個地方是工作目錄樹,編輯文件時可以直接在這里操作;
第二個是索引(index),也就是暫存區(staging area)。暫存區是工作目錄樹和版本庫之間的緩沖區。
第三個,也就是最終的一個,是版本庫。
命令git add,可以暫存對文件剛做的修改。它跟前面添加一個新文件時使用的是同一個命令,只不過,這次它告訴Git要跟蹤的是一個新的修改而非新的文件。
prompt> git add index.html
prompt> git add 。將當前文件夾的所有文件包括文件夾都加入index
prompt> git reset 撤銷上一次的add
prompt> git status
暫存修改過的index.html之后,執行命令git status可以看到,信息變為了Changes to be commited,index.html這行由紅色變為了綠色。
使用命令git commit時,不要忘記使用帶-m的參數,並在參數后面加上提交留言,以解釋修改的原因,如下:
prompt> git commit –m "add <head> and <title> to index"
prompt> git reset 2ee446d99c02ce66f4bc4ef463241950a9f2ddcd 提交恢復到某一次版本
git log可以快速瀏覽提交留言:
prompt> git log
prompt> git log -1
命令中加入參數:-1可以限制命令輸出的提交條目的個數。
理解並使用分支
比如mysite項目的代碼現在幾乎可以發布了,但是還需要進行測試等工作,直到確認它達到了預期的功能和質量,而與此同時,借助分支,可以開始下一個版本的新功能的開發了。
查看分支:
$ git branch 該命令會類出當先項目中的所有分支信息,其中以*開頭的表示當前所在的分支。參數-r列出遠程倉庫中的分支,而-a則遠程與本地倉庫的全部分支。
創建新分支:
$ git branch testing 創建一個名為testing的分支
切換分支:
$ git checkout teting 切換到testing分支上。通過向該命令傳遞一個-b參數,可以實現創建並切換分支的功能。
合並分支:
$ git merge hotfix 將hotfix分支合並到當前分支當中去
刪除分支:
$ git branch -d hotfix 刪除分支hotfix,-d選項只能刪除已經被當前分支所合並過的分支,而要強制刪除沒有被合並過的分支,可以使用-D。
重命名分支:
$ git branch -m oldbranch newbranch -M用來強制重命名,如newbranch已經存在的時候。
查看分支之間的不同:
$ git diff branchName 查看當前分支與branchName分支之間的差異,也可以使用:$ git diff branch1 branch2 來比較這1和2分支之間的差異,當使用第一種方式比較時,如果當前工作目錄中存在與branchName同名的文件,系統則會提示錯誤,要是指明要比較的 是文件還是分支,如果比較分支,可以進入.git中進行比較或切換分支,如果是>比較文件,則使用$ git diff -- fileName命令。
$ git diff <branchA>:<fileA> <branchB>:<fileB>
$ git ls-tree -r branch 列出所有的樹對象
把兩次提交的不同重定向到patch
$git diff dc20827e8880a0403dde7a94dfa540ebdd3c6df1 547348d336697c6e166f6b9183ed7ff61ef28b04 >haixin.patch
合並沖突:
如果在不同的分支中都修改了同一個文件的同一部分,Git 就無法干凈地把兩者合到一起(譯注:邏輯上說,這種問題只能由人來裁決。)
任何包含未解決沖突的文件都會以未合並(unmerged)的狀態列出。Git 會在有沖突的文件里加入標准的沖突解決標記,可以通過它們來手工定位並解決這些沖突。
在解決了所有文件里的所有沖突后,運行 git add 將把它們標記為已解決狀態(譯注:實際上就是來一次快照保存到暫存區域。)。因為一旦暫存,就表示沖突已經解決。如果你想用一個有圖形界面的工具來解決這些問題,不妨運行 git mergetool,它會調用一個可視化的合並工具並引導你解決所有沖突。
要從該清單中篩選出你已經(或尚未)與當前分支合並的分支,可以用 --merge 和 --no-merged 選項(Git 1.5.6 以上版本)。比如用 git branch --merge 查看哪些分支>已被並入當前分支(譯注:也就是說哪些分支是當前分支的直接上游。)
遠程分支:
遠程分支是對遠程倉庫分支的索引。它們是一些無法移動的本地分支,只有在Git進行網絡交互時才會更新。我們用(遠程倉庫名)/(分支名)來表示遠程分 支。比如想查看上次>同origin倉庫通訊時master的樣子,就應該查看origin/master分支。
推送本地分支:
$ git push (遠程倉庫名字) (分支名) 如:$ git push orgin serverfix 該命令會將本地serverfix分支推送到origin遠程倉庫的serverfix分支中去,也可以使用命令 $ git push origin serverfix:serferfix實現同樣的效果,可以將第二個serverfix更改為其它名字來指定要將該本地分支推送到遠程倉庫中的的指定分 支中去,如果不存在,則會在
遠程倉庫中新建分支。
獲取遠程分支:
在使用git clone命令從遠程服務器克隆Git倉庫時,只是將遠程倉庫當前分支的內容克隆到本地,要是克隆其他分支的內容,需要使用下面命令:可通過git branch -r命令來查看想要獲取的遠程倉庫中的分支。
$ git fetch origin 值得注意的是,在 fetch 操作下載好新的遠程分支之后,你仍然無法在本地編輯該遠程倉庫中的分支。
如果要把該內容合並到當前分支,可以運行 git merge origin/serverfix。如果想要一份自己的 serverfix 來開發,可以在遠程分支的基礎上分化出一個新的分支來:
$ git checkout -b serverfix origin/serverfix
這會切換到新建的 serverfix 本地分支,其內容同遠程分支 origin/serverfix 一致,這樣你就可以在里面繼續開發了。
Git pull:
從服務器的倉庫中獲取代碼,和本地代碼合並。(與服務器交互,從服務器上下載最新代碼,等同於: Git fetch + Git merge)。
從其它的版本庫(既可以是遠程的也可以是本地的)將代碼更新到本地,例如:“git pull origin master ”就是將origin這個版本庫的代碼更新到本地的master主分支。
git pull可以從任意一個git庫獲取某個分支的內容。用法如下:
git pull username@ipaddr: 遠端repository名 遠端分支名:本地分支名。這條命令將從遠端git庫的遠端分支名獲取到本地git庫的一個本地分支中。其中,如果不寫本地分支名,則默認pull到本地當前分支。
需要注意的是,git pull也可以用來合並分支。 和git merge的作用相同。 因此,如果你的本地分支已經有內容,則git pull會合並這些文件,如果有沖突會報警。
Git push
將本地commit的代碼更新到遠程版本庫中,例如 “git push origin”就會將本地的代碼更新到名為orgin的遠程版本庫中。
git push和git pull正好想反,是將本地某個分支的內容提交到遠端某個分支上。用法: git pushusername@ipaddr: 遠端repository名 本地分支名:遠端分支名。這條命令將本地git庫的一個本地分支push到遠端git庫的遠端分支名中。
需要格外注意的是,git push好像不會自動合並文件。因此,如果git push時,發生了沖突,就會被后push的文件內容強行覆蓋,而且沒有什么提示。 這在合作開發時是>很危險的事情。
git-clone命令只要碰到類似下面格式的遠程倉庫地址,都會被認為地址是符合SSH協議的: 賬戶@IP:工作目錄
git checkout -b [分支名] [遠程名]/[分支名]
如果你有 1.6.2 以上版本的 Git,還可以用 --track 選項簡化
$ git checkout --track origin/serverfix
刪除遠程分支:
git push [遠程名] :[分支名]
git pull 遠程倉庫名 遠程分支:本地分支
git push 遠程倉庫名 遠程分支:本地分支
git checkout -b 分支名 遠程倉庫名/分支名
創建分支的命令是git branch,該命令需要兩個參數:新分支名稱和父分支名稱。新創建的分支基於已經存在的父分支。
prompt> git branch RB_1.0 master
該命令從主分支(master branch)上創建一個叫RB_1.0的分支。
主分支master是Git的默認分支。分支名稱中的RB代表發布分支(release branch)。該前綴可以讓人快速分辨出哪些分支是發布分支。
現在來做一些新的改動。這些改動不影響准備發布的代碼。
在</body>之前增加如下代碼:
<ul> <li><a href="bio.html">Biography</a></li> </ul>
用如下命令提交這些修改:
prompt> git commit –a
參數-a告訴Git提交全部修改過的文件。
(這時彈出了一個文本文件,輸入的信息是提交留言)。
現在主分支上有最新的修改,而發布分支上還是原來的代碼。
請切換到發布分支,做發布前的最后修改。切換分支的命令是git checkout。
prompt> git checkout RB_1.0
轉換分支后,所使用的打開文件的編輯器會提醒文件已經被修改,重新載入文件,會發現剛才在主分支上做過的修改消失了。
可以用git status命令來查看自己在哪一個分支上:
prompt> git status
做發布前的最后修改:在<head>標記塊中添加一些描述性的元標簽:
<head> <title>Hello World in Git</title> <meta name="description" content="hello world in Git"/> </head>
保存並修改該提交:
prompt> git commit –a
處理發布
添加標簽
現在是發布的時候了,要給版本打個標簽。
給Git中的代碼打標簽,意味着在版本庫的歷史中標記出特定的點,這樣將來就容易找到相應版本的代碼。
prompt> git tag 1.0 RB_1.0
以上命令中的兩個參數分別指明了標簽的名稱(1.0)和希望打標簽的點(RB_1.0分支的末梢(所對應的版本或者說所對應的提交))。
用不帶參數的命令git tag可以查看版本庫中的標簽列表:
prompt> git tag
變基
想把RB_1.0分支上所做的修改合並到主分支上來,變基命令git rebase可以完成這項工作。
變基是把一條分支上的修改在另一條分支的末梢重現。
先回到主分支:
prompt> git checkout master
接着運行命令git rebase,后面跟一個參數:希望變基到哪條分支的末梢,就使用哪條分支名稱做參數。
prompt> git rebase RB_1.0
變基前和變基后的版本庫如下面兩個圖:
刪除分支
作為整理工作的一部分,刪除發布分支RB_1.0。
只要標簽還在,從標簽到版本樹起點的一連串提交記錄就都在。
這時候刪除分支只是刪除了分支的名字,並不會刪除分支上的任何實際內容。
prompt> git branch –d RB_1.0
打補丁
如果沒有了發布分支,如何給1.0.x分支打補丁呢?很簡單,只需要在打標簽的地方再創建一條分支即可。
前面創建分支的時候,命令的最后一個參數是新分支的父分支名稱,現在只須把父分支名稱改成發布標簽名即可。命令如下:
prompt> git branch RB_1.0.1 1.0
prompt> git checkout RB_1.0.1
運行命令git log快速查看歷史記錄:
prompt> git log --pretty=oneline
為代碼發布創建歸檔文件
沒有必要總是把歷史記錄(也就是Git版本庫)一起發布,通常情況下,將標簽對應的版本內容打包成一個tar包或者zip包就足夠了。
Git提供了git archive命令來做歸檔處理。
prompt> git archive --format=tar --prefix=mysite-1.0/ 1.0 |gzip > mysite-1.0.tar.gz
該命令中有三個參數:
--format指明要產生tar格式的輸出。
--prefix指明包中所有東西都放到mysite-1.0/目錄下。
1.0指明要歸檔的標簽的名稱。
最后一段命令把git archive產生的tar文件用管道輸出的方法傳遞給命令gzip進行壓縮,而壓縮結果則重定向到mysite-1.0.tar.gz壓縮包里。
創建zip文件:
prompt> git archive --format=zip –prefix=mysite-1.0/ 1.0 >mysite-1.0.zip
生成zip格式和tar格式的命令參數幾乎一樣,只是改變了傳遞給--format的參數,而且無需通過命令gzip管道輸出,直接把歸檔內容保存到歸檔文件中。
克隆遠程版本庫
git clone帶有兩個參數:遠程版本庫的位置和存放該版本庫的本地目錄。
第二個參數是可選的。