簡體   English   中英

如果您已經將文件推送到遠程分支,合並到開發分支並且它不是最新提交,如何從 git 中完全刪除文件

[英]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-branchdevelop

我怎么做?

我找到了這個食譜:

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 )是我運行命令的分支上的最后一次提交,所以我必須刪除文件(但我必須用rmgit-rm刪除它嗎? git-rm ?) 然后提交並再次運行 BFG?

雖然我沒有使用過 The BFG,但我從它的文檔中了解到,它認為每個分支的最尖端提交是“正確狀態”。 也就是說,假設您想從每次提交中刪除文件secret.txt 如果您將 BFG 與指令“remove file secret.txt ”一起使用,它將從當前提交(以及包含該文件的任何其他分支提示提交)之外的所有提交中刪除它。

請記住,分支名稱只是通過其提交哈希 ID 來標識某個提交。 提交本身包含文件。 每個提交都有每個文件的完整快照。 因此,如果您在四次提交前添加了secret.txt並具有以下內容:

... <-H <-I <-J <-K <-L   <--master

其中每個大寫字母代表一次提交,文件secret.txt在提交LKJI 它不在H因為H五次提交前。

這里的向后箭頭是 Git 的工作原理:每次提交都會向后引導到上一次提交。 任何提交的任何部分都不能更改(也不能被 BFG 更改),因此 BFG 必須做的是創建新的和改進的提交,然后完全丟棄舊的提交。

BFG 會將現有的提交I復制到一個新的和改進的I' ,其中secret.txt不存在。 然后它將J復制到一個新的和改進的J'中,其中secret.txt不存在,並為K重復此操作。 但是L最后一次提交,由名稱標識,所以BFG假定你的意思是保持secret.txt那里,因為它的存在,現在識別的名稱。 這是“受保護的”提交。 所以BFG副本LL' -它必須這樣做,因為它復制KK'和現有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的地方。 現在提交IL都可以修復,因為L不再最后一次提交了。 它不是通過名稱來識別的。 名稱master找到的不是L ,而是M 只有M本身找到L

筆記

一旦您更新了自己的存儲庫以進行新的和改進的提交,並拋出舊的壞提交,您將需要使用git push --force來獲取任何其他仍然擁有並仍在使用的 Git,舊的錯誤提交,切換到新的和改進的提交。

始終假設,如果secrets.txt在網絡上可用甚至幾秒鍾,那里的就抓住了它的副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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