删除除 .git 目录和 .git 在 linux 上忽略的所有内容

remove everything exept for .git directory and .gitignore on linux

您好,我正在尝试使用 linux 命令行删除文件夹中的所有内容,但 .git 目录和 .gitignore 文件

除外
#!/bin/bash

cd /git/
# remove old files
find . ! -name '.gitignore' ! -path '.git' ! -path '.git/*' -exec rm -rf {} \;

它有点用,它删除了所有东西,除了 .gitignore 文件。那么我还需要更改什么才能保留 .git 目录(及其所有文件和文件夹!)?

注意:执行脚本的用户有sudo权限

顺便说一句。当我 运行 它与 sudo sh cleanup.sh 控制台输出时:

rm: cannot remove directory: ‘.’
find: `./.git': No such file or directory
find: `./foo': No such file or directory

我 运行宁 Ubuntu 14.04

这里使用 find 没有多大意义,因为您只想保留顶级 .git 目录和 .gitignore 文件(如果我理解正确的话)。

请注意 rm -rf 是递归删除,因此您无需遍历目录树即可进行删除。由于 find 可能会选择在扫描 some_directory 的内容时执行 rm -rf ./some_directory,因此在 find 期间进行递归删除很可能会给您带来问题(例如find 突然找不到它认为知道的文件)。

-path 谓词的参数用于匹配 整个路径 ,从根参数开始(. 在你的情况下),所以 .git 不匹配 ./.git.

总的来说,我推荐(非常仔细,先用echo测试):

shopt -s extglob
echo rm -fr * .!(|.|git|gitignore)

rm 的第二个参数是一个扩展的 glob,意思是“一个点后跟除以下内容之外的任何内容:无或点或 gitignore。不包括 ... 非常重要,特别是如果您有 root 权限。

你可以运行这个:

find -mindepth 1 -depth -print0 | grep -vEzZ '(\.git(/|$)|/\.gitignore$)' | xargs -0 rm -rvf

但首先模拟它会做什么:

find -mindepth 1 -depth -print0 | grep -vEzZ '(\.git(/|$)|/\.gitignore$)' | xargs -0 echo rm -rvf

解释:

-mindepth 1 : 它将排除当前目录

-depth : 它会在文件夹之前列出文件

print0 :它会用一个空字符分隔每条记录,如果你的文件名包含空格就很方便

-path指的是find中的完整路径。 .git 不是完整路径,./.git 是。

因此,以下可能会起作用

find . ! -name '.gitignore' ! -path './.git' ! -path './.git/*' -exec echo rm -rf {} \;

但是,它仍然有 2 个递归点遍历相同的文件(findrm -r)。如果你想避免错误(特别是因为 find 预处理树的部分)你真的应该只有一个

find . -mindepth 1 -maxdepth 1 ! -name '.gitignore' ! -name '.git' -exec echo rm rf {} +

需要 -mindepth 以避免将当前工作目录 . 作为文件处理。

一样,删除 echo 以实际执行删除