首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果您已经将文件推送到远程分支,合并到开发分支,并且它不是最新的提交,那么如何从git中完全删除该文件?

如果您已经将文件推送到远程分支,合并到开发分支,并且它不是最新的提交,那么如何从git中完全删除该文件?
EN

Stack Overflow用户
提问于 2020-08-25 18:13:21
回答 1查看 147关注 0票数 2

我已经看过很多教程,解释如何在不同的场景中这样做,但是他们中的许多人似乎都在谈论最新的提交。因此,我需要的是从两个分支( feature-branchdevelop )中完全删除这个敏感文件。

我该怎么做?

我找到了这个菜谱:

代码语言:javascript
复制
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'

产出:

代码语言:javascript
复制
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 )是在运行命令的分支上的最后一次提交,所以我必须删除该文件(但必须使用rmgit-rm删除它吗?)然后提交并再次运行BFG?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-25 20:49:04

虽然我没有使用BFG,但我从它的文档中了解到,它认为每个分支的最提示提交是一个“正确的状态”。也就是说,假设您希望从每次提交中删除文件secret.txt。如果您使用BFG和指令"remove secret.txt",它将从除当前提交之外的所有提交中删除它(以及包含该文件的任何其他分支提示提交)。

记住,分支名称只是通过提交散列ID来标识某个提交,其中包含文件的是提交本身。每个提交都有每个文件的完整快照。因此,如果您在前面添加了secret.txt 4,并且拥有以下内容:

代码语言:javascript
复制
... <-H <-I <-J <-K <-L   <--master

在每个大写字母表示提交的情况下,文件secret.txt位于提交LKJI中。它不在H中,因为H是五次提交。

这里的反向箭头是Git的工作原理:每个提交都会向后引导到以前的提交。任何提交的任何部分都不能更改( BFG也不能),所以BFG必须做的是创建新的和改进的提交,然后完全丢弃旧的提交。

BFG将将现有的提交I复制到不存在secret.txt的新的和改进的I'中。然后将J复制到不存在secret.txt的新的和改进的J'中,并对K重复此操作。但是L是最后一次提交,由名称标识,因此BFG假设您打算将secret.txt保存在那里,因为它现在就在那里,并且由名称标识。这是“受保护的”提交。因此,BFG将L复制到L'-it必须这样做,因为它将K复制到K',而现有的L指向现有的K-but,这一次它将secret.txt保存在提交L'中。

你的下场是:

代码语言:javascript
复制
... <-H [ XXX deleted: <-I <-J <-K <-L ]
       \
        I' <-J' <-K' <-L'   <-- master

其中secret.txt现在只存在于上次提交( L' )中,这是受保护的。

BFG的文档建议您这样做:

代码语言:javascript
复制
git rm secret.txt
git commit

在开始之前,让您从以下开始:

代码语言:javascript
复制
... <-H <-I <-J <-K <-L <-M   <--master

新提交M中没有secret.txt的地方。现在,通过L提交I可以全部修复,因为L不再是最后一次提交。它没有用名字来识别。master查找的名称不是L,而是M;只有M本身才能找到L

备注

一旦您更新了自己的存储库,使其具有新的和改进的提交,并丢弃了旧的坏的提交,您将需要使用git push --force来获得任何其他的Git,这些Git仍然有并且仍然在使用旧的坏提交,从而切换到新的和改进的提交。

总是假设,如果secrets.txt在网络上可用了几秒钟,外面的人就会抓取它的副本。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63584840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档