在開發工作中,大家估計都遇到過這樣的需求:正在開發的東西不想動,但是需要一個完整工作目錄來做測試或者搞一些其他事情。一般來說可以拉個分支,用git stash保存目前的工作區狀態,等搞完事情再切回來。但是如果需要兩個或者更多個工作區同時搞事情上面的方案就不行。這時候當然可以git clone幾個完整倉庫副本來搞,但是也很麻煩費事,而且倉庫的同步也是個問題。有沒有更好的方法呢?在次之前我是不知道的,知道我發現了git的一個新的屠龍技——git worktrees工作樹功能。今天蟲蟲就給大家介紹這個新的鮮爲人知的萬人需屠龍秘籍。
概述
Git worktree嚴格意義上說已經不是一個新的功能了,它推出也已經好幾年了,是在2015年7月發布的2.5版引入的。Worktree是鏈接到統一倉庫的多個工作區(目錄,樹)。一個git倉庫可以支持多個工作樹,分別對應不同的分支。我們在git中通過"git init"或"git clone"創建一個(主)工作區(樹)(main working tree)。
同理,我們使用git worktree創建一個(和工作區)不同目錄的工作區(樹),我們稱之爲爲"鏈接工作區(樹)(linked working tree)"。git倉庫有一個主工作樹(裸庫)和零個或多個鏈接工作樹。與重建的孤立的目錄不同,鏈接工作樹和主倉庫直接就行分支一樣是有機關聯的,任何一個鏈接工作樹的變更提交都在倉庫內部。鏈接工作樹用完後,可以直接通過git worktree remove刪除。
基本用法
add
工作樹的創建和創建新分支一樣簡單而高效。運行下面的格式創建工作樹:
git worktree add ../工作樹目錄 分支(commits ID)
該命令就會在../工作樹目錄下,創建一套完整分支工作區。該目錄可以任意指定,但是最好在主倉庫目錄之外,免得汙染倉庫。然後就可以在該目錄下檢出分支,向上遊推送,等等。
如果分支不存在,則可以用-b操作,可以新建分支並使這個新分支關聯到工作樹。
list
list功能會列出每個工作樹的詳細信息。首先列出主工作樹,然後列出每個鏈接工作樹。輸出詳細信息包括工作樹是否爲裸樹,工作樹對應git commit哈希以及對應的分支(如果沒有,則爲分離的HEAD)。
list功能有一個–porcelain 選項,可以列出更完整的哈希值和分支信息
lock
如果工作樹目錄位于便攜式設備或網絡共享上,請使用lock對其進行鎖定,以防止其管理文件被自動刪除。這也可以防止其被移動或刪除。
move
將工作樹移動到新目錄。請注意,不能移動包含子模塊的主工作樹或鏈接的工作樹。比如我們執行:
git worktree move alpha ../a
對未操作以前變化:
prune
清楚$GIT_DIR/worktrees中的工作樹信息。
remove
前面提到過,用戶刪除工作樹。注意:該命令只能刪除幹淨的工作樹(沒有未跟蹤的文件,也無法對跟蹤的文件進行任何修改)。不幹淨的工作樹或帶有子模塊的樹需要使用–force刪除。主工作樹無法刪除。
unlock
對鎖定工作中的樹,解鎖,解鎖後就可以對其進行prune、move或者remove等操作。
工作樹的作用
那麽用工作樹可以搞什麽事情呢?這兒就介紹介紹工作樹的作用。
在另一個分支上工作時運行測試
在具有非常好的測試覆蓋範圍的大型項目中,運行某組測試套件可能需要很長時間,與其浪費時間死等,不如多拉幾個工作樹並行運行多個測試套件。許多IDE都允許一次打開多個項目,但每個項目必須位于自己的目錄中。我們可以git克隆兩個完全獨立的存儲庫,但是工作樹更完美:
工作樹是使用硬鏈接實現的,因此它們既輕巧又快速。
可以在工作樹之間共享更改(只要它們將其提交到本地存儲庫)。對于克隆,必須先推送到遠程庫,在git pull來同步。
如果不小心clone的副本提交錯誤的提交了變化,則必須手工(如果很簡單)或使用修補程序遷移變更。而使用工作樹,只需要使用git cherry-pick和git reset即可修複錯誤。
通常做法是爲運行測試保留一個額外的工作樹。但是工作樹有一個限制就是一個分支只能拉一個工作樹。可以通過創建臨時分支來解決這個問題,如下所示:
git checkout -b TEMP/branch feature/branch
此處使用TEMP前綴來強調該分支是臨時的。當在原始分支上提交更改時,可以方便的使用git merge feature/branch同步分支。
比較多個版本
有時,需要比較一個項目的某兩個版本,但僅用diff無法做得到。可能需要同拉兩個版本逐個比對,甚至需要同時運行本。或者一個複雜的功能恰好寫了一半,無法確定從那個地方做標記對比,這時可以通過先前的版本或者任何commit提交來拉工作樹操作。
在其他分支上工作,而不會影響當前的工作副本
也許我們需要在其他分支上工作,但是當前的工作目錄混亂不堪,也無法使用git stash來保存狀態。根據項目的不同,切換分支有可能還會産生不良的副作用(例如,導致IDE重新生成索引)。這時候就只能使用工作樹來解決。
使用工作樹快速驗證項目
每個人都可能遇到過構建失敗的經曆,可能是因爲你搭檔忘記提交一些必須的配置或.gitgnore設置的太寬泛了等等。而代碼可以很好的在它的電腦上運行,到你這就挂了,則可能是由于可能缺少某些文件。這時候就可以使用工作樹拉一個幹淨的副本做測試驗證所有需要包含都已經添加了。只有從創建新工作樹開始,才能可靠地工作。
限制
不能多個工作樹對應同一個分支
前面提到了過了,這是工作樹的一個限制,只需拉一個臨時分支就ok。
不適用于子模塊
目前使用子模塊的存儲庫無法利用工作樹。
總結
本文給大家介紹了一個非常實用的git功能——工作樹。該功能簡練而好用,絕對是一個人見人愛,人見人用的五星級好功能。猶豫什麽呢,先用先受益!