![](/img/trans.png)
[英]How do I clean all git history and blobs of files not currently present in HEAD with BFG
[英]git: How to remove *all* files from the git history that are not currently present?
我看過幾篇關於如何從所有 git 歷史記錄中刪除單個文件的文章和問題。 示例: 如何從 Git 存儲庫中的提交歷史記錄中刪除/刪除大文件?
我想做的是刪除所有當前不存在於主分支頭部的文件。
我的用例是我從一個整體存儲庫(稱為monolith
)中分離出一個較小的存儲庫(稱為small
)。 我想在創建small
時保留 git 歷史記錄,但只保留相關的 git 歷史記錄。
首先,我在 GitHub 上創建了一個新的small
存儲庫。 然后,在我的筆記本電腦上,我將它作為一個名為origin-small
的遠程文件添加到我的本地monolith
存儲庫中,並將單體的 master 分支的當前monolith
推送到origin-small
。
然后我從monolith
中刪除了遠程origin-small
,更改了目錄,並從 GitHub 中克隆了small
。 瞧,我有一份原始存儲庫monolith
的副本,其中包含完整的歷史記錄。
但是,在small
的歷史記錄中有大量文件不再相關,並且它們正在使 repo 膨脹。
我想做的是:
small
的 . 有沒有辦法用一個命令來做到這一點? 或者我是否需要為要刪除的每個文件/目錄運行一次git filter-branch
?
列出舊提交中存在的所有文件。
git rev-list HEAD | sed 1d | xargs -i git ls-tree -r {} --name-only | sort -u
列出所有存在於頭部的文件。
git ls-tree -r HEAD --name-only | sort -u
獲取頭部不存在的文件(參考)。
files=$(comm -23 <(git rev-list HEAD | sed 1d | xargs -i git ls-tree -r {} --name-only | sort -u) <(git ls-tree -r HEAD --name-only | sort -u))
用空格替換不可見字符(我猜是換行符),否則會導致git filter-branch
出錯。
lostfiles=$(echo $files | sed -e 's/\s/ /g')
從歷史記錄中刪除lostfiles
:
git filter-branch -f --tree-filter "rm -rf ${lostfiles}" --prune-emtpy
可以將它們組合成一個命令,但我不知道是否會有任何性能問題,所以我更喜歡單獨的命令。
我最終使用了git-filter-repo
:
安裝git-filter-repo
。
brew install git-filter-repo
以鏡像形式克隆您想要的存儲庫。
git clone --mirror <my-repo>
分析 repo 以識別歷史記錄中的所有文件,但不再存在。
git filter-repo --analyze
在分析目錄中,打開 output 列出 git 歷史記錄中的所有文件,但不再存在。 刪除標題和前兩列,以便只保留路徑。
code./filter-repo/analysis/path-deleted-sizes.txt
清除所有不再存在的文件的 git 歷史記錄。 這還將清理臟提交,刪除空提交,並為您重新壓縮所有內容。
git filter-repo --invert-paths --paths-from-file./filter-repo/analysis/path-deleted-sizes.txt
強制將所有引用推送到原點。 它會強制推送,即使命令沒有指示它。 此外,它會更新遠程上的所有分支,這很方便。 如果您在 GitHub/Bitbucket/etc. 中的某些分支上啟用了分支保護,那么您將需要允許強制推送。 如果您發現無法強制推送某些 ref,您可以隨時重新運行此命令。
git push
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.