从 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 vim
或git 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' 警惕名称中带有空格的文件 @DaveEverittgit 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 <filenames>
仅暂存已删除的文件。
例如,如果您删除了文件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从存储库中删除了几个文件,并且存在巨大的提交差异