Git 子模組問題
問題描述
在 GitHub 上查看專案時,發現前後端子目錄(voting-system-be
和 voting-system-fe
)顯示為特殊的連結圖示,而非普通資料夾。點擊這些連結後無法正常訪問內容。

問題原因
這種情況發生是因為這些子目錄被設定為 Git 子模組(submodules)。子模組是 Git 的一個功能,讓你可以在一個 Git 儲存庫中包含其他 Git 儲存庫。
當我們一開始將前後端專案 clone 到總專案目錄中時,實際上建立了子模組引用,這些引用指向前後端專案的特定 commit(預設分支上的最新 commit,通常就是 main 或 master 上的最新 commit)。這導致:
前後端專案各自更新後,總專案不會自動更新
這些子目錄中有自己的 .git 目錄,所以在總專案中修改前後端程式碼時,這些變更不會被總專案的 Git 追蹤
解決方案
有兩種解決方法:
方法一:正確初始化和使用子模組
如果希望保持子模組結構(前後端各自獨立版控,同時總專案可以引用它們),需要正確初始化和更新子模組:
# 初始化子模組
git submodule init
# 更新子模組,拉取對應的實際內容
git submodule update
後續要更新子模組時,可以使用:
# 更新所有子模組到遠端最新版本
git submodule update --remote
方法二:將前後端程式碼移出主儲存庫,用腳本管理
如果不想使用子模組功能,而是將前後端程式碼直接從總專案中移除:
# 刪除子模組引用
git rm --cached voting-system-be
git rm --cached voting-system-fe
# 如果存在 .gitmodules 檔案,也需要刪除對應項目
# 然後添加以下到 .gitignore
voting-system-be/
voting-system-fe/
注意:執行第二個方法後,前後端目錄會從檔案系統中消失,因為它們是作為子模組引用而非實際檔案存在的。不過不用擔心,可以再次 clone 前後端專案把程式碼拉回來,也可以透過腳本來執行 clone。

子模組操作的額外說明
添加子模組
git submodule add <儲存庫URL> <本地路徑>
例如:
git submodule add https://github.com/your-org/voting-system-be.git voting-system-be
克隆包含子模組的專案
# 克隆主專案
git clone <主專案URL>
# 初始化和更新子模組
cd <主專案目錄>
git submodule init
git submodule update
或者一步完成:
git clone --recursive <主專案URL>
更新特定子模組
cd <子模組目錄>
git pull origin main
cd ..
git add <子模組目錄>
git commit -m "更新子模組"
刪除子模組
完整刪除子模組的步驟:
# 1. 取消暫存子模組路徑
git rm --cached <子模組路徑>
# 2. 刪除子模組相關目錄
rm -rf <子模組路徑>
# 3. 刪除 .gitmodules 中的相關部分
# 編輯 .gitmodules 檔案,移除該子模組的區段
# 4. 刪除 .git/config 中的相關部分
# 編輯 .git/config 檔案,移除該子模組的區段
# 5. 刪除 .git 目錄中的子模組目錄
rm -rf .git/modules/<子模組路徑>
# 6. 提交變更
git add .gitmodules
git commit -m "移除子模組 <子模組路徑>"
子模組優缺點
優點
可以在單一專案中管理多個獨立的程式碼庫
每個子模組都可以有自己的版本歷史和分支
主專案可以精確控制使用的子模組版本
適合前後端分離的專案架構
缺點
子模組不會自動更新,需要手動更新
操作較為複雜,需要團隊成員都了解子模組概念
容易造成混淆,特別是當子模組的改動需要同步到主專案時
子模組的目錄結構改變時可能會導致問題
Last updated