从 Git 存储库中删除已从磁盘中删除的多个文件

Posted

技术标签:

【中文标题】从 Git 存储库中删除已从磁盘中删除的多个文件【英文标题】:Removing multiple files from a Git repo that have already been deleted from disk 【发布时间】:2010-10-04 07:14:14 【问题描述】:

我有一个 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 . 相同的工作方式。

【问题讨论】:

相关:***.com/questions/1856654/… @seth,使用git rm 并不总是很方便,删除可能来自单独的工具、IDE 或文件管理器。删除/重命名文件时,Visual Studio for one 可能会很痛苦。 呃,问为什么有人不使用git rm 有点像问他们为什么不使用git vimgit cd。这是一件愚蠢的事情,git应该有一个内置的命令或别名来从staging中删除已删除的文件,你不应该在SO上查找它或在午休时间阅读手册页。跨度> Varinder 的回答不是一个好办法。按照 Cody 的建议考虑 git add -u ,这也是这个问题的答案:***.com/questions/1402776/… How to add and commit removals made with "rm" instead of "git rm"?的可能重复 【参考方案1】:

你可以使用

git add -u

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

git commit -m "Deleted files manually"

【讨论】:

请注意谷歌用户:它也会将修改后的跟踪文件添加到暂存区。 仅当您刚刚删除文件并希望立即暂存它们时才运行此命令。 我无法从 bitbucket repo 中删除文件]【参考方案2】:

类似

git status | sed -s "s/^.*deleted: //" | xargs git rm 

可以。

【讨论】:

2019 git 版本 2.13.3:git diff --diff-filter=D --name-only | xargs git rm【参考方案3】:

如果这些是唯一的变化,你可以简单地做

git commit -a

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

【讨论】:

不知道为什么我被否决了; git 可以很好地识别已删除的文件,即使您没有使用 git rm 明确告知它。 你被否决了,因为“-a”不是一个可接受的开关,它是“-A”。编辑你的答案。 不,“-a”可接受的开关,因为命令是commit。 "-A" 是切换到 add 但不是 commit。我看到您建议的修改已被拒绝。 如果您要提交的唯一内容是已删除的文件,请添加开关 --allow-empty err,实际上 --allow-empty 只有在你执行 git rm --cached 时才需要【参考方案4】:

您可能正在寻找 -A:

git add -A

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

【讨论】:

顺便说一下,使用 -u 会限制添加到已跟踪的文件,而 -a 也将包括未跟踪的文件。只是想我会指出其中的区别。 在这个阶段你不妨通过 commit -a 标志添加所有内容。【参考方案5】:

通过将 git-add 与“--all”或“--update”选项一起使用,您可能会得到比您想要的更多的东西。新的和/或修改的文件也将被添加到索引中。当我想从 git 中删除已删除的文件而不触及其他文件时,我有一个 bash 别名设置:

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

已从文件系统中删除的所有文件都将作为已删除添加到索引中。

【讨论】:

【参考方案6】:

git-add 的任何标志都不会只暂存已删除的文件;如果你修改的只是被删除的文件,那么你很好,否则,你需要运行 git-status 并解析输出。

根据杰里米的回答,这就是我得到的:

git status |  sed -s "s/^.*deleted: //" | grep "\(\#\|commit\)" -v | xargs git rm
    获取文件状态。 对于已删除的文件,隔离文件名。 删除所有以#s 开头的行,以及其中包含“已删除”字样的状态行;我不记得它到底是什么,而且它不再存在了,所以你可能需要针对不同的情况进行修改。我认为表达式分组可能是 GNU 特有的功能,因此如果您不使用 gnutils,则可能需要添加多个 grep -v 行。 将文件传递给git rm

现在将其粘贴到 shell 别名中...

【讨论】:

【参考方案7】:

对于 Git 1.x

$ git add -u

这告诉 git 自动暂存跟踪的文件——包括删除以前跟踪的文件。

对于 Git 2.0

展示你的整个工作树:

$ git add -u :/

仅暂存当前路径:

$ git add -u .

【讨论】:

请注意,这将添加 所有 个已更改、跟踪的文件 -- 已删除和更新。 @beanland,如果您不希望它全部获取,您只需提供要修改的特定文件的路径。例如git add -u [路径] git add -u folder/ 在文件夹中运行此操作 仅供参考:此答案合并自 ***.com/questions/1402776/… 这可能是人们在到达此页面时提出的问题,也可能是 OP 的实际意思,但它并没有回答所提出的确切问题。【参考方案8】:
git rm test.txt

在您删除实际文件之前或之后。

【讨论】:

虽然它会起作用,但我经常发现自己通过 rm 删除了大量文件,后来又后悔了。 为什么这比git add -u 更糟糕?似乎将已删除的特定文件添加到提交中比添加 ALL 更改更安全。 实际上这应该是根据问题的最后一行“我只想要一个命令从 git 中删除所有文件的命令,这些文件也从磁盘中删除。” @Ramsharan 不,因为它根本不这样做。这会删除一个文件; OP 明确要求“所有”已删除文件。 @Ramsharan 不,这就是重点 - 在几乎所有情况下,您都不能简单地使用通配符(没有匹配的通配符)。这就是为什么主要的答案要复杂得多。【参考方案9】:

如果你只是运行:

git add -u

git 将更新它的索引,以知道您删除的文件实际上应该是下一次提交的一部分。然后你可以运行“git commit”来签入该更改。

或者,如果你运行:

git commit -a

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

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

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

【讨论】:

对,git commit -a 会做我想做的事,除非在某些情况下我有不想提交的文件,所以我想手动准备提交。 commit -a 本质上是先执行“add -u”;它将使用对已知文件的任何更改(无论是删除还是简单更改)来更新索引。您当然可以更具体,只添加/rm 您想要的文件。 git.or.cz/gitwiki/… 可能会有所帮助。 “更新:..”下面的命令集就像一个魅力。谢谢! 非常感谢'git ls-files --deleted | xargs git rm' ! "git ls-files --deleted | xargs git rm" 是正确答案!谢谢!【参考方案10】:
git ls-files --deleted -z | xargs -0 git rm 

可能是你要找的东西..它对我有用..

【讨论】:

对于 Windows 尝试在您的配置中添加以下别名,而不是 Evan Moran 上面所述的引号 'remove = !git ls-files --deleted -z | xargs -0 git rm' 警惕名称中带有空格的文件 @DaveEveritt git ls-files --deleted -z | xargs -0 git rm git add -u 正如 Cody 建议的那样,是一种更简单、更安全的方法,不会有意外删除文件的风险。 投反对票,因为它是错误的答案,即使它可能适用于某些文件。使用下面的“git add -u”。这就是它的用途。【参考方案11】:

我也需要同样的 并使用 git gui“阶段更改”按钮。 它还添加了所有内容。

在“阶段改变”之后,我做了“提交”......

所以我的工作目录又干净了。

【讨论】:

使用 gui 就是作弊,哈哈!但在 GUI 设计器满足您的需求的情况下更快。知道如何修补“引擎盖下的东西”是件好事。 仅供参考:此答案合并自 ***.com/questions/1402776/…【参考方案12】:

仅暂存已删除的文件:

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

您可以alias您喜欢的命令集,方便以后使用。

【讨论】:

@Saeb 了解队列,但 xargs 大约需要 15 分钟才能掌握。 git status | awk '/deleted/ print $3' | xargs git rm 将是一种更短的方法。 grep | awk... 说不。 git rm $(git ls-files --deleted) 是不是更方便(复制自this)。 xargs 或上面的 $() 替换,如果你知道列表不是很大的话。如果列表 很大:git ls-files --deleted | while read f; do git rm $f; done @Andrew xargs 对于一个巨大的列表来说可能比 while 循环更有效,因为它每次执行 git rm 时都会传递多个参数。要限制每次执行时传递给git rm 的参数数量,请使用-n 选项:git ls-files --deleted | xargs -n 15 git rm【参考方案13】:

如前所述

git add -u

将已删除的文件暂存以进行删除,同时对已修改的文件进行更新。

要取消暂存修改后的文件,您可以这样做

git reset HEAD <path>

如果您想保持提交的组织和整洁。注意:这也可以取消暂存已删除的文件,因此请小心使用这些通配符。

【讨论】:

【参考方案14】:

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

git add -u 

... 如果工作树中的相应文件已被删除,则将从索引中删除文件,但它也会暂存已修改的跟踪文件的新内容。

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

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

所以我认为后者是更好的选择。

【讨论】:

【参考方案15】:

如果您想将其添加到您的 .gitconfig,请执行以下操作:

[alias]
  rma = !git ls-files --deleted -z | xargs -0 git rm

那么你所要做的就是运行:

git rma

【讨论】:

和来自命令行git config --global alias.rmd '!git ls-files --deleted -z | xargs -0 git rm'【参考方案16】:
git ls-files --deleted | xargs git rm 

是仅添加已删除文件的最佳选择。

这里有一些其他选项。

git add .  => Add all (tracked and modified)/new files in the working tree.

git add -u => Add all modified/removed files which are tracked.

git add -A => Add all (tracked and modified)/(tracked and removed)/new files in the working tree.

git commit -a -m "commit message" - Add and commit modified/removed files which are tracked.

【讨论】:

【参考方案17】:

迄今为止我发现的最灵活的解决方案是

git cola

然后选择我要暂存的所有已删除文件。

(请注意,我通常在 git 中使用命令行执行所有操作,但 git 处理删除的文件有点笨拙)。

【讨论】:

通配符不适用于git add -u path/to/my/deleted-files-pattern-*.yml,所以这对我来说是最好的答案(不想暂存所有已删除的文件,而是数百个文件中的 50 个)。【参考方案18】:

您可以使用git add -u &lt;filenames&gt; 仅暂存已删除的文件。

例如,如果您删除了文件templates/*.tpl,则使用git add -u templates/*.tpl

-u 是必需的,以便引用存储库中存在但工作目录中不再存在的文件。否则,git add 的默认设置是在工作目录中查找文件,如果您指定已删除的文件,则不会找到。

【讨论】:

【参考方案19】:

即使您有很多文件要处理,以下操作也可以:

git ls-files --deleted | xargs git rm

您可能还想提交评论。

详情见:Useful Git Scripts

【讨论】:

【参考方案20】:
git ls-files --deleted -z | xargs -0 git rm --cached

这将删除之前由 git 跟踪的所有已删除文件,并处理文件名中包含空格的情况。

根据您的 POSIX 变体,您可能需要使用 xargs -0 -r:这将导致 xargs 在管道空内容时正常退出。

编辑:--cached--deleted 标志一起使用,以防止意外删除尚未删除的文件。

【讨论】:

【参考方案21】:

对于视觉工作室项目

'git ls-files --deleted | sed 's/(.*)/"\1"/'| xargs git rm' 

当删除的文件路径有空间时很有用

【讨论】:

【参考方案22】:

为暂存已删除文件添加系统别名作为命令rm-all

UNIX alias rm-all='git rm $(git ls-files --deleted)'

Windows doskey rm-all=bash -c "git rm $(git ls-files --deleted)"

注意

Windows 需要安装 bash

【讨论】:

【参考方案23】:
git commit -m 'commit msg' $(git ls-files --deleted)

在我删除文件后,这对我有用。

【讨论】:

【参考方案24】:

git add -u

-u - 更新 只匹配索引中已经跟踪的文件而不是工作树。这意味着它永远不会暂存新文件,但它将暂存已修改的跟踪文件的新内容,并且如果工作树中的相应文件已被删除,它将从索引中删除文件。

如果没有给出,默认为“.”;换句话说,更新当前目录及其子目录中的所有跟踪文件。

【讨论】:

The top-voted answer 已经说过要使用git add -u。您的答案中的所有其他内容来自哪里,文档?如果有,您应该链接到文档并引用它。【参考方案25】:

告诉命令自动暂存已修改和删除的文件,但未告诉 Git 的新文件不受影响:

-a --全部

git add . && git commit -m -a "Your commit"

git add --all && git commit -m "Your commit"

【讨论】:

git add --all && git commit -m "Your commit" 这在 windows-7 中对我有用,使用 Git bash 命令 shell。 以下命令在 windows-7 中为我工作,使用 Git bash 命令外壳:$ git add --all && git commit -m "remove property files" [master 58c41ac] 删除属性文件 1 个文件已更改,9 个删除(-)...然后将已提交的更改推送到远程存储库已运行:$ git push origin .. 计数对象:10,完成。 【参考方案26】:

这个简单的解决方案对我来说很好用:

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

【讨论】:

我认为您应该始终在当前工作目录上使用 git shell 这很好很简单,但不适用于递归文件夹。 @BehnazChangizi 我认为是的,***.com/questions/1054044/… @PvdL 不接受路径中的空格是操作系统特有的问题【参考方案27】:

请使用-t 查看实际运行的是哪个命令

我刚刚调整了 Virender 的答案来做同样的事情:

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

【讨论】:

【参考方案28】:

(另一种变体)

我想从磁盘文件中删除所有已删除的文件,但从一个特定文件夹中删除,而其他文件夹保持不变。以下对我有用:

git ls-files --deleted  | grep <folder-name> | xargs git rm

【讨论】:

【参考方案29】:
git rm $(git ls-files -d)

删除git ls-files 命令列出的所有文件(-d 仅显示已删除的文件)。不适用于文件名或路径中有空格但容易记住的文件

【讨论】:

【参考方案30】:

只是简单

git add . && git commit -m "the message for commit" && git push

【讨论】:

以上是关于从 Git 存储库中删除已从磁盘中删除的多个文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 git bash 屏幕中删除文件并从存储库中删除该文件? [复制]

GIt:使用BFG从存储库中删除了几个文件,并且存在巨大的提交差异

如何在不从磁盘中删除文件的情况下 git rm 文件? [复制]

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

轻松安装已从 CRAN 存储库中删除的软件包

如何从 git 存储库中删除文件而不实际删除文件 [重复]