[英]Git - Removing files from a branch's history
我有一個當前正在開發的本地存儲庫,我想在 GitHub 上公開共享(部分)它。 到目前為止我所做的:
git checkout dev # dev is the current development branch of my local repository
git branch public # create a new branch from dev for the public repo
git checkout public
git remote add public git@github.com # add the public repo as a new remote
git push -u public public:master # push local 'public' branch to 'master' branch of 'public' remote
但是,這次推送失敗了,因為我的存儲庫包含一些相當大的子目錄。 所以我開始清理它:
git rm -r --cached external # remove large subdirectory 'external'
git rm -r --cached ... # repeat for other large subdirectories
然后我將上述所有子目錄也包含在.gitignore
中並提交。 對git ls
的調用現在僅顯示少量文件,其組合大小最多為幾 MB,對git status
的調用顯示沒有未提交或未跟蹤的文件。 然而git push
仍然失敗,顯然是因為大的子目錄仍然包含在分支的歷史中。
從歷史記錄中清除文件的正確方法似乎是使用git filter-branch
命令,但是該命令附加了很多警告,我不想在此過程中弄亂我的整個存儲庫。 我如何正確清除我上面用git rm
從public
分支(只有public
分支)的歷史記錄中刪除的子目錄(並且只有子目錄)?
由於該分支不太可能合並回其他分支,因此作為最后的手段,我也可以簡單地從中刪除所有歷史記錄。 其他分支仍應保持原樣,但是
從某種意義上說,分支在 git 中並不真正存在:它們只是指向特定提交的指針,並從那里指向導致該提交的歷史記錄。 因此,您的存儲庫可能看起來像這樣,示意性地:
+-- E --- F <- main branch
/
A --- B --- C --- D
\
+-- G --- H <- public branch
如果大文件存在於提交 A、B、C 和 D 中的任何一個中,那么根據定義,它們存在於主分支和公共分支的歷史記錄中。
要重寫歷史記錄,您必須創建新的提交,直到這些文件首次添加時。 您可以使用git-filter-repo工具執行此操作,如下所示:
git filter-repo --invert-paths --path '/directory/to/delete' --refs public
讓我們假設文件首先在提交 B 中添加; 我們現在可能有這樣的事情:
+-- B --- C --- D -- E --- F <- main branch
/
A
\
+-- B2 --- C2 --- D2 --- G2 --- H2 <- public branch
這似乎是您想要的,但它不再能用作分支 - 如果您曾嘗試將任何內容從main
合並到它,您最終會得到這樣的結果:
+-- B --- C --- D -- E --- F ----- X <- main branch with new feature
/ \
A \
\ \
+-- B2 --- C2 --- D2 --- G2 --- H2 --- M <- public branch with merge commit
包含我們大文件的提交 B 的原始版本現在又回到了分支歷史記錄中,以及新的提交 B2。
因此,與其擔心哪些分支包含和不包含文件,不如簡單地使用新名稱獲取存儲庫的副本,並使其好像這些文件從未存在於存儲庫歷史中的任何地方一樣。
git filter-repo --invert-paths --path '/directory/to/delete'
這將重寫您的所有提交,提供全新的歷史記錄:
+-- E2 --- F2 <- main branch
/
A2 --- B2 --- C2 --- D2
\
+-- G2 --- H2 <- public branch
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.