【问题标题】:How to remove multiple deleted files in Git repository如何在 Git 存储库中删除多个已删除的文件
【发布时间】:2011-08-25 15:45:18
【问题描述】:

我删除了一些文件,git状态显示如下。

我已经承诺并推动了。

GitHub 仍然显示存储库中已删除的文件。如何删除 GitHub 存储库中的文件?

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

如果我使用git rm,它会给出以下内容。

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched

【问题讨论】:

标签: git git-rm


【解决方案1】:

如果您想使用“git rm”删除所有这些。我就是这样做的:

git ls-files --deleted -z | xargs -0 git rm

此查询列出了所有已删除的文件并将它们从您的 git 存储库中删除。 希望对您有所帮助。

【讨论】:

    【解决方案2】:

    在我删除它们并遇到这个简洁的命令后,我的仓库中出现了这个幽灵文件的问题!

    git add -A

    它与git add -agit add -u 的组合基本相同,但区分大小写。我是从 this awesome link 获得的(此链接现在指向 archive.org 上的版本,因为截至 2016 年 6 月,原版已转换为垃圾邮件/网络钓鱼页面)

    【讨论】:

      【解决方案3】:

      试试这个:

       git rm `git ls-files -d`
      

      【讨论】:

      • 这解决了我只暂存已删除脚本的问题(使用 bash)
      【解决方案4】:
      git add -u .
      
      git add --update .
      

      【讨论】:

        【解决方案5】:

        以下是如何检测已删除文件并将其删除作为下一次提交的一部分。该线程上的所有解决方案都有不同的优点。下面这个解决方案专门处理文件名中带有空格的问题。

        git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'
        

        确保在使用以下命令运行之前使用 git 的 --dry-run 选项对其进行测试:

        git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'
        

        解释:

        git status --porcelain
        

        这会打印出类似 D "/文件夹路径/文件路径" 只有当路径名中有空格时才会发生这种情况

        awk '/^.D .*$/ {print $0}'
        

        只匹配以“D”开头的行

        sed 's/ D \(.*\)/\1/'
        

        去掉每个字符串前面的“D”

        tr -d '"'
        

        删除引号,如果有的话

        xargs -I {} git rm '{}'
        

        将文件名变量定义为 {} 在用单引号括起来的 git rm 下运行文件名,以确保它支持带空格的文件名。

        【讨论】:

          【解决方案6】:

          当我删除了很多未暂存的文件时,您可以git rm 将它们全部集中在一个节目中:

          for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done
          

          正如问答者所说,小心git rm

          【讨论】:

            【解决方案7】:

            您可以创建一个 shell 脚本,它会在运行时删除所有文件:

            git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh
            

            创建的脚本是remove.sh,它包含git rm 命令的完整列表。

            【讨论】:

              【解决方案8】:

              更新您所做的所有更改:

              git add -u
              

              删除的文件应该从未暂存(通常为红色)变为暂存(绿色)。 然后提交删除删除的文件:

              git commit -m "note"
              

              【讨论】:

              • 值得民粹主义徽章。
              • 这是迄今为止最好的解决方案。没有脚本黑客,没有冗长的过程,只是一个告诉 git 彻底更新其索引的标志。
              • 太棒了!让我不必输入 20 多个文件路径。谢谢!
              【解决方案9】:

              你可以使用

              git commit -m "remove files" -a
              git push
              

              在您手动删除文件之后。

              【讨论】:

              • 或者相同但更简洁: git commit -am"remove files"
              【解决方案10】:

              ByScripts 答案的另一个版本是

              git rm $(git ls-files --deleted)
              

              这只会从 git 中删除已删除的文件。

              它也可以用于添加仅修改过的文件。

              git add $(git ls-files --modified)
              

              这些命令也适用于 gitbash for windows。

              【讨论】:

              • 无价,状态为已删除或已修改的git ls-files 非常有用。
              • 'git add --update (or -u)' 在树的子目录中没有路径参数的行为将在 Git 2.0 中发生变化,不应再使用。要为整个树添加内容,请运行:git add --update :/(或 git add -u :/)要将命令限制在当前目录,请运行:git add --update .(或 git add -u。)使用当前 Git 版本,该命令仅限于当前目录
              • 知道如何处理带有空格的路径吗?示例:src/my spaced directory/myfile。这可以单独处理,但如何使用此答案中的命令来处理?
              【解决方案11】:

              内置的清洁功能也很有帮助...

              git clean -fd
              

              【讨论】:

              • 这仅适用于未跟踪的文件。
              【解决方案12】:

              如果您不关心暂存修改过的文件,最好的解决方案是使用 mshameers 和/或 pb2q 所说的git add -u

              如果您只想删除已删除的文件,而不是暂存任何修改过的文件,我认为您应该使用 ls-files 参数和 --deleted 选项(无需使用正则表达式或其他复杂的参数/选项):

              git ls-files --deleted | xargs git rm
              

              【讨论】:

              【解决方案13】:
              git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf
              

              【讨论】:

                【解决方案14】:
                git add -u 
                

                更新您的所有更改

                【讨论】:

                • 很有魅力。当您看到像“git status | sed -n '/^# *deleted:/s///p' | xargs git rm”这样简单而频繁的需求的建议解决方案时,您就会知道更好的解决方案是,或者很快就会,指日可待。
                • 简单更好,这真的比“bash”方式方便
                • 作者问如何删除文件,为什么添加文件是正确答案?
                • @kelin: from git docs (git-scm.com/docs/git-add): "-u --update 仅在它已经有匹配 的条目的位置更新索引。这将删除索引条目并将其修改为匹配工作树,但不添加新文件。如果使用 -u 选项时没有给出 ,则更新整个工作树中的所有跟踪文件(旧版本的 Git 用于限制更新到当前目录和它的子目录)。”
                【解决方案15】:

                是的,git rm &lt;filename&gt; 将暂存文件的已删除状态,其中&lt;filename&gt; 可以是全局模式:

                $ git rm modules/welcome/language/*/kaimonokago_lang.php
                rm modules/welcome/language/english/kaimonokago_lang.php
                rm modules/welcome/language/french/kaimonokago_lang.php
                rm modules/welcome/language/german/kaimonokago_lang.php
                rm modules/welcome/language/norwegian/kaimonokago_lang.php
                
                $ git status
                # On branch master
                # Changes to be committed:
                #   (use "git reset HEAD <file>..." to unstage)
                #
                #       deleted:    modules/welcome/language/english/kaimonokago_lang.php
                #       ...
                

                然后,您可以提交。

                git commit -a 可以一次性完成,如果你愿意的话。

                您也可以使用git add -u 暂存所有更改,包括所有已删除的文件,然后提交。

                【讨论】:

                • 所以 rm 。 (句号)立即删除它们?
                • 所以 git rm 会一次性全部删除?
                • 您可以使用 glob 样式的模式来删除多个文件;我更新了答案以显示示例。
                • 看来git add -u 正是我们正在寻找的——如果你做了很多删除,然后想要提交所有的删除,这似乎是最简单和最“标准”的方式(意思是,没有特定于案例的 glob 或复杂的 shell 解析为 xargs)。除了它一次添加所有更改之外,还有什么我们不想使用它的原因?
                【解决方案16】:

                git rm .要非常谨慎;它可能会删除比您想要的更多。当然,您可以恢复,但不必这样做更简单。

                最简单的是:

                git rm modules/welcome/language/english/kaimonokago_lang.php \
                       modules/welcome/language/french/kaimonokago_lang.php \
                       modules/welcome/language/german/kaimonokago_lang.php \
                       modules/welcome/language/norwegian/kaimonokago_lang.php
                

                您不能使用 shell 通配符,因为文件不存在,但您可以使用(至少在 Bash 中):

                git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php
                

                或者考虑:

                git status | sed -n '/^# *deleted:/s///p' | xargs git rm
                

                这需要git status 的输出,默认情况下不打印任何内容(sed -n),但在以# deleted: 开头的行上,它会去掉#deleted: 并打印什么离开了; xargs 收集参数并将它们提供给git rm 命令。这适用于任意数量的文件,无论名称是否相似。

                【讨论】:

                • 可以使用通配符(虽然你可能需要转义它们),并且 git 将匹配索引中的路径,而不仅仅是工作树中的路径,所以它不会'文件系统上不存在它们无关紧要。
                • git diff --diff-filter=D --name-only -z | xargs -0 git rm 是一种比尝试解析git status 更可靠的方法,git status 是面向用户的,不能保证在未来版本中稳定。
                • @Charles:这当然更好,但它需要大量关于git diff 可用选项的知识(我没有,以前没有需要)。谢谢!
                • 注意还有“git ls-files --deleted”
                • 所以,git ls-files --deleted | xargs git rm 帮了我大忙。
                猜你喜欢
                • 2013-06-03
                • 2010-11-27
                • 2019-05-27
                • 2015-09-01
                • 2011-06-04
                • 2011-01-04
                相关资源
                最近更新 更多