Git Worktree:解決分支依賴衝突的問題

entronad發表於2018-08-01

git worktree 命令可在不同資料夾中開啟同一個 git 倉庫的不同分支,很好的解決不同分支 node_modules 依賴衝突的問題。

將一個專案不同平臺的版本放在 git 倉庫的不同分支,是一種常見的做法。比如我最近在考慮開發 Gitview (專案連結 )的小程式版,計劃將原先 React Native 版的程式碼放到名為 react-native 的分支,小程式版在一個新的名為 weixin 的分支中開發,master 分支中將只放簡介和各分支的索引連結。

由於 node_modules 資料夾是在 .gitignore 之中的,git 不會對其有任何記錄或操作,因此不同分支不會有自己獨立的 node_modules,使用 git checkout 命令切換時,專案裡還是同一個 node_modules 資料夾。

此時在各分支直接執行 npm install 的話,各分支 package.json 中對應的依賴都會被放到同一個 node_modules 資料夾。如果同一個依賴不同分支的版本不一致,則會衝突覆蓋,發生問題。

類似問題還會出現在以下場景:

  • 你想將專案的 react 版本從 15 升級到 16 ,並嘗試使用一些 16 的新特性,因此建立了一個新的分支,但在這期間,你還要在原分支上維護老版本的專案,互相切換時 react 版本會衝突覆蓋
  • dev 分支中是全新的內容,但你有些程式碼片段希望從原來的 master 分支直接拷貝,互相切換後看不到其它分支的程式碼

以上問題,究其原因是 git checkout 命令是在同一個資料夾中切換不同分支。

怎麼解決呢,一個思路是不同的分支 clone 到不同的資料夾,但這樣就是相互完全獨立的倉庫了,不能merge。

那有沒有辦法能在不同的資料夾中開啟同一個倉庫的不同分支呢,這就要介紹今天的主角:git worktree 命令了:

git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]
git worktree list [--porcelain]
git worktree lock [--reason <string>] <worktree>
git worktree move <worktree> <new-path>
git worktree prune [-n] [-v] [--expire <expire>]
git worktree remove [-f] <worktree>
git worktree unlock <worktree>
複製程式碼

每個命令詳細的介紹請看文件(連結 ),下面以對 Gitview (專案連結 )改造為例進行講解:

原本 Gitview 只有一個 master 分支,為 React Native 版本的程式碼,本地倉庫為 gitview 資料夾,現在希望將 React Native 版本的程式碼移動到 react-native 分支,新建 weixin 分支進行小程式開發,master 分支作為索引。

改造步驟如下:

  1. 將 gitview 資料夾的全部內容移動到 gitview/gitview-master資料夾
  2. 在 gitview-master 目錄下執行 git worktree add ../gitview-react-native -b react-native
  3. 在 gitview/gitview-react-native 目錄下執行 git push --set-upstream origin react-native
  4. 刪除 gitview/gitview-master 下除了 .git 資料夾的全部內容,再新增所需內容,並add、commit、push
  5. 在 gitview-master 目錄下執行 git worktree add ../gitview-weixin -b weixin
  6. 在 gitview/gitview-weixin 目錄下新增相應內容,並add、commit、push
  7. 在 gitview/gitview-weixin 目錄下執行 git push --set-upstream origin weixin

這樣 gitview 專案在本地和 GitHub 遠端都有了 master、react-native、weixin 三個分支,在本地三個分支分別被放置在 gitview/gitview-master、gitview/gitview-react-native、gitview/gitview-weixin 資料夾,但它們同屬一個倉庫,相互merge沒有問題,在對應資料夾下開啟 git bash 就是在對應的分支,無需通過 git checkout 命令。

注意在執行 git worktree add 的時候,不要將目錄指定在當前目錄下(./),而應該指定在當前目錄的同級目錄(../),否則新分支的資料夾又會被新增到原分支中。

使用 git worktree 建議將 git 升級到最新版本,因為其中的好幾個命令是最近幾個版本才加入的。事實上,git worktree 命令是2015年9月的2.6.0版本才推出的。這其中的原因個人認為可能是,在過去的程式語言中,專案的依賴庫不在專案目錄中, git checkout 不會遇到依賴不同的問題,而npm 管理的專案中,依賴被放在專案目錄中的 node_modules 資料夾中,故隨著前端開發和 npm 的興起,在不同資料夾中開啟不同分支愈發變成了剛需。

相關文章