如何在Git存储库中删除多个已删除的文件


236

我已经删除了一些文件,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


Answers:


637
git add -u 

更新您的所有更改


31
很有魅力。当您看到诸如“ git status | sed -n'/ ^#*已删除:/ s /// p'| xargs git rm”之类的建议方案时,您会发现一个更好的解决方案是,或即将到来。
arcseldon

简单更好,这真的很方便,然后是“重击”方式
castiel 2014年

1
作者问如何删除文件,为什么添加文件才是正确的答案?
凯林

3
@kelin:来自git docs(git-scm.com/docs/git-add):“ -u --update在索引已经具有与<pathspec>匹配的条目的位置更新索引。这将删除并修改索引条目为匹配工作树,但不添加任何新文件。如果使用-u选项时未提供<pathspec>,则会更新整个工作树中的所有跟踪文件(旧版本的Git用于将更新限制为当前目录,其子目录)。”
HEDMON '16

92

小心点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

您不能使用外壳通配符,因为文件不存在,但是可以使用(至少在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),但是在start的行上# deleted:,它删除#deleted:并打印剩余的内容;xargs收集参数并将其提供给git rm命令。这适用于任意数量的文件,而不管名称中的相似性(或相似性)如何。


6
可以使用通配符(尽管您可能需要转义它们),并且git将匹配索引中的路径,而不仅仅是工作树中的路径,因此它们在文件系统上不存在并不重要。
本·詹姆斯

109
git diff --diff-filter=D --name-only -z | xargs -0 git rm比尝试解析git status是面向用户的,并且不能保证在将来的版本中稳定,这是一种比尝试解析更可靠的方法。
CB Bailey

@Charles:那当然更好,但是它需要相当多的关于哪些选项可用的知识git diff(我没有,以前没有需要)。谢谢!
乔纳森·莱夫勒

8
请注意,还有“ git ls文件--deleted”
Petr Gladkikh 2012年

1
所以,git ls-files --deleted | xargs git rm为我做了把戏。
fiacobelli 2015年

50

ByScripts答案的另一个版本是

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

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

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

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

这些命令也适用于Windows的gitbash。


2
无价之宝,git ls-files状态已删除或修改非常有帮助。
Mario Peshev 2014年

1
'git add --update (or -u)'树的子目录中没有path参数的行为将在Git 2.0中更改,并且不应再使用。要为整个树添加内容,请运行:( git add --update :/ 或git add -u:/)要将命令限制为当前目录,请运行:( git add --update . 或git add -u。)对于当前的Git版本,该命令仅限于当前目录
Ans 2014年

1
知道如何处理其中带有空格的路径吗?范例:src/my spaced directory/myfile。这可以单独处理,但是如何使用此答案中的命令来处理呢?
穆罕默德·盖尔巴纳

35

更新您所做的所有更改:

git add -u

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

git commit -m "note"

1
值得民粹主义徽章。
约翰

1
到目前为止,这是最好的解决方案。没有脚本黑客,没有冗长的过程,只是一个标志,告诉git彻底更新其索引。
罗恩·达尔格伦

辉煌!使我不必键入20多个文件路径。谢谢!
allardbrain

12

如果你不关心分期修改文件的最佳解决方案是使用git add -u如说mshameers和/或pb2q

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

git ls-files --deleted | xargs git rm

1
git add -A解决了这个问题...以防万一将来有人想知道。检查以下答案
Ja8zyjits

8

是的,git rm <filename><filename>暂存文件的已删除状态,可能是全局模式:

$ 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可以一次删除所有内容?
胫骨

1
您可以使用全局样式的模式来删除多个文件。我更新了答案以显示示例。
本·詹姆斯

5
似乎git add -u正是我们要寻找的-如果您进行了多次删除,然后想提交所有删除操作,这似乎是最简单,最“标准”的方式(意味着无需区分大小写的glob或复杂的shell解析为xargs)。除了它会立即添加所有更改之外,还有其他我们不想使用的原因吗?
trisweb 2012年

7

当我删除了很多未暂存的文件后,可以通过以下方式git rm一次显示所有文件:

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

正如问答者所说的那样,请当心git rm



3

您可以使用

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

手动删除文件后。


1
还是相同但更简洁:git commit -am“删除文件”
BradChesney79

3

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

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

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


2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf


2

如果要使用“ git rm”将其全部删除。这是我的工作:

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

该查询列出了所有已删除的文件,并将其从git存储库中删除。希望能帮助到你。



1

删除它们并遇到此整洁命令后,我的仓库中出现了幻影文件的问题!

git add -A

它本质上git add -a和和相同git add -u,但是区分大小写。我是从这个很棒的链接获得的(此链接现在指向archive.org上的版本,因为截至2016年6月,原始文件已转换为垃圾邮件/网络钓鱼页面)


0

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

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下用单引号引起来运行文件名,以确保它支持带空格的文件名。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.