簡體   English   中英

Git - 從分支的歷史記錄中刪除文件

[英]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 rmpublic分支(只有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM