根据扩展名将 git 个 repo 文件移动到子文件夹

Move git repo files to subfolders according to extension

我想做什么

我的 repo 中的所有文件都在一个文件夹中,但此文件夹包含 .gitignore 排除的其他文件。我想根据它们的扩展名(以编程方式)将这些文件(而不是那些被忽略的文件)重新组织到不同的文件夹中。

示例。

假设我有一个文件夹 /project 包含:
a.pyb.pyc.py1.png2.png3.png
其中
- a.pyb.py1.png2.png 在 git 仓库中;
- c.py3.png 在 git 仓库中 不是 ,即根据 .gitignore 中的规则忽略它们。

最后我想要两个子文件夹:
- /project/scripts 包含 a.pyb.py
- /project/images 包含 1.png2.png

- /project 仍然包含 c.py3.png.

一些想法

我阅读了 git mv 命令的文档,但我没有看到我可以直接从 git mv 命令过滤文件。

一个想法是使用 git ls-files 从存储库中列出这些文件,然后将其通过管道传输到 git mv。但我怀疑这是 as bad as piping ls and mv

作为最后的手段,我可​​以使用 for 循环,但我相信有人知道得更多。事实上,我不确定这是否会规避管道 lsmv.

的问题

文件名格式

文件名不是特别奇特:除了扩展名(.py.png),它们只包含字母数字字符 [a-zA-Z0-9]、连字符 - 和下划线_。所以管道 git ls-filesgit mv 可能不是世界末日。

假设现在您的文件在 project 目录中并且您只想将跟踪的文件移动到可以使用的不同目录

mkdir scripts images
find project/ -name "*.py" -exec git mv -k {} scripts/ \;
find project/ -name "*.png" -exec git mv -k {} images/ \;
git commit

您会找到与特定模式匹配的所有文件。然后您将移动这些文件,但前提是它们被 git 跟踪到指定的文件夹。否则 git mv 命令将跳过这些文件(例如因为它们被 .gitignore 忽略)。

来自 git mv 手册页:

   -k
       Skip move or rename actions which would lead to an error condition.
       An error happens when a source is neither existing nor controlled by Git, or
       when it would overwrite an existing file unless -f is given.

实际上您可以省略 -k 选项,因为 git mv 命令会针对已找到的每个文件执行。它只会打印一条错误消息并继续处理剩余的文件。另一方面,一次对多个文件执行 git mv 时需要它(例如 git mv project/* new_folder/),因为在这种情况下它只会以错误结束并忽略剩余的文件。