从Git仓库中删除已经从磁盘中删除的多个文件

1388

我有一个Git存储库,我使用rm(而不是git rm)删除了其中的四个文件,我的Git状态如下:

#    deleted:    file1.txt
#    deleted:    file2.txt
#    deleted:    file3.txt
#    deleted:    file4.txt

我如何在Git中删除这些文件而无需手动逐个添加每个文件,类似于这样:

git rm file1 file2 file3 file4

理想情况下,我希望找到的东西能够像git add .一样工作,如果可能的话。


3
相关:https://dev59.com/enI-5IYBdhLWcg3wbXxN - kch
12
@seth,使用git rm并不总是方便的,因为删除操作可能来自于其他工具、IDE或文件管理器。例如,使用Visual Studio删除/重命名文件时可能会出现问题。 - Brett Ryan
73
问别人为什么不使用“git rm”有点像问他们为什么不使用“git vim”或“git cd”。这是一件很愚蠢的事情,git应该有一个内置命令或别名来从暂存区中删除已删除的文件,你不应该必须在SO上查找或在午休时间阅读man页面。 - Isabelle Wedin
8
Varinder的回答不是一个好方法。请考虑Cody建议的git add -u,这也是这个问题的答案:http://stackoverflow.com/questions/1402776/how-do-i-commit-all-deleted-files-in-git - Roland
@Roland git add -u 会添加所有被跟踪的修改过的文件。这可能会起作用,因为其他所有内容都已提交,但如果你希望它只是同步删除操作,那么你可能需要花些时间找到一些编辑的正确提交。 - jbo5112
32个回答

2368

对于Git 1.x版本

$ git add -u

这会让Git自动暂存被跟踪的文件,包括之前被跟踪的文件的删除。

对于Git 2.0版本:

要暂存整个工作目录:

$ git add -u :/

仅将当前路径加入暂存区:

$ git add -u .

142
注意,这将添加所有已更改、被跟踪的文件--已删除和已更新。 - Ian Hunter
20
如果你只想修改特定的文件,只需提供该文件的路径即可,不必选取所有文件。例如,git add -u [路径]。 - Paul Prewett
28
也可以使用 git add -u folder/ 命令来在一个文件夹中运行此操作。 - c..
3
FYI:此答案合并自http://stackoverflow.com/questions/1402776/how-do-i-commit-all-deleted-files-in-git - Shog9
4
这可能是人们来到这个页面时所问的问题,也可能是OP实际上想要问的问题,但它并没有回答所问的确切问题。 - Relequestual
显示剩余6条评论

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

可能是你正在寻找的...它对我有用...


6
尝试在你的配置文件中添加以下别名,如Evan Moran所述,不包括引号:'remove = !git ls-files --deleted -z | xargs -0 git rm' 该别名用于将已删除的文件从Git仓库中彻底删除。 - C.LS
22
小心文件名中带有空格的文件。 - maazza
46
@DaveEveritt git ls-files --deleted -z | xargs -0 git rm - Max Nanasy
16
如Cody所建议的那样,使用“git add -u”是一种更简单、更安全的方法,不会有意外删除文件的风险。 - Roland
6
由于这个回答有误,即使对某些文件可行,我会将其下降评分。请使用下面的命令 "git add -u"。那才是正确的用法。 - n13
显示剩余14条评论

754

您可以使用

git add -u

将已删除的文件添加到暂存区,然后提交它们

git commit -m "Deleted files manually"

104
请注意,谷歌用户:它还会将修改过的跟踪文件添加到暂存区。 - erenon
5
只有在你刚刚删除了文件并希望立即将它们加入暂存区时才运行此命令。 - Aryo
2
我无法从Bitbucket仓库中删除文件。 - srinivas gowda

361

如果您只是简单地运行:

git add -u

Git将更新其索引,以知道您已删除的文件实际上应该成为下一个提交的一部分。然后,您可以运行"git commit"来提交更改。

或者,如果您运行:

git commit -a

它将自动接受这些更改(和其他任何更改)并提交它们。

更新: 如果您只想添加已删除的文件,请尝试:

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

2
对的,git commit -a 命令可以实现我想要的功能,但是在某些情况下,我有一些不想提交的文件,因此我希望手动准备提交。 - Igor Zevaka
2
commit -a 实际上首先执行了 "add -u" 命令;它会将已知文件的任何更改(无论是删除还是简单更改)更新到索引中。当然,您也可以更具体地添加/删除您想要的文件。http://git.or.cz/gitwiki/GitFaq#Whyis.22gitrm.22nottheinverseof.22gitadd.22.3F 可能会有所帮助。 - Emil Sit
2
"Update: .." 下面的命令集非常好用。谢谢! - Jay Taylor
10
非常感谢您使用 'git ls-files --deleted | xargs git rm' 命令! - mit
18
"git ls-files --deleted | xargs git rm"是正确的答案!谢谢!" - reto
显示剩余4条评论

170

你可能正在寻找-A:

git add -A

这与git add -u类似,但还会添加新文件。这大致相当于hg的addremove命令(尽管移动检测是自动的)。


9
顺便提一下,使用"-u"选项只会将更改添加到已跟踪的文件中,而使用"-a"选项则会将未跟踪的文件也包括在内。我只是想指出这两者之间的区别。 - spaaarky21
在这个阶段,你可以考虑添加 -a 标志以提交所有更改。 - Zac Grierson

97

仅暂存被删除的文件:

for x in $(git status | grep deleted | awk '{print $2}'); do git rm $x; done

或者(使用xargs):

git status | awk '/deleted/ {print $2}' | xargs git rm

你可以使用别名来方便地使用你喜欢的命令集。


2
@Saeb 理解队列,但是掌握 xargs 大约需要 15 分钟。 - Eric Wilson
11
git status | awk '/deleted/ {print $3}' | xargs git rm 可以更简洁地完成这个操作。grep | awk... 坚决拒绝。 - Mark Reed
62
git rm $(git ls-files --deleted) 这样做不是更方便吗?(摘自 这里 - Hotschke
1
Saeb的预览回答:for x in ``git status | grep deleted | awk '{print $3}'``; do echo $x; done (将双反引号替换为单引号); SO的标记转义似乎不起作用。 - fazy
2
@Andrew 对于大型列表,xargs 比 while 循环更有效率,因为它每次执行 git rm 时会传递多个参数。为了限制每次执行 git rm 时传递的参数数量,请使用 -n 选项:git ls-files --deleted | xargs -n 15 git rm - Ajedi32
显示剩余4条评论

65
git rm test.txt
在你删除实际文件之前或之后。

7
虽然这样做可以达到目的,但我经常会通过使用 rm 命令删除大量文件,之后感到后悔。 - carl
4
为什么这比使用“git add -u”更糟糕?似乎将被删除的特定文件添加到提交中比添加所有更改更安全。 - Ian Dunn
2
实际上,根据问题的最后一行“我只想要一个命令,删除所有在git中也从磁盘中删除的文件”,这应该是最佳答案。 - Ramsharan
2
@Ramsharan 不行,因为它根本不会这样做。这只删除一个文件;OP明确要求删除“所有”文件。 - Adam
1
@Adam,我在项目中通常使用“git rm 文件名”或“git rm 文件夹/*”,这对我来说通常已经足够了。 - Ramsharan
显示剩余6条评论

50

使用带有“--all”或“--update”选项的git-add命令可能会添加您不想要的文件。新文件和/或修改过的文件也将被添加到索引中。我设置了一个Bash别名,以便在不影响其他文件的情况下从git中删除已删除的文件:

alias grma='git ls-files --deleted -z | xargs -0 git rm'

所有已从文件系统中删除的文件都会被添加到索引中以表示已删除。


41

虽然这并不重要,但我不同意所选择的答案:

git add -u 

如果工作树中对应的文件已被删除,那么该命令将从索引中删除这些文件,但它还将暂存已跟踪文件的修改后新内容。

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

另一方面,它只会删除已被跟踪的已删除文件。

因此,在我看来,后者是更好的选择。


31

如果这些是唯一的更改,你可以简单地执行

git commit -a

提交所有更改。这将包括已删除的文件。


3
不确定为什么我被踩了;Git 能够很好地识别已删除的文件,即使你没有使用 git rm 明确告诉它。 - SpoonMeiser
你被踩了一下,因为“-a”不是一个可接受的开关,应该是“-A”。请修改你的回答。 - Sheharyar
11
“-a”是一个可以接受的开关,因为命令是“commit”。而“-A”是一个用于“add”而不是“commit”的开关。我看到你建议的编辑已经被拒绝了。 - SpoonMeiser
如果你只是提交了已删除的文件,那么请添加 --allow-empty 开关。 - billrichards
错误,实际上只有在执行了 git rm --cached 命令后才需要使用 --allow-empty。 - billrichards

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接