删除除.git文件夹外的所有文件的Linux命令是什么?

45

我想在将新文件复制到分支之前删除当前目录的所有内容,除了.git/文件夹

这个操作用什么Linux命令?


4
在大多数情况下,我会只执行 rm -rf * 命令,这将跳过所有以点开头的文件,然后根据需要手动删除剩余的文件。如果你想更加高级一些,可以使用 find 命令,但有时只需执行 ls -A > /tmp/doit 命令,然后编辑 /tmp/doit 文件以删除除 .git 以外的所有内容,这通常更容易实现。 - torek
5
或者将.git文件夹暂时移动到另一个文件夹中,然后删除所有内容,最后再将其移回原来的位置。 - CrayonViolent
如果您需要在克隆后立即执行此操作,则可以使用“-n”(“--no-checkout”)选项进行克隆:git clone -n -b <branch> <repository> <directory> - Mike Shiyan
几乎是重复的问题,但适用于任何文件/目录:https://unix.stackexchange.com/questions/153862/remove-all-files-directories-except-for-one-file - Devin Rhode
7个回答

84

重置索引的成本很低,因此

git rm -rf .
git clean -fxd

接着你可以通过使用git reset命令来重置索引或者直接切换到新分支。


2
不错!这是一个很好的 Git 特定解决方案,我之前并不知道,这在这种情况下可能是更好的解决方案。 - cincodenada
重置索引,git resetgit checkout都无法正常工作。我必须使用git reset --hard - Trần Việt Hoàng
1
巧妙地使用“-x”选项来绕过gitignore。 - Andry
在这里添加 git reset --hard 作为第一个命令会有任何好处吗? - Devin Rhode
如果我们需要删除跟踪器文件:git update-ref -d refs/heads/ - nextloop

19

使用查找和修剪选项。

find . -path ./.git -prune -o -exec rm -rf {} \; 2> /dev/null


编辑: 对于两个目录.gitdist

find . -path ./.git -prune -o \( \! -path ./dist \) -exec rm -rf {} \; 2> /dev/null

1
不会删除任何文件夹 - Eric Steinborn
PxL,如果您能够抑制我收到的“没有此文件或目录”的错误,那么这将是我首选的答案。 - Eric Steinborn
1
@EricSteinborn:将stderr重定向到空文件中。 - P̲̳x͓L̳
1
嗯...我认为通常来说将所有可能的错误重定向到null并不是一个好主意。 为什么不使用find选项-delete而不是执行rm呢? - Antonio
@Antonio: 我同意你关于重定向错误的看法。从-delete选项的文档中可以得知: 由于-delete隐含了-depth,因此您不能有用地同时使用-prune和-delete。 - P̲̳x͓L̳
显示剩余6条评论

14

正如Crayon在评论中提到的那样,简单的解决方案是将.git移出目录,删除所有内容,然后再将其移回来。但如果你想以花哨的方式解决问题,find可以帮助你:

find -not -path "./.git/*" -not -name ".git" | grep git
find -not -path "./.git/*" -not -name ".git" -delete

我加入了第一行代码是因为使用find命令时,我总是想要在运行-delete之前再次确认它是否找到了我认为的那个文件。

编辑:添加了-not -name ".git",这将防止尝试删除.git目录并抑制错误。根据find尝试删除的顺序,它可能无法删除非空目录。


这需要运行第一行吗? - Eric Steinborn
回答了自己的问题,不。 - Eric Steinborn
所以这个程序可以正常工作,但我感觉非引用版本更被广泛接受为正确答案。 - Eric Steinborn
1
这个答案与被接受的答案之间的主要区别不在于引号(我有引号来保护免受 shell 尝试过早扩展 glob 的影响),而是 -prune。这是完成相同任务的不同方式。至于第一行:任何时候运行 find -delete,都应该先运行没有 -delete 的命令,以确保您不会做出意外的操作。 - cincodenada
1
很好的答案。当将“-path "./.git/"”替换为“-path "/.git/*"”时,它可以用于排除在一个共同目录下的多个git存储库。像projects/project1/.gitprojects/project2/.git,然后可以直接在 projects/ 目录中运行此命令。 - Daniel F

11

一种方法是使用rm -rf *,将删除文件夹中除点文件和点文件夹(如.git)之外的所有文件。然后您可以逐个删除点文件和点文件夹,以便不会错过重要的点文件,如.gitignore.gitattributes等。

另一种方法是将您的.git文件夹移出目录,然后返回并删除文件夹的所有内容,最后再将.git文件夹移回去。

mv .git/ ../
cd ..
rm -rf folder/*
mv .git/ folder/
cd folder

1
我认为 rm -r * 是最好的解决方案。保留 .gitignore 和其他类似的文件可能非常重要。 - Matthew Mitchell

1
for i in `ls | grep -v ".git"` ; do rm -rf $i; done; rm .gitignore;

结尾处的附加rm将会删除特殊的.gitignore文件。如果你需要该文件,请去掉这个附加项。


1
用户想要删除除了.git文件之外的所有文件,而这些文件似乎是您正在删除的文件。 - Anshul Goyal
2
@mu無 他们使用了grep -v,这会反转匹配结果。但是当有更好的选项时,这仍然是一个非常笨拙的解决方案。 - cincodenada
@cincodenada 另一个问题是,这不会删除文件夹中剩余的点文件。另外,最初代码存在一些错误,现在已经进行了更正,这使我得到了“-bash:syntax error near unexpected token `|'” 的错误提示。 - Anshul Goyal
@TimWolla 你是对的,但如果那些特殊字符不能/不被用于文件名,生活会更加美好。 - Antonio

1
CB Bailey所提到的:
我想要删除tracker files的历史记录。
git rm -rf .
git clean -fxd
git update-ref -d refs/heads/master #or main or ...

-5
应该找到所有以名称 .git 结尾的文件和目录。
find .  -name .git

应该查找所有文件和目录,但不包括名为.git的文件夹

find . -not -name .git

删除所有找到的文件

find . -not -name .git -exec rm -vf {} \;

确保查找功能符合您的要求

如果您想删除目录,请将rm命令更改为rm -rvf,我包含了v选项以查看被删除的文件。

如果您想在删除文件之前确认它们,请将find命令导入文件并查看结果。


4
尝试运行find . -not -name .git | grep git命令-你会发现你正在尝试删除.git目录中的所有文件,因为它们的文件名中没有“.git”。你需要使用-path和通配符来解决这个问题。 - cincodenada
这就是为什么我在删除文件时使用了“-not”的命令。我会检查我的答案。 - DannyK
2
我的原始评论有一个错别字,我已经更正了。请查看我更正后的评论,了解为什么您需要更多地了解find命令的工作方式。 - cincodenada
好的,幸运的是它是一个 Git 仓库,我可以在测试后重新克隆。 - Eric Steinborn

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