【问题标题】:How can I delete a file from a Git repository?如何从 Git 存储库中删除文件?
【发布时间】:2011-01-04 02:01:19
【问题描述】:

我已将一个名为 "file1.txt" 的文件添加到 Git 存储库。之后,我提交了它,添加了几个名为 dir1dir2 的目录,并将它们提交到 Git 存储库。

现在当前存储库有"file1.txt"dir1dir2。如何在不影响其他人的情况下删除"file1.txt",例如dir1dir2

【问题讨论】:

  • git rm 是正确的答案,但请记住该文件仍将保留在历史记录中。如果你想删除一个文件,因为它包含敏感信息,你需要做一些更激烈的事情。 (更改历史记录,尤其是对于您已经推送的内容,是一种激烈的行为,应尽可能避免。)
  • 注意:在 GitHub 上,您现在可以直接从 Web 界面删除文件(甚至无需克隆 repo)。见my answer below
  • @KeithThompson 如果我非常想这样做,可能会采取哪些步骤?

标签: git git-rm


【解决方案1】:

使用git rm

如果您想从 Git 存储库和文件系统中删除文件,请使用:

git rm file1.txt
git commit -m "remove file1.txt"

但是如果你只想从 Git 存储库中删除文件而不是从文件系统中删除它,请使用:

git rm --cached file1.txt
git commit -m "remove file1.txt"

并将更改推送到远程仓库

git push origin branch_name

【讨论】:

  • 也很方便: git rm -r directory // 删除目录和内容
  • 不过,这不会在其他提交中删除该文件。
  • @SaulOrtega:没错。要从以前的提交中删除文件(更改过去的历史记录),请参阅Remove sensitive data 上的 GitHub 帮助页面。
  • 请注意,这也会在本地删除文件。如果你只想从 repo 中删除它: git rm --cached file1.txt
  • 值得注意的是,如果该文件包含敏感信息(例如凭据),您应该立即更改这些凭据。引用GitHub“一旦你将提交推送到 GitHub,你应该考虑它包含的任何数据都会受到损害。如果你提交了密码,请更改它!如果你提交了一个密钥,则生成一个新的。”
【解决方案2】:

更一般地说,git help 至少可以帮助解决像这样的简单问题:

zhasper@berens:/media/Kindle/documents$ git help
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]

The most commonly used git commands are:
   add        Add file contents to the index
   :
   rm         Remove files from the working tree and from the index

【讨论】:

  • 对于更复杂的事情,我觉得git help 令人困惑,但它对简单的事情有好处:)
  • 对于 git noobs 来说实际上并不是那么好,因为“索引”不是 git noobs 熟悉的概念。我是从一个 git noob 的个人经验说的 :) 另外,我觉得说 rm 暂存文件以供删除 而不是 从索引中删除(尽管对于新手来说仍然毫无意义)。
  • 同意 romkyns:“从工作树和索引中删除文件”的描述在我看来不像是从存储库中删除文件的一种方式。也许如果我更好地理解 git 它会。相反,听起来您只是在取消暂存文件(并且可以选择将它们从工作树中删除——这必然会影响存储库吗?)
【解决方案3】:

如果您有 GitHub for Windows 应用程序,您可以通过 5 个简单的步骤删除文件:

  • 点击同步。
  • 点击文件所在目录,选择你最新版本的文件。
  • 单击工具并选择“在此处打开外壳”。
  • 在 shell 中,输入:“rm {filename}”并回车。
  • 提交更改并重新同步。

【讨论】:

    【解决方案4】:

    git rm file.txt 从 repo 中删除文件,但也会从本地文件系统中删除它

    要从 repo 中删除文件并且从本地文件系统中删除它,请使用:
    git rm --cached file.txt

    下面的确切情况是我使用 git 来维护我的企业网站的版本控制,但“mickey”目录是一个 tmp 文件夹,用于与 CAD 开发人员共享私人内容。当他需要巨大的文件时,我创建了一个私有的、未链接的目录,并在那里 ftpd 文件供他通过浏览器获取。忘记我这样做了,我后来从网站的基本目录执行了git add -A。随后,git status 显示了需要提交的新文件。现在我需要将它们从 git 的跟踪和版本控制中删除...

    下面的示例输出来自我刚刚发生的事情,我无意中删除了.003 文件。谢天谢地,我不在乎 .003 的本地副本发生了什么,但其他一些当前更改的文件是我刚刚对网站进行的更新,如果在本地文件系统上被删除,那将是史诗般的! “本地文件系统”= 实时网站(不是一个很好的做法,但这是现实)

    [~/www]$ git rm shop/mickey/mtt_flange_SCN.7z.003
    error: 'shop/mickey/mtt_flange_SCN.7z.003' has local modifications
    (use --cached to keep the file, or -f to force removal)
    [~/www]$ git rm -f shop/mickey/mtt_flange_SCN.7z.003
    rm 'shop/mickey/mtt_flange_SCN.7z.003'
    [~/www]$ 
    [~/www]$ git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   deleted:    shop/mickey/mtt_flange_SCN.7z.003
    #
    # Changed but not updated:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #   modified:   shop/mickey/mtt_flange_SCN.7z.001
    #   modified:   shop/mickey/mtt_flange_SCN.7z.002
    [~/www]$ ls shop/mickey/mtt_flange_S*
    shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
    [~/www]$ 
    [~/www]$ 
    [~/www]$ git rm --cached shop/mickey/mtt_flange_SCN.7z.002
    rm 'shop/mickey/mtt_flange_SCN.7z.002'
    [~/www]$ ls shop/mickey/mtt_flange_S*
    shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
    [~/www]$ 
    [~/www]$ 
    [~/www]$ git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   deleted:    shop/mickey/mtt_flange_SCN.7z.002
    #   deleted:    shop/mickey/mtt_flange_SCN.7z.003
    #
    # Changed but not updated:
    #   modified:   shop/mickey/mtt_flange_SCN.7z.001
    [~/www]$
    

    更新:这个答案获得了一些流量,所以我想我会提到我的 other Git answer 分享了一些很棒的资源:@​​987654322@ 有一张图片可以帮助我揭开 Git 的神秘面纱。 "Pro Git" book is online 对我有很大帮助。

    【讨论】:

    • 然后您需要使用git commit -m "Just removing file1.txt" 之类的东西来提交它,然后,如果您有一个远程存储库,请使用git push origin master 之类的东西来推送提交。
    【解决方案5】:

    首先,如果您使用git rm,特别是对于多个文件,请考虑任何通配符都将由shell解析,而不是由git命令。

    git rm -- *.anExtension
    git commit -m "remove multiple files"
    

    但是,如果你的文件已经在 GitHub 上,you can (since July 2013) 直接从 web GUI 中删除它!

    只需查看存储库中的任何文件,单击顶部的垃圾桶图标,然后像任何其他基于 Web 的编辑一样提交删除。

    然后在本地存储库中添加“git pull”,这也会在本地删除文件。
    这使得这个答案成为从 git repo 中删除文件的(迂回)方式?
    (更不用说 GitHub 上的文件在“git repo”中)


    (提交将反映该文件的删除):

    就这样,它消失了。

    有关这些功能的帮助,请务必阅读我们关于 creatingmovingrenamingdeleting 文件的帮助文章。

    注意:由于它是一个版本控制系统,如果您以后需要恢复文件,Git 总是为您提供支持。

    最后一句表示被删除的文件仍然是历史的一部分,你可以很容易地恢复它(但还不能通过 GitHub 网页界面):

    见“Restore a deleted file in a Git repo”。

    【讨论】:

    • 您必须滚动到底部并点击“提交更改”才能提交删除!
    • 这不适用于大文本文件。服务器尝试按照屏幕截图呈现文件,然后失败并出现 500 错误。
    • 这个答案是指github,问题是关于一个git repo。不是如何使用github接口。
    【解决方案6】:

    这是唯一对我有用的选项。

    git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch *.sql'
    

    注意:将 *.sql 替换为您的文件名或文件类型。要非常小心,因为这将通过每个提交并撕掉这个文件类型。

    编辑: 注意 - 执行此命令后您将无法推送或拉取 - 您将看到拒绝“无关历史记录”您可以使用“git push --force -u origin master”进行推送或拉取

    【讨论】:

    • 这是一个很好的答案,但请注意,与其他答案相比,此命令会重写提交历史记录并删除与模式匹配的文件的所有跟踪。如果您发现您不小心提交了一些敏感信息,这将特别有用(并且,如果需要,可以成功使用 --force 重写已推送到的任何远程仓库的历史记录)。
    • 这正是我遇到的问题,经过反复试验才能解决问题。与我一起工作的一个人已经将几个大型数据库转储提交到一个 repo 中,并通过许多提交返回。这就是我在示例中使用 .sql 的原因。我的仓库变得如此臃肿和庞大,以至于 github 不再接受推送。
    • 如果您使用的是远程主机,您需要强制提交并使用 git push --force -u origin master 推送它
    • @AlbertMarkovski 抱歉,我没有具体说明。 Github 实际上不会接受推送,因为 repo 超出了他们的大小限制。至少几个 GB。他们切断了我的联系并通过电子邮件告诉我。因此,不幸的是,在这一点上,再多的强制推动也无济于事。
    • @JasonGlisson 我也遇到过视频被意外添加到存储库的问题。
    【解决方案7】:

    如果您想从 repo 中删除文件,但将其留在文件系统中(将不被跟踪):

    bykov@gitserver:~/temp> git rm --cached file1.txt
    bykov@gitserver:~/temp> git commit -m "remove file1.txt from the repo"
    

    如果你想从 repo 和文件系统中删除文件,那么有两个选项:

    1. 如果文件在索引中没有暂存更改:

      bykov@gitserver:~/temp> git rm file1.txt
      bykov@gitserver:~/temp> git commit -m "remove file1.txt"
      
    2. 如果文件在索引中有暂存的更改:

      bykov@gitserver:~/temp> git rm -f file1.txt
      bykov@gitserver:~/temp> git commit -m "remove file1.txt"
      

    【讨论】:

      【解决方案8】:

      此外,如果它是要删除的文件夹以及后续的子文件夹或文件,请使用:

      git rm -r foldername
      

      【讨论】:

      • 这也会从本地删除文件夹! Use git rm --cached -r &lt;foldername&gt;
      【解决方案9】:

      如果您想使用 rm 命令从本地文件夹中删除文件,然后将更改推送到远程服务器,则另一种方法。

      rm file1.txt
      
      git commit -a -m "Deleting files"
      
      git push origin master
      

      【讨论】:

        【解决方案10】:

        在我的情况下,我尝试在几次提交后删除 github 上的文件,但保存在计算机上

        git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch file_name_with_path' HEAD
        git push --force -u origin master
        

        后来这个文件被忽略了

        【讨论】:

          【解决方案11】:

          删除特定文件

          git rm 文件名

          单次递归清除目录中所有未跟踪的文件

          git clean -fdx

          【讨论】:

            【解决方案12】:
            1. 首先,从本地存储库中删除文件。

              git rm -r 文件名

              或者,仅从本地存储库中删除文件,但从文件系统中删除文件

              git rm --cached 文件名

            2. 其次,将更改提交到本地存储库。

              git commit -m "unwanted files or some inline comments"   
              
            3. 最后,将本地更改更新/推送到远程存储库。

              git push 
              

            【讨论】:

            • 这会删除与意外添加和推送的文件相关的所有内容吗?
            • @bapors 不,它将保留在 git 历史记录中
            【解决方案13】:

            如果你不是在本地仓库而是在 git repo 中归档,那么只需通过 web 界面在 git repo 中打开文件,然后在界面右上角找到删除按钮。 Click Here, To view interface Delete Option

            【讨论】:

              【解决方案14】:

              git rm 从现在开始只会删除该分支上的文件,但它会保留在历史记录中,git 会记住它。

              正确的做法是使用git filter-branch,正如其他人在这里提到的那样。它将重写分支历史中的每个提交以删除该文件。

              但是,即使在这样做之后,git 也可以记住它,因为在 reflog、remote、tags 等中可以引用它。

              如果你想一步完全抹杀,我推荐你使用git forget-blob

              https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

              很简单,只需git forget-blob file1.txt

              这将删除所有引用,执行 git filter-branch,最后运行 git 垃圾收集器 git gc 以完全删除您的 repo 中的这个文件。

              【讨论】:

              • 2021年,我试过这个,好像没用。我仍然可以看到文件历史记录。相反,我最终将文件重命名为git mv,并从提交的文件中清除了所有内容。
              【解决方案15】:

              我尝试了很多建议的选项,但似乎都没有效果(我不会列出各种问题)。 我最终做的(对我来说)简单直观的工作是:

              1. 将整个本地仓库移到别处
              2. 再次将 repo 从 master 克隆到本地驱动器
              3. 将 #1 中原始副本中的文件/文件夹复制回 #2 中的新克隆
              4. 确保 .gitignore 文件中不存在或排除有问题的大文件
              5. 执行通常的 git add/git commit/git push

              【讨论】:

                【解决方案16】:

                我有 obj 和 bin 文件不小心进入了我不想污染我的“已更改文件”列表的存储库

                之后我注意到他们去了遥控器,我通过将其添加到.gitignore来忽略他们

                /*/obj
                /*/bin
                

                问题是它们已经在远程,当它们被更改时,它们会弹出为已更改并污染已更改的文件列表。

                要停止看到它们,您需要从远程存储库中删除整个文件夹。

                在命令提示符下:

                1. CD 到 repo 文件夹(即C:\repos\MyRepo
                2. 我想删除 SSIS\obj。看来你只能在顶层删除,所以你现在需要CD到SSIS:(即C:\repos\MyRepo\SSIS
                3. 现在输入魔法咒语git rm -r -f obj
                  • rm=删除
                  • -r = 递归删除
                  • -f = 表示强制,因为你是认真的
                  • obj 是文件夹
                4. 现在运行git commit -m "remove obj folder"

                我收到一条警告消息,说 13 个文件更改了 315222 个删除

                然后因为我不想查找 CMD 行,所以我进入 Visual Sstudio 并进行了同步以将其应用到遥控器

                【讨论】:

                  【解决方案17】:

                  使用 git rm 从 repo 中删除文件后,您可以使用 BFG Repo-Cleaner 从 repo 历史记录中完全轻松地删除文件。

                  【讨论】:

                    【解决方案18】:

                    注意:如果您只想从 git 中删除文件,请使用以下命令:

                    git rm --cached file1.txt
                    

                    如果你也想从硬盘中删除:

                    git rm file1.txt
                    

                    如果你想删除一个文件夹(文件夹可能包含很少的文件),你应该使用递归命令删除,如下:

                    git rm -r foldername
                    

                    如果要删除另一个文件夹中的文件夹

                    git rm -r parentFolder/childFolder
                    

                    然后,您可以像往常一样commitpush。但是,如果你想恢复被删除的文件夹,你可以按照这个:recover deleted files from git is possible.

                    来自文档:

                    git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…​
                    

                    选项

                    &lt;file&gt;…​

                    Files to remove. Fileglobs (e.g. *.c) can be given to remove all matching files. If you want Git to expand file glob characters, you
                    

                    可能需要对它们进行外壳转义。前导目录名称(例如 dir to remove dir/file1 和 dir/file2) 可以删除所有文件 目录,并递归所有子目录,但这需要 -r 选项要明确给出。 -f --force

                    Override the up-to-date check.
                    

                    -n --dry-run

                    Don’t actually remove any file(s). Instead, just show if they exist in the index and would otherwise be removed by the command.
                    

                    -r

                    Allow recursive removal when a leading directory name is given.
                    

                    --

                    This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken for
                    

                    命令行选项)。 --cached

                    Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.
                    

                    --忽略不匹配

                    Exit with a zero status even if no files matched.
                    

                    -q --quiet

                    git rm normally outputs one line (in the form of an rm command) for each file removed. This option suppresses that output.
                    

                    Read more on official doc.

                    【讨论】:

                      【解决方案19】:

                      如果您需要从确定的扩展名中删除文件(例如,编译的文件),您可以执行以下操作以一次将它们全部删除:

                      git remove -f *.pyc
                      

                      【讨论】:

                        【解决方案20】:

                        根据documentation.

                        git rm --cached file1.txt

                        当涉及到敏感数据时,最好不要说您删除了文件,而只是将其包含在最后一次已知的提交中:

                        0。修改上次提交

                        git commit --amend -CHEAD
                        

                        如果要从所有 git 历史记录中删除文件,根据documentation,您应该执行以下操作:

                        1.从您的本地历史记录中删除它

                        git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" \  --prune-empty --tag-name-filter cat -- --all
                        # Replace PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA with the path to the file you want to remove, not just its filename
                        
                        1. 不要忘记将此文件包含在 .gitignore 中(如果它是您不想共享的文件(例如密码...):
                        echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
                        git add .gitignore
                        git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
                        

                        3.如果您需要从遥控器中移除

                        git push origin --force --all
                        

                        4.如果您还需要从标签发布中删除它:

                        git push origin --force --tags
                        

                        【讨论】:

                          【解决方案21】:

                          只需在您的 github 存储库中打开文件,您就可以看到 Raw|Blame 旁边的删除图标,并且不要忘记单击提交更改按钮。并且您可以看到您的文件已被删除。

                          【讨论】:

                            【解决方案22】:

                            对于git rm 不够用且文件需要从历史记录中删除的情况:正如git filter-branch 手册页现在本身建议使用git-filter-repo,而我今天必须这样做,这是一个示例使用那个工具。它使用示例 repo https://example/eguser/eg.git

                            1. 将仓库克隆到新目录git clone https://example/eguser/eg.git

                            2. 保留除不需要的文件之外的所有内容。 git-filter-repo --path file1.txt --invert-paths

                            3. 重新添加远程存储库来源: git remote add origin https://example/eguser/eg.gitgit-filter-repo 工具通过设计删除远程远程信息并建议a new remote repo(见第 4 点)。这对于大型共享存储库是有意义的,但对于像本例中那样删除单个新添加的文件可能会有点过分。

                            4. 如果对 local 的内容感到满意,请将 remote 替换为它。

                              git push --force -u origin master。由于更改了历史记录,因此需要强制。

                            还要注意有用的--dry-run 选项以及链接手册中关于团队和项目动态的良好讨论,然后再加入和更改存储库历史记录。

                            【讨论】:

                              【解决方案23】:

                              转到您的项目目录并输入:

                              git filter-branch --tree-filter 'rm -f <deleted-file>' HEAD
                              

                              之后 push --force 从所有提交中删除文件。

                              git push origin --force --all
                              

                              【讨论】:

                                【解决方案24】:

                                Greg Hewgill 的答案(由Johannchopin 编辑)帮助了我,因为我并不关心完全从历史记录中删除文件。 就我而言,它是一个目录,所以我所做的唯一更改是使用:

                                git rm -r --cached myDirectoryName
                                

                                而不是“git rm --cached file1.txt” ..接着是:

                                git commit -m "deleted myDirectoryName from git"
                                git push origin branch_name
                                

                                感谢Greg HewgillJohannchopin

                                【讨论】:

                                  猜你喜欢
                                  • 2010-09-11
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2011-03-28
                                  • 2012-08-31
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多