列出未存储在 Git 存储库中的文件

列出未存储在 Git 存储库中的文件

我想找出某个目录中哪些文件不是由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

您的要求中有很多具体案例。

  1. 实际上位于 git 管理的目录之外的文件。
    • 你的TheFile适合这种情况。
  2. 由 Git 管理的目录内的文件,带有一些.git标记。 .git并不总是一个目录。它也可以是一个文件,带有真实 GIT_DIR 的路径。我们可以将这些文件进一步细分如下:
    1. 已知文件,即 Git 索引中存在的文件。
    2. 忽略的文件,那些与以下模式匹配的文件gitignore(5)
      • .gitignore
      • $HOME/.config/git/ignore
      • $GIT_DIR/info/exclude
    3. 实际$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 库,有很多绑定,还有很多文档、示例以及如何 .

相关内容