Git 如何不再追蹤 Tracked Files

今天的例子比較特殊,因為 Android 的原始碼在編譯的過程中修改了一些檔案,這些檔案不能被刪除,它們屬於原始碼的一部分,但是我們必須避免因為編譯而被修改的部份進入到 Git 歷史裡面。換句話說,這些檔案在原始碼裡面是永遠不能改變的,每次從遠端 repo sync 下來都必須是原版,只有編譯之後才會依編譯情況而改變,這要怎麼解決呢?

參考資料:
[Git-Scm]Git-Hooks
[DigitalOcean]How To Use Git Hooks To Automate Deployment Tasks 

需求:
讓 Tracked files 存在於目錄,但任何修改都不再被 Git 追蹤。

Android 原始碼本身就是由 Repo 和 Git 來管理,剛好在這兩個工具相互合作的情況下,找到了一個方法,就是 Git Hook 加上 Repo 的 Linkfile 功能,可以達到上方描述的需求,如此一來可以避免我們不小心將不必要的修改 Commit 進去。

方法:
設定 Repo 參數,使其 Sync 完成的同時,觸發 Git hook: post-checkout 執行特定指令。

步驟1:
將不想再被追蹤的檔案加入 .gitignore。

疑?.gitignore不是僅適用於尚未被追蹤的檔案嗎?沒錯,如果是 Tracked files,必須再執行 git update-index --assume-unchanged 這行指令,在本地端才會生效,為什麼說本地端呢?因為只要刪除整個目錄,重新 repo sync 一次,那些被加入 .gitignore 的 Tracked files 仍然會被追蹤!所以我們需要繼續下面步驟。

  •  Untracked file => 加入即生效
  •  Tracked file => git update-index --assume-unchanged

步驟2:
在專案裡新增目錄 hooks,在 hooks 目錄內新增檔案 post-checkout,然後 git add; git commit; git push......,post-checkout 內容如下所示。

#!/bin/sh
exec git update-index --assume-unchanged FileName
echo "update-index"
exit 0

步驟3:
修改 .repo/manifests/default.xml,並且 git add; git commit; git push......

<project name="test" path="test">
  <linkfile dest=".repo/project-objects/test.git/hooks/post-checkout" src="hooks/post-checkout" />
</project> 

步驟4:
為了能夠觸發 post-checkout,必須在執行 repo sync 時加上參數 -d (detach),這個參數會將 Project 切換至 Manifest 所指定的 Revision,我的猜測是它執行了 git checkout 的動作,因此能夠符合 post-checkout 所需的條件。

測試結果:

從測試結果來看,這樣的方法可以達成我們的目標,雖然目前還沒發現問題,但我不能保證沒有其他副作用,所以......僅供參考!

留言

這個網誌中的熱門文章

程式語言常用之符號與詞彙 - 中英文對照

Repo 實用指令

什麼是 Bootloader?