[英]How to completely remove a file from git if you already pushed it to the remote branch, merged to the develop branch and it is not the latest commit
我看過很多教程解釋了如何在不同的場景中執行此操作,但似乎其中許多都在談論最新的提交。 所以我需要的是從兩個分支中完全刪除這個敏感文件: feature-branch
和develop
。
我怎么做?
我找到了這個食譜:
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD
它會在我的情況下工作嗎? 也就是說,它會從所有分支中完全刪除這個文件嗎?
編輯:
我決定使用 BFG,這是我運行后它給我的輸出
bfg --delete-files 'filename_of_the_file_to_delete'
輸出:
Found 273 objects to protect
Found 198 commit-pointing refs : HEAD, refs/heads/develop, refs/heads/develop-with-relative-paths, ...
Protected commits
-----------------
These are your protected commits, and so their contents will NOT be altered:
* commit 7d97ab00 (protected by 'HEAD') - contains 1 dirty file :
- src/email/filename_of_the_file_to_delete (16.1 KB)
WARNING: The dirty content above may be removed from other commits, but as
the *protected* commits still use it, it will STILL exist in your repository.
Details of protected dirty content have been recorded here :
/Users/albert/Documents/projects/rjx/rjxfp/.git.bfg-report/2020-08-25/21-50-38/protected-dirt/
If you *really* want this content gone, make a manual commit that removes it, and then run the BFG on a fresh copy of your repo.
Cleaning
--------
Found 486 commits
Cleaning commits: 100% (486/486)
Cleaning commits completed in 699 ms.
Updating 7 Refs
---------------
Ref Before After
--------------------------------------------------------------------------
refs/heads/develop | e9c3c4ba | 53c5dd39
refs/heads/feature-icons-for-top-level-cats | d7dde80c | 377ae820
refs/heads/feature-user-profile | 7d97ab00 | e3b1b336
refs/remotes/origin/develop | e9c3c4ba | 53c5dd39
refs/remotes/origin/feature-icons-for-top-level-cats | d7dde80c | 377ae820
refs/remotes/origin/feature-user-profile | 7d97ab00 | e3b1b336
refs/stash | 9fc9a356 | 39945789
Updating references: 100% (7/7)
...Ref update completed in 54 ms.
Commit Tree-Dirt History
------------------------
Earliest Latest
| |
..........................................................DD
D = dirty commits (file tree fixed)
m = modified commits (commit message or parents changed)
. = clean commits (no changes to file tree)
Before After
-------------------------------------------
First modified commit | 6a211a6b | 35597e71
Last dirty commit | e9c3c4ba | 53c5dd39
Deleted files
-------------
Filename Git id
------------------------------------------------------
filename_of_the_file_to_delete | 4121d724 (16.1 KB)
In total, 37 object ids were changed. Full details are logged here:
/Users/albert/Documents/projects/rjx/rjxfp/.git.bfg-report/2020-08-25/21-50-38
BFG run is complete! When ready, run: git reflog expire --expire=now --all && git gc --prune=now --aggressive
我想刪除的文件仍在創建它的目錄中,至少在我運行bfg
命令的分支上。 然后我不認為我完全理解它對一些受保護的臟內容所說的內容。 誰保護了它,為什么? 它說: If you *really* want this content gone, make a manual commit that removes it, and then run the BFG on a fresh copy of your repo.
我不明白我應該做什么。
據我所知,它提到的提交7d97ab00
(現在是e3b1b336
)是我運行命令的分支上的最后一次提交,所以我必須刪除文件(但我必須用rm
或git-rm
刪除它嗎? git-rm
?) 然后提交並再次運行 BFG?
雖然我沒有使用過 The BFG,但我從它的文檔中了解到,它認為每個分支的最尖端提交是“正確狀態”。 也就是說,假設您想從每次提交中刪除文件secret.txt
。 如果您將 BFG 與指令“remove file secret.txt
”一起使用,它將從除當前提交(以及包含該文件的任何其他分支提示提交)之外的所有提交中刪除它。
請記住,分支名稱只是通過其提交哈希 ID 來標識某個提交。 提交本身包含文件。 每個提交都有每個文件的完整快照。 因此,如果您在四次提交前添加了secret.txt
並具有以下內容:
... <-H <-I <-J <-K <-L <--master
其中每個大寫字母代表一次提交,文件secret.txt
在提交L
、 K
、 J
和I
。 它不在H
因為H
是五次提交前。
這里的向后箭頭是 Git 的工作原理:每次提交都會向后引導到上一次提交。 任何提交的任何部分都不能更改(也不能被 BFG 更改),因此 BFG 必須做的是創建新的和改進的提交,然后完全丟棄舊的提交。
BFG 會將現有的提交I
復制到一個新的和改進的I'
,其中secret.txt
不存在。 然后它將J
復制到一個新的和改進的J'
中,其中secret.txt
不存在,並為K
重復此操作。 但是L
是最后一次提交,由名稱標識,所以BFG假定你的意思是保持secret.txt
那里,因為它的存在,現在及識別的名稱。 這是“受保護的”提交。 所以BFG副本L
到L'
-它必須這樣做,因為它復制K
到K'
和現有L
回指向現有K
-但這次它使secret.txt
在提交L'
。
你最終得到:
... <-H [ XXX deleted: <-I <-J <-K <-L ]
\
I' <-J' <-K' <-L' <-- master
其中secret.txt
現在僅存在於最后一次提交L'
,該提交受保護。
The BFG 的文檔建議您這樣做:
git rm secret.txt
git commit
在你開始之前,讓你開始:
... <-H <-I <-J <-K <-L <-M <--master
新提交M
中沒有secret.txt
的地方。 現在提交I
到L
都可以修復,因為L
不再是最后一次提交了。 它不是通過名稱來識別的。 名稱master
找到的不是L
,而是M
; 只有M
本身找到L
。
一旦您更新了自己的存儲庫以進行新的和改進的提交,並拋出舊的壞提交,您將需要使用git push --force
來獲取任何其他仍然擁有並仍在使用的 Git,舊的錯誤提交,切換到新的和改進的提交。
始終假設,如果secrets.txt
在網絡上可用甚至幾秒鍾,那里的人就抓住了它的副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.