我想找出某个目录中哪些文件不是由Git管理的。我之所以如此,是因为我使用 Git 进行备份,并且我希望最终将所有文件都保存在其中。
什么unix工具可以完成这个任务?有没有一种方法可以以find
相当有效的方式做到这一点?
例子:
我有一个文件夹,用于存储 RFC 相关的内容,如下所示:
.
├── TheFile
└── tests
├── 4180
│ └── data
│ ├── bad
│ └── good
│ └── linebreaks.csv
├── get-rfc.sh
├── .git <contents omited>
├── LICENSE
├── README
└── rfc4180.txt
我正在寻找一个可以输出我的命令:
TheFile
答案1
find the_starting_dir \( -type d -exec test -d '{}'/.git \; -prune \) -o -print
不是最可移植的 find 调用,但可以与 GNU find 一起使用。
Find 遍历目录树。该术语-prune
返回 true,但停止find
进一步处理子树。所以左边说-o
“如果这是一个目录,并且如果test
说有一个子目录被调用.git
,并且如果prune
返回 true 那么我们就完成了树中这个东西的处理”。右侧显示“否则打印”
如果您不想打印目录,请更改-print
为\( ! -type d -print \)
,但您将不会收到有关空目录的任何指示。
您可以将 更改-print
为-ls
来获取列表,-printf
参见手册等等等等
答案2
我不明白你为什么不想使用 git...
git status --untracked-files
[编辑]
据我了解该请求,有一个目录树。在这棵树中,有多个 git 存储库,但没有一个覆盖整个树。该示例显示了测试子目录中的 git 存储库。因此,您建议的命令将收到 git error fatal: Not in a git repositoryrather not TheFile as required。
find . -name .git -exec echo $(realpath '{}') \; |\
sed 's/\(.*\)\(.git\)/git --git-dir=\1\2 --work-tree=\1 status --untracked-files/g' | bash
答案3
您的要求中有很多具体案例。
- 实际上位于 git 管理的目录之外的文件。
- 你的
TheFile
适合这种情况。
- 你的
- 由 Git 管理的目录内的文件,带有一些
.git
标记。.git
并不总是一个目录。它也可以是一个文件,带有真实 GIT_DIR 的路径。我们可以将这些文件进一步细分如下:- 已知文件,即 Git 索引中存在的文件。
- 忽略的文件,那些与以下模式匹配的文件
gitignore(5)
:.gitignore
$HOME/.config/git/ignore
$GIT_DIR/info/exclude
- 实际
$GIT_DIR
目录下的文件,但是不是回购协议的一部分。.git/hooks
最有可能的是- 也可能是恶意软件
因此,最可靠的情况是,相对于给定的基本目录生成两个列表$D
,并对它们进行比较(确保事先对它们进行排序并删除重复项)。
我想不出一种可靠的方法来生成上面 2.3 的子列表,所以我将其作为一个开放问题(我很想知道它,因为我之前已经失去了钩子)。
根据上述 2.1 列出已知文件的 Shell 脚本:
for g in $(find $D -name .git) ; do
echo $g
p=${g%/.git} g2=`readlink -f $g` ;
( cd $p && GIT_DIR=$g2 \
git ls-files --exclude-standard --full-name ) \
| sed "s,^,${p}/,g" ;
done > list-2.1
根据上述 2.2 列出被忽略文件的 Shell 脚本:
for g in $(find $D -name .git) ; do
p=${g%/.git} g2=`readlink -f $g` ;
( cd $p && GIT_DIR=$g2 \
git ls-files \
--others -i --exclude-standard ) \
| sed "s,^,${p}/,g" ;
done > list-2.2
根据上述 2.3 列出文件的 Shell 脚本:
TODO > list-2.3
用于处理列表并查找 B 面没有的内容的 Shell 脚本:
comm -23 <(find $D ! -type d |sort) <(sort 2.1 2.2 2.3 | uniq)
答案4
find <root_dir> -type d -name ".git"
这是你想要的 ?
你也可以做类似的事情
find <root_dir> -type d -name ".git" -print0 | xargs -0 -r dirname
仅输出不带/.git
部分的目录名称;您甚至可以避免并仅在每个文件夹名称末尾使用plusdirname
的输出。find
/../
find <root_dir> -type d -name ".git" -print0 | xargs -0 -r printf "%s/../"
编辑
您可以否定该-name
参数并使用该-maxdepth
值;例如,我可以轻松列出内核树中名称不以 a c
(大写或小写)开头的所有目录。
find linux-4.8.2/ -type d ! -iname "c*" -maxdepth 1
我还是不太明白你的意思:
我正在寻找与此完全相反的命令,即查找不在 Git 存储库中的所有文件的命令;
只是因为根目录的同一文件系统上的同一目录中的文件.git
甚至可能不是存储库的一部分,这只是意味着从字面上看,存在目录的同一目录(或子目录)中存在文件命名.git
也。请记住,git
有一个概念分期一般来说,你在磁盘上看到的可能不是你的 git 存储库。
看一眼https://libgit2.github.com/这是 git 的官方 C 库,有很多绑定,还有很多文档、示例以及如何 .