2017-06-08 89 views
0

以下是我用來重寫多個父存儲庫中引用的子模塊的歷史記錄的腳本。這在Windows環境中運行在Git bash中。重新編寫子模塊的git歷史記錄後,更新對父存儲庫中子模塊的引用

#!/bin/bash 

cd submodule_repo 

git filter-branch --index-filter 'git rm -q --cached --ignore-unmatch files_to_remove' \--tag-name-filter cat -- --all 

git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d 

git reflog expire --expire=now --all 
git gc --prune=now 

我需要的SHA一箇舊提交的某種方式映射到新創建的SHA S,這樣我就可以更新父庫相同的參考。有沒有辦法做到這一點?我確實看過Repository with submodules after rewriting history of submodule,但這並不是真正的幫助,因爲我正在更新原始參考文件,以確保我刪除的文件不會被任何機會重新打包。我對使用git比較陌生,所以任何指導都會非常感激。

編輯

繼公認的答案(由@torek)的評論部分中提到的步驟爲我工作。

回答

0

沒有好辦法做到這一點(至少在git filter-branch和現有的Git工具 - BFG離開所需的地圖文件,但仍然需要構建的東西)。

git filter-branch副本提交時,它將每個新提交的散列放入一個「映射文件」(配對舊和新ID--實際上是現有實現中的一個目錄,雖然這在大型過濾器中表現很差,所以它可能有一天會被修改),這樣就可以將原始提交哈希轉換爲重寫提交哈希。這是怎麼回事提供map功能the git filter-branch documentation指的是在這裏:

一個地圖功能是可用,接受一個「原始的SHA1 ID」的說法,並輸出「重寫SHA1 ID」如果犯已被重寫,否則「原始sha1 id」; 函數可以在單獨的行上返回多個標識符,如果您的提交過濾器發出多個提交。

不幸的是,當git filter-branch飾面和清理,它移除映射表中,而不是把它變成一個有用的數據庫。如果你的數據庫中有映射,你可以將它用於任何外部項目(其他存儲庫,測試框架或其他可能已保存的地方的「gitlink」條目)。沒有地圖,沒有好辦法來處理這個問題。超級項目說,例如,「使用提交1234567」,但該提交在重寫的子模塊存儲庫中不再存在。新提交的ID 在地圖上是,但沒有地圖。

+0

謝謝@torek這是令人失望的:(應該有一個選項來保留或放棄地圖一旦過濾器分支完成,將在這種情況下非常有用。任何解決方法,我可以用來手動創建地圖? –

+0

最簡單的方法就是修改過濾分支代碼,這是一個shell腳本,所以修改起來非常簡單,只需找到刪除臨時目錄的地方,然後讓它對地圖進行一些有用的操作即可保存。 – torek

+0

已經有一段時間了,但現在我又回到了這個任務,所以我使用了'$ GIT_COMMIT'變量,如[這裏]所述(https://stackoverflow.com/questions/14782906/how-do-i-get- ),並創建了地圖作爲filter-branch的一部分,它似乎正確地填充地圖(所有我的修改提交在地圖中註冊)以及舊的提交。 –