對於所有的開發者來說,掌握一門程式碼版本控制系統都是必須的,無論是自己做專案,團隊合作,工作中的合作,都離不開版本控制系統的幫助。然而目前大多數初學的開發者還不瞭解或者還停留在幾個常用的指令,那麼毫無疑問是不夠的。詳細的瞭解 Git 和如何高效的使用 Git 是這篇文章要說的。
兩種主要的版本控制系統
版本控制系統主要分為兩個型別:集中式和分散式。相信現在還有不少的公司或團隊選擇的版本控制系統是 svn
,svn就是一個典型的集中事版本控制系統。而 Git 則是一個分散式版本控制系統。
什麼是集中式版本控制系統
集中式版本控制系統需要一臺伺服器作為中央伺服器,這個伺服器充當我們的完整版本庫,我們的其他開發者必須聯網才能使用版本控制系統向我們的中央伺服器提交程式碼和下載程式碼,所有開發者都是對同一個 完整版本庫 進行操作。
什麼是分散式版本控制系統
在分散式版本控制系統中,每一個開發者的電腦都可以作為一個完整版本庫,無論是否聯網開發者都可以向程式碼庫進行提交修改等操作,通常情況下需要藉助一臺伺服器以方便大家交換程式碼,所有開發者將自己的完整程式碼庫與伺服器進行同步來進行程式碼的交換。
分散式版本控制系統的優勢
分散式版本控制系統的優勢在於開發者無論是否聯網,都可以進行工作,將修改提交到自己的完整版本庫中。同時每個開發者都擁有這個完整版本庫,所以也不必擔心因中央伺服器出問題而導致所以人都無法工作。而且git的分支切換等操作是基於指標位置的移動,所以效能高。
Git 程式碼庫的分割槽
在本地資料夾下初始化一個git倉庫後,這個倉庫存在三個分割槽:工作區,索引區和資料庫。
- 工作區: 是我們實際操作的區域,也就是說,我們開發時,看到的都是工作區的程式碼,任何的修改都是對工作區的直接修改。
- 資料庫: 則是我們的完整版本庫,它儲存我們對程式碼的最終修改,也是程式碼最終的結果。
- 索引區:工作區和資料庫之間存在著一個索引區,它是為了向資料庫提交作準備的區域。
基本的操作
初始化倉庫:
git init
複製程式碼
將工作區的修改新增到索引區:
git add <filename>
複製程式碼
將修改的檔案新增到索引區,可以通過萬用字元 “*” ,或“.”來進行批量的操作:
git add file1 file2 file3 // 將指定的多個修改檔案新增到索引區
git add *.txt // 將所有txt檔案新增到索引區
git add . // 將所有的檔案新增到索引區
複製程式碼
將索引區中的內容新增到資料庫
git commit -m "本次提交的資訊"
複製程式碼
這樣我們就完成了一次完整的修改和提交。
status 和 log
$ git status
On branch master
Your branch is up to date with `origin/master`.
nothing to commit, working tree clean
複製程式碼
可以檢視當前的狀態,比如處於哪一個分支,是否有修改未提交,哪些檔案被修改了等等的資訊。
git log
複製程式碼
可以檢視到目前為止的所有的提交記錄,它會顯示每一個提交的使用者、時間、提交資訊。
分支(branches)
在 Git 中分支的本質其實是一個指向最新提交的指標,建立不同的分支實際就是建立了多個指標。每一個分支互不影響,可以平行的進行開發,負責不同的任務。
建立新分支,比如新建名為test的分支:
git branch test
複製程式碼
切換分支,進入test分支:
git checkout test
複製程式碼
合併分支,在master分支中將test分支的修改合併進來:
// 在master分支中
git merge test
複製程式碼
刪除分支test
git branch -d test
複製程式碼
遠端倉庫
克隆與關聯
前面提到了所有開發者將自己的完整程式碼庫與遠端倉庫進行同步來進行團隊合作開發,
通過以下命令克隆或者說下載遠端倉庫到自己的電腦:
git clone [repository url]
複製程式碼
克隆後可以得到一個與遠端倉庫關聯的本地倉庫。也可以通過以下命令來直接關聯遠端倉庫:
// 將指定地址的遠端資料庫關聯,並命名為origin
git remote add origin [repository url]
複製程式碼
顯示遠端資料庫列表,如:
$ git remote
origin
複製程式碼
推送內容與分支修改
向遠端倉庫推送修改,比如將本地master分支程式碼推送到遠端倉庫的master分支:
git push -u origin master
複製程式碼
第一次提交的時候通常帶上引數 -u
,它的作用是記錄這次操作的遠端倉庫地址等資訊。那麼我們使用例如 git pull 等命令時後面就不需要再加上對於的分支地址了。不是第一次提交的話可以省略 -u
。
刪除本地某分支後,同步遠端資料庫,刪除遠端資料庫上的此分支:
git push origin --delete <分支名稱>
複製程式碼
想將標籤也推送到遠端資料庫:
git push origin --tags
複製程式碼
拉取內容與分支修改
將遠端倉庫分支的最新變化拉去下來,併合併到自己的程式碼中:
git pull origin <遠端倉庫分支名稱>
複製程式碼
預設情況下,git pull 不會同步遠端資料庫刪除的分支,加上引數-p
可以在本地刪除遠端資料庫中已經刪除的分支:
git pull -p
複製程式碼
將遠端的資料庫的變化提取下來檢視,但不合並到當前自己的程式碼中:
git fetch <遠端資料庫名稱> <分支>
複製程式碼
這樣會將遠端的變化提取到本地,在本地可以通過切換到”遠端資料庫/分支”來進行檢視,比如檢視遠端master分支的修改:
git checkout origin/master
複製程式碼
可以通過git branch指令與隊友引數檢視所有分支:
// 檢視本地和遠端所有分支
$ git branch -a
* master
remotes/origin/master
// 檢視遠端所有分支
$ git branch -r
origin/master
複製程式碼
標籤操作
標籤分為兩種:
- 輕量標籤
- 註解標籤
輕量標籤通常作為臨時標籤方便我們的開發,註解標籤通常為上線的程式碼標記版本資訊,可以通過以下指令建立一個輕量標籤:
git tag <標籤名稱>
複製程式碼
還可以給標籤新增資訊備註來建立一個註解標籤
git tag -a <標籤名稱> -m "備註資訊"
// 比如:
git tag -a v1.0 -m "first version"
複製程式碼
可以通過以下指令檢視已有標籤:
$ git tag
v1.0
複製程式碼
加上引數 -n
可以連備註一起檢視:
$ git tag -n
v1.0 first version
複製程式碼
刪除分支:
git tag -d <分支名稱>
複製程式碼
實際開發中運用標籤
我們想檢視某個標籤的內容:
git checkout <標籤名稱>
複製程式碼
這樣就可以進入到當前分支中的對應標籤中,但是這隻能檢視標籤的內容。
如果你想基於該標籤繼續進行開發,那麼應該先基於該標籤新建一個分支,在新分支上進行開發,然後再合併。
git branch <分支名稱> <標籤名稱>
複製程式碼
這樣就可以基於某一版本並行的開發。
進階操作
覆蓋或修改最近的提交
有時候我們想要用當前的提交去覆蓋上一次的提交,避擴音交歷史中存在多餘的提交歷史,我們可以使用 --amend
引數:
git add <檔名>
git commit --amend -m "新的commit備註"
複製程式碼
通過
git log
複製程式碼
檢視提交記錄可以發現此次提交替代了上一次的提交。
取消上一次的提交(版本回退)
有時候我們需要取消上一次的提交,那麼我們可以通過 reset 指令修改 HEAD 指向的位置來實現:
git reset --hard HEAD~
// ~的數量表示取消提交的數量,如果要取消強兩次提交的話可以改為 HEAD~~
複製程式碼
可以通過檢視檔案內容或檢視git日誌的方式來檢視是否成功取消了修改。
這裡的hard
模式的意思是:索引區和工作去都會受到影響,回退到對應的內容。除此之外還有其他的模式:
- –soft:僅HEAD的指向退回到對應位置,索引區和工作區內容不變。
- –mixed:HEAD位置和索引區內容傳送改變,工作區不變。
- –hard: HEAD位置和索引區和工作區內容都傳送改變。
版本恢復
如果我們版本回退後後悔了想恢復到最新版本怎麼辦?可以通過commit id來進行移動。
git reset --hard <對應的 commit -id>
複製程式碼
如果我們沒有記住對應的 commit id 怎麼辦?可以通過 git reflog 指令來檢視命令歷史。
$ git reflog
9154108 (tag: v1.1, tag: v1.0, origin/master, master) HEAD@{12}: pull: Fast-forward
1319463 HEAD@{13}: checkout: moving from 9154108ced0df7f7c220bc5440af008aff330e92 to master
9154108 (tag: v1.1, tag: v1.0, origin/master, master) HEAD@{14}: checkout: moving from master to origin/master
1319463 HEAD@{15}: commit (initial): first commit
複製程式碼
這樣就可以看到每次提交操作對應的 id(第一列) 了,那麼我們想移動到哪個版本都可以了。