[UE4] 如何使用git及git lfs來進行版本控制

本章節並不打算進行git的使用教學,對於不懂這套軟體運作機制的讀者可以很簡單的在其他地方找到更完整的教材。相對的,這個章節會專注於描述在使用git進行UE4專案開發時有哪些東西需要特別注意。

若是電腦沒有git,在Windows環境下請先下載並安裝下面二個網址中的檔案:

Git for windows為git的主程式,必須要先安裝,而TortoiseGit則是給git主程式使用的GUI介面,若已有偏好的軟體則可略過這步。

安裝完成後,在程式集中尋找並打開Git Bash這隻程式,輸入Figure 1.6.1中的指令檢查是否有正確安裝:

image

Figure 1.6.1 檢查git跟git lfs是否有正確安裝。

之後在Unreal Editor的Toolbar中選擇Connect to Source Control之後(見Figure 1.6.2),就會開啟設定視窗,如Figure 1.6.3。

image

Figure 1.6.2 啟用Source Control

 

image

Figure 1.6.3 Source Control設定視窗,先確認Add a .gitignore file這個選項有選取後,按下Initialize Project with Git之後,再按Accept Settings就可完成基本設定

在完成設定之後,我們會在專案目錄底下看到一個.git的資料夾以及.gitignore檔就代表我們已經設定成功。在.gitignore裡面描述的,是UE4官方所提供不該commit進到版本控制裡面的檔案跟資料夾。由於在.gitignore裡面列出來的都是可以由引擎方產生出來的,因此我們可以利用這個官方提供的初始化機制,讓我們可以省去設定.gitignore的步驟。

以下是官方預設在.gitignore的資料夾跟檔案清單:

  • Binaries
  • DerivedDataCache
  • Intermediate
  • Saved
  • *.VC.db
  • *.opensdf
  • *.opendb
  • *.sdf
  • *.sln
  • *.suo
  • *.xcodeproj
  • *.xcworkspace

雖然到這裡我們已經完成了基本的git repository設定,但由於UE4中的所有asset都是以binary的方式存在,而binary檔本身,其實並不適合存放在git裡面。為什麼呢?這是因為在專案經過的時間累積,repository大小由於需要包含所有歷史記錄中的檔案,因此就會變的非常耗費硬碟空間。

這不僅會造成git server在效能上的負擔,而且目前大多數的雲端git服務都會限制repository的大小。例如github推薦你的git庫需要維持在1GB以下,超過之後就會先寄信警告你;而bitbucket則更是直接限定不能超過2GB,一旦超過之後就再也沒辦法進行push。

你可以想像團隊中的每個人在開始開發專案之前,都必須要先用git下載幾十GB或幾百GB的情景嗎?最重要的是有些存在於過去幾個月前的檔案在開發時期根本就不需要。好在最近git lfs(git large file storage)這個概念逐漸成熟,它幫助你將指定的檔案存放在其他空間上,而在git repository本身就只保存著指向該檔案的指標,參見Figure 1.6.4。因此在進行git repository的clone或pull的時候,就只需要下載最新的檔案即可。

image

Figure 1.6.4 使用git lfs,原本的repository就只有儲存檔案hash與相關資訊而已。

那麼我們該怎麼啟用git lfs呢?首先要先確定lfs已經安裝見Figure 1.6.1,若尚未安裝完成,可以在這個網址找到:https://git-lfs.github.com/

然後在專案目錄下輸入以下幾個指令:

· git lfs install

· git lfs track “Content/**”

完成之後在專案資料夾下面可以看到.gitattributes這個檔案,打開該檔案可以看到裡面內容如下:

Content/** filter=lfs diff=lfs merge=lfs –text

在這裡,我們將Content目錄底下的檔案全部都列入lfs清單中。將該更動commit並push到你git遠端的service之後,就能夠自動使用到lfs的便利機制。

image

Figure 1.6.5 在成功啟用lfs之後,在做push的同時會有圖中標示的訊息出現,此畫面使用TortoiseGit進行push操作。

在完成git repository的建置之後,可以試著將一些常用的指令寫成script檔放在專案的根目錄。例如下面幾個git常用功能:

  • git_checkout_master.sh:主要用途是將目前專案跟底下的git submodule的內容全部checkout到mater branch並做pull。詳細指令如下:

git checkout -f master

git pull

git submodule foreach –recursive “git checkout -f master”

git submodule foreach –recursive “git pull”

  • git_clean.sh:用來將目前的專案跟底下的git submodule回復到剛clone下來的狀態,意即將一些暫存檔刪除。詳細指令如下:

git clean -xfd

git submodule foreach –recursive “git clean -xfd”

  • git_submodule_update.sh:初始化所有的submodule,並把所有的submodule切換 (switch/checkout) 到專案目前所追蹤的commit上。詳細指令如下:

git submodule sync –recursive

git submodule update –init –recursive

  • git_lfs_prune.sh:將git repo中所累積起來不需要的lfs檔案清除,只保留最新需要的檔案,見Figure 1.6.6。詳細指令如下:

git lfs prune

git submodule foreach –recursive “git lfs prune“

 

image

Figure 1.6.6 做完git lfs prune後,repository會清除掉過去的檔案只保留最新的一份,這對於硬碟容量有限的專案開發非常有用,例如專案放在SSD硬碟上,圖中使用這個操作後,釋放了143.6MB的硬碟空間。

當然,git lfs並沒有解決binary檔在做merge時的衝突問題,例如團隊中有二個人同時去操作同個binary檔案的話,那麼在做merge所產生的檔案修改衝突該怎麼解決?這時候,我們能做的就只是選其中一方的版本使用而已。又由於在ue4裡面所有的map跟uasset,例如blueprint或material,又全部都是沒辦法做merge的binary格式,因此在團隊的分工上就必須要特別留心。

在解決這個問題上,其他版本控制軟體,如svn跟perforce,都有將檔案作lock不讓別人修改的機制。這也是很多人不用git來進行binary檔案控管的原因,好在git lfs 2.0.0最近導入lock這個概念,雖然功能仍在前期測試,目前沒有也任何的GUI將這個功能整合進去,必須要手動輸入指令。但至少,在功能上是蠻完整的,可以持續關注之後的發展: https://github.com/git-lfs/git-lfs/wiki/File-Locking

詳細文檔:  https://github.com/git-lfs/git-lfs/blob/master/docs/proposals/locking.md

 

 

最後,下表整理了目前各類雲端服務的比較:

 

image

Leave a Reply

Your email address will not be published. Required fields are marked *