Git 是一個分散式管理工具,通過指紋字串來時刻保持資料的完整性,關心的是檔案資料整體的變化,並不儲存變化前後的差異資料;Git 在本地磁碟儲存有關專案的歷史更新,所有絕大多數操作只需要訪問本地檔案資源,並不需要Internet。當然可以使用GitHbub將程式碼託管,進行遠端開發,方便團隊比較分散的情況(這正體現Git分散式的優勢);開發人員只需將專案clone到本地,進行相應的開發然後push上傳到 GitHub(GitHub使用的是utf-8編碼,所以上傳的檔案如若不是以utf-8編碼,可能出現亂碼),供別的開發人員更新即可。
任何檔案在Git庫中都有四種狀態:未跟蹤狀態untracked、跟蹤狀態tracked(未修改狀態unmodified、已修改狀態modified、暫存狀態staged),參考http://blog.csdn.net/u011384252/article/details/9406503
,由於檔案的上述四種狀態,在使用Git進行專案管理的時候涉及到三個區域:
(1)Git 本地資料目錄:每個專案都有一個 git 目錄,它是 Git 用來儲存後設資料和物件資料庫的地方。該目錄非常重要,每次克隆映象倉庫的時候,實際拷貝的就是這個目錄裡面的資料。
(2)工作目錄(專案工作空間):從專案中取出某個版本的所有檔案和目錄,用以開始後續工作的叫做工作目錄,即就是我們進行專案開發的目錄。
(3)暫存區域:所謂的暫存區域只不過是個簡單的檔案,一般都放在 git 目錄中。
Git本地倉庫的基本用法:
① git init :初試化當前目錄為一個Git本地倉庫。
② git add : 如果一個檔案是未被跟蹤的,將 一個檔案加入到Git版本控制當中,讓Git對其進行跟蹤;如果一個檔案是已修改狀態,則將一個檔案放到暫存區中。
git add . : "."點表示當前目錄下的所有內容
③ git status : 檢視當前Git倉庫中所有檔案的狀態,若是為跟蹤狀態 則用紅色顯示。
④ git diff:比較工作目錄中當前檔案和暫存區域快照之間的差異,也就是修改之後還沒有暫存起來的變化內容。
⑤ git commit:提交暫存區域。
git commit -m <說明資訊>
git commit -a 可以跳過暫存區域,直接將已跟蹤的檔案暫存起來一併提交。
⑥ git rm :從Git中刪除一個檔案。
git rm --cached :從暫存區刪除一個檔案,但是仍保留在工作目錄中。也就是將檔案變為未跟蹤狀態。
⑦ git log:檢視專案提交歷史記錄。
git log -p 選項展開顯示每次提交的內容差異
git log --stat 僅顯示簡要的增改行數統計
git log --pretty=
,其中option可以是:oneline(使每條歷史資訊在一行中顯示),short,full,fuller,format(按指定的格式輸出)gitk 可以開啟歷史記錄的視覺化檢視視窗。
⑧ git commit --amend:修改最後一次提交。該命令是提交當前快取區快照,並修改最後一次的說明。
⑨ git checkout -- :撤銷對檔案的修改,慎用!
⑩ git reset HEAD :撤銷對檔案的暫存,讓檔案回到暫存前的狀態。
Git遠端倉庫的基本用法:
① git clone [url]:將一個遠端倉庫克隆到本地。
② git remote:檢視當前配置的遠端倉庫,在克隆完某個專案後,至少可以看到一個名為origin的遠端倉庫,Git 預設使用這個名字來標識你所克隆的原始倉庫。如git remote add origingit@github.com:usernmae/repositoryname.git
-v :顯示對應的克隆地址。
git remote add [remote-name] [url]:新增一個新的遠端倉庫。
git remote show [remote-name]:檢視遠端倉庫資訊。
git remote rm [remote-name]:移除遠端倉庫。
git remote rename [old-remote-name] [new-remote-name]:重新命名遠端倉庫。
③ git push [remote-name] [branch-name]:推送資料到遠端倉庫,remote-name指的是遠端倉庫簡稱,branch-name指的是分支名稱。對於克隆的倉庫預設分別為:origin,master
git push -u origin master //將本地的專案提交到遠端倉庫
Git將遠端倉庫GitHub取回本地:
① git [url] : 在git下切換到想要存放此專案的目錄,執行這條命令就可以將專案克隆到本地磁碟的當前目錄
②專案取回本地,遠端倉庫GitHub上有更新,取得更新
git fetch origin //開始取得更新
git merge origin /master //將更新內容合併到本地分支/master
======================================================================================================
Git基本概念
Git作為一個版本控制軟體,相比其他版本控制軟體有什麼不同呢?
-
Git是一個分散式的版本控制系統,一般來講,各個Git倉庫沒有主次之分;
-
大多數的操作可以在本地完成,事後方便時,再推送到中心伺服器的倉庫中;
-
採用“直接記錄快照,而非差異比較”
的版本控制策略,內部只關心檔案資料的整體是否發生改變,而不是檔案內容的具體差異(Git內部被實現為一種微型的檔案系統);
-
Git工作時就是在工作目錄(工作區、work tree)、暫存區(索引、index file)、本地倉庫
三者之間管理檔案的變化情況,Git會監視工作目錄中的檔案變化(增加新檔案,刪除檔案,修改檔案等),需要我們自己手動將變化的檔案新增(git add)到暫存區中(這就是檔案快照),然後再提交(git commit)到本地倉庫中;上述過程,涉及Git內部的三種物件:commit物件、tree物件和blob物件,blob物件會對應的檔案快照中那些變化的檔案內容,tree物件記錄了檔案快照中各個目錄和檔案的結構關係,從概念上講,tree物件和blob物件組成了檔案快照,commit物件則記錄了這次要提交到本地倉庫的檔案快照,同時也會指向上次的commit物件,它也是Git內部進行版本控制的重點(Git內部會記錄各個commit物件,並用HEAD來指示當前分支中最新的commit物件),很多重要的功能,如分支、版本回溯、Git倉庫內部狀態等都是在commit物件基礎上實現的;上述的每一個物件都對應一個獨一無二的ID,該ID是一個由40個字元組成的雜湊碼,由SHA-1演算法計算而來;Git能夠通過ID的前幾個字元就識別出對應的物件;
-
Git的分支功能很強大,很靈活,切換速度非常快,並且實現成本很低,這也是Git比其他版本控制軟體要受歡迎的原因之一;
-
Git擁有豐富的、功能強大的命令,一個命令通過配置不同的選項可以實現不同的功能;要學好Git,關鍵就是要掌握這些命令,並靈活使用它們;
Git常用命令解析
Git中有許多命令,並且每種命令都有一些功能選項可被選擇,因此,在不熟悉Git這些命令的時候,查閱這些命令的使用說明是不錯的選擇。
要查詢Git命令,可以使用git help 命令或者git 命令 –help的方式,它會自動開啟瀏覽器來檢視。
1. Git倉庫建立
git init
在專案的開始,必須使用該命令來建立和初始化Git倉庫,它會在專案的資料夾下生成一個隱藏的.git資料夾
,這就是這個專案的Git本地倉庫,後面所有的Git命令操作都是針對該資料夾裡的內容。執行過該命令後,原來的資料夾就成為了Git的工作目錄。
Note:在一個已經初始化過的資料夾下再次執行git init
,Git並不會將之前的.git資料夾的內容清除,這應該是Git的一種保護。
.git資料夾的初始組成如下:
初始狀態下,Git預設處於master分支,HEAD檔案的內容為ref: refs/heads/master,但在refs/heads目錄下卻沒有master檔案;而objects資料夾下則沒有檔案。
在有過一次提交後,.git資料夾就會產生變化,如增加了logs資料夾,裡面記錄了git各種操作產生的log,我們通過git命令,如git log, git show, git reflog等可以檢視這些log內容; 產生了一個index檔案,這就是暫存區對應的檔案; objects資料夾下新增了很多資料夾和檔案,它們實際就是檔案快照(tree物件和blob物件)存放的地方; refs/heads資料夾下這時生成了master檔案,其內容就是master分支最新commit物件對應的ID;如果有其他分支,則在refs/heads資料夾下也會生成以分支名命名的檔案,裡面儲存著該分支最新commit物件的ID。
2. 檔案快照
git add .
在Git中,工作目錄下檔案的狀態可以分為已跟蹤和未跟蹤兩大類狀態,其中,已跟蹤的檔案是指已經被提交到git倉庫的那些檔案,而未跟蹤的檔案是指還沒被提交到Git倉庫中的那些非Git忽略的檔案(Git可以通過在專案根目錄下產生一個.gitignore檔案,在裡面指定要忽略的檔案型別,這樣Git就不會去監視這些檔案的變化),如果工作目錄中已跟蹤的檔案被修改或者刪除,或者有新的檔案(包括非空資料夾)加入,則通過git status
可以檢視到Git監視到檔案變化情況,然後通過git add .
做一次檔案快照,並將其儲存到暫存區(index檔案)中,等待被提交到Git倉庫中。
3. 檔案快照提交至倉庫
git commit -m '本次提交檔案變化的描述資訊'
如果工作目錄中的檔案變化已經被暫存(也可以同git status
來檢視),則說明這次的檔案快照可以被提交到倉庫中,並一直儲存。
提交時,需要新增一些資訊,這裡最好要將這次的檔案變化情況描述清楚,以便以後在版本回溯時能夠了解到各版本之間的差別。
如果工作目錄中僅是已跟蹤的檔案被修改或被刪除,則可以不用先git add .
,直接使用git commit -am "描述資訊"
即可。
4. 檢視工作目錄檔案狀態
git status
在git命令執行後,要養成通過git status
檢視git狀態的習慣,以便及時瞭解檔案變化的情況。通過git status
可以知道檔案的狀態(已修改未暫存、已刪除、已修改並已暫存等待提交、未跟蹤)。
5. 檢視提交歷史
git log
通過git log
可以檢視當前分支的所有提交歷史,知道每次提交的commit物件的ID以及提交時附加的描述資訊等。要顯示更多的資訊,需要使用其支援的選項,如git log -p
可以將每次提交的檔案變化也顯示出來。
Note : git log
顯示的內容可能會比較多,但git bash上顯示不下時,最下面會有一個冒號:,指示還有更多的內容,這是通過上下箭頭就可以選擇內容進行檢視,要退出按q鍵即可,要檢視其他命令,按h鍵。
6. 檢視指定的提交物件
git show commit-id
通過git log
可以顯示整個提交歷史,而通過git show commit-id
則可以檢視指定的某次提交記憶體,當然git show -all
也可以顯示出提交歷史,另外還可以格式化顯示內容。具體請檢視其help。
Note : commit-id可以是commit物件對應的ID,也可以是HEAD,分支名,tag等。
7. 檢視工作目錄/暫存區/倉庫之間的差異
git diff
是比較工作目錄與暫存區的差異
git diff HEAD
則是比較工作目錄與倉庫中最近一次的提交間的差異
git diff --cached
比較了暫存區與倉庫中最近一次的提交間的差異。
8. 分支的建立、刪除、切換、合併、檢視
Git一個比較吸引人的功能就是其強大的分支和合並功能。初始狀態下,Git預設的分支為master。
- 通過
git branch
可以檢視目前Git倉庫中已有的分支;
- 建立分支 :
git branch 新分支名 [分支起點]
,沒有分支起點的話,則預設在當前分支的最新的提交上建立分支
- 切換分支 :
git checkout 分支名
- 建立同時切換到新分支 :
git checkout -b 新分支名 [分支起點]
- 合併分支到master分支 :
git checkout master
git merge 要被合併的分支名
,合併過程中如果發生衝突則需要自己手動解決衝突,然後再提交。有衝突時,Git會顯示哪個檔案有衝突,並在衝突的檔案中加上特殊的識別符號號,解決完衝突後,要手動去掉這些被新增的識別符號號。如果衝突比較複雜的話,最好使用其他工具來協助,通過git mergetool來啟動。衝突一般是在不同的分支上對同一檔案的同一位置內容進行了改動,並已提交到倉庫中,這樣在合併的時候就會發生衝突。
- 刪除已經被合併過的分支 :
git branch -d 要刪除的分支
名,如果分支沒有被合併過,該命令會執行失敗
- 刪除分支,不管有沒有被合併過 :
git branch -D 要刪除的分支名
- 用圖形介面檢視分支提交歷史 :
gitk
充分利用好分支,可以幫助我們進行很好的版本控制與管理,如何用好分支其實是門藝術。
基於分支的版本控制模型有一篇文章進行了很好的闡述。
A succeddful Git branching model
中文翻譯:Git分支管理是一門藝術
9. 標籤的新增、刪除、檢視
標籤可以在需要的地方,為某個提交物件建立別名,這樣以後我們就可以通過標籤來檢視一些資訊,建立分支等。
- 檢視標籤 :
git tag
- 建立簡單的標籤 :
git tag 標籤名
- 建立附加資訊的標籤 :
git tag -a 標籤名 -m '附加資訊'
- 通過標籤檢視資訊 :
git show 標籤名
- 刪除標籤 :
git tag -d 標籤名
10. 與遠端倉庫的互動
Git相比其他版本控制軟體的一個優點就是大多數的操作都可以在本地進行,而不用管遠端的倉庫,因為操作是在本地,且操作的資料也是在本地,所以執行的速度就會比較快。 在多人協作的專案中,就需要涉及與遠端倉庫互動的問題,主要是如何從遠端倉庫抓取最新資料合併到自己的本地分支上,將自己的最新成果分享給其他人或讓別人審查等 。
- 檢視本地已經新增的遠端倉庫 :
git remote
僅顯示已新增的遠端倉庫名,git remote -v
可以一併檢視遠端倉庫的地址
- 在本新增遠端倉庫 :
git remote add 遠端倉庫名 遠端倉庫地址
- 刪除本地新增的遠端倉庫 :
git remote rm 遠端倉庫名
- 重新命名遠端倉庫名 :
git remote rename 原名 新名
- 克隆遠端倉庫到本地 :
git clone 遠端倉庫地址 [克隆到指定資料夾]
- 從遠端倉庫抓取最新資料到本地但不與本地分支進行合併 :
git fetch 遠端倉庫名
- 從遠端倉庫抓取最新資料並自動與本地分支進行合併 :
git pull 遠端倉庫名 本地要合併的分支名
- 將本地倉庫推送到遠端倉庫中 :
git push 遠端倉庫名 本地分支名
- 檢視遠端倉庫資訊 :
git remote show 遠端倉庫名
- 將標籤推送到遠端倉庫 :
git push 遠端倉庫名 標籤名
, 預設Git是不會將標籤推送到遠端倉庫的
11. 檢視所有分支的所有的commit和reset操作記錄(包括已刪除的commit記錄)
通過git reflog
可以幫助我們獲得將工作目錄恢復到某個狀態所需的ID(可以用HEAD@{數字}來表示對應的ID)。
12. 撤銷操作和版本回溯
有時候,由於我們的誤操作,產生了一些錯誤,我們發現後希望能夠及時糾正這些因為誤操作而產生的結果,將工作目錄恢復到某個正常狀態。
- 撤銷檔案暫存,但還沒有提交的檔案:
git checkout -- filename
或git reset HEAD
,修改的檔案會被恢復到上次提交時的狀態,修改的內容會丟失
- 版本回溯 : [方法1] 根據分支或者標籤將工作目錄恢復到指定版本 :
git checkout 分支名或標籤名
; [方法2] 先通過git reflog
找到某個版本的commit-ID,然後用git reset --hard commit-ID
將工作目錄的檔案恢復到指定的版本
- 恢復工作目錄中被刪除的檔案 (檔案之前被提交到倉庫中):
git checkout -- filename
或 git checkout -f
或 git ls-files -d | xargs git checkout --
13. 備份工作目錄
git stash
git stash list
git stash apply
git stash pop
git stash clear
如果正在一個develop分支上正在開發新功能,但這時master分支(穩定版本)突然發現了bug,並需要及時修復,而develop分支此時的工作還沒有完成,且不希望將之前的工作就這樣提交到倉庫中時,這時就可以用git stash來暫時儲存這些狀態到Git內部棧中,並用當前分支上一次的提交內容來恢復工作目錄,然後切換到master分支進行bug修復工作,等修復完畢並提交到倉庫上後,再使用git stash apply [stash@{0}]
或者git stash pop
將工作目錄恢復到之前的狀態,繼續之前的工作。
同時也可以多次使用git stash
將未提交的程式碼壓入到Git棧中,但當多次使用’git stash’命令後,Git棧裡將充滿了未提交的程式碼,這時候到底要用哪個版本來恢復工作目錄呢?git stash list
命令可以將當前的Git棧資訊列印出來,我們只需要將找到對應的版本號,例如使用git stash apply stash@{1}
就可以用版本號為stash@{1}的內容來恢復工作目錄。
當Git棧中所有的內容都被恢復後,可以使用git stash clear
來將棧清空。
14. 二分查詢
git bisect
15. 垃圾回收
git gc
16. 將當前工作目錄檔案壓縮歸檔(不包括.git目錄)
git archive --format=zip -o arch.zip HEAD
或 git arch --format zip head>arch.zip
17. 跟上游分支同步
git rebase 上游分支名
假設master和develop是一個專案的兩個分支,其中master是主分支,develop是從master而來的開發分支,如果在develop分支上提交過2次,之後又切換到master分支,做了一些修改並提交2次,這時,如果想將master分支的最新修改內容合併到develop分支,但同時也不能影響master分支時,就需要使用git rebase了,這時的上游分支為master。
18. 檢視commit的次數
git shortlog -s -n
會顯示出總的提交次數。
19. 檢視倉庫中commit物件、tree物件和blob物件
在我們將檔案提交到Git倉庫後,我們可以通過每次的commit物件的ID來檢視檔案快照的內容。
具體的方法就是:
-
先通過
git log
檢視提交歷史,選擇需要檢視的commit-id
-
git cat-file -t id
可以知道擁有該ID的物件是屬於哪種型別:commit、tree、blob
-
git cat-file commit id
可以檢視到該commit物件指向的tree物件的ID
-
git ls-tree tree-id
可以檢視該tree中的blob物件的ID和其他tree物件的ID(如果有)
-
git cat-file blob blob-id
20. 檢視倉庫中index檔案
通過git ls-files --stage
可以檢視當前分支的index檔案中有哪些檔案,它列出了檔名及對應的blob物件的ID。
21. 檢視倉庫目錄結構
find
可以列出.git目錄下所有目錄和檔案,這樣就可以清楚地知道當前倉庫的目錄結構。
22. 檢視檔案的修改歷史
git blame filename
可以列出該檔案每次被修改的時間和內容。
23. 常用的linux命令
- 建立資料夾
mkdir
- 刪除資料夾
rmdir
- 檢視檔案列表
ls
- 檢視檔案內容
cat
- 回顯 和 管道命令
echo "hello" >> file.txt