git diff - 只显示更改的目录

21

有没有一种方法只列出已更改的目录?

比如说我在git根目录中,~/project

我更改的文件是

~/project/subtool/file1

~/project/subtool/file2

~/project/subtool3/file1

我只想要

~/project/subtool

~/project/subtool3


5个回答

38

您可以使用git-diff命令,并带上--dirstat参数。

在您的场景中,假设您有以下提交记录:

$ git diff --name-status HEAD~1
M       subtool/file1
M       subtool/file2
M       subtool3/file1

它将产生以下输出:
$ git diff --dirstat=files,0 HEAD~1
  66.6% subtool/
  33.3% subtool3/

请确保添加,0,否则git diff默认仅显示至少有3%更改的目录。我也选择了文件,因为这是计算成本最小的选项,而且您似乎也不关心具体的更改。

如果您能够使用sed,则可以摆脱百分比值(您可能需要微调正则表达式以适应您的需求):

$ git diff --dirstat=files,0 HEAD~1 | sed 's/^[ 0-9.]\+% //g'
subtool/
subtool3/

1
这非常完美!有没有办法避免输出%的细节呢?我想将目录读入脚本并将其用于某些事情:wq - Nishant Roy
3
如果你正在编写脚本,那么 git diff-tree 就是为此而构建的。doit() { git diff-tree "$@" | awk '$1$2~/04/' | cut -f2-; } - jthill
2
在 macOS 上,sed 正则表达式对我无效。使用的是日期为 2005 年 5 月 10 日的 BSD sed。 - user918510
5
在 macOS 的 zsh shell 中,我必须在 sed 命令中添加 -E 标志,并从 \+ 中移除正斜杠。这是我使用的命令:sed -E 's/^[ 0-9.]+% //g' - Doug Ayers
4
通过将输出导入到另一个sed命令中,您可以删除所有子文件夹名称,以便只剩下顶层文件夹。git diff --dirstat=files,0 HEAD~1 | sed -E 's/^[ 0-9.]+% //g' | sed -E 's/\/.*$//g' - Doug Ayers
显示剩余4条评论

10
这个解决方案同样适用于根目录中的文件:
git diff --name-only HEAD~1 | awk -F "/*[^/]*/*$" '{ print ($1 == "" ? "." : $1); }' | sort | uniq

根目录的变更将会被标记为.

git diff --dirstat=files,0 HEAD~1 的限制在于它无法展示根目录的变更。


这段程序相关的内容需要翻译成中文。请返回仅翻译后的文本:这会导致某些重复。如果我有dir/foo/file-a,它会显示dir和dir/foo。 - The Fool
@TheFool 我通过对 Lari Hotari 的答案进行更新,将我的答案添加在这里。您可以在此处找到它:https://dev59.com/vlUL5IYBdhLWcg3wYXF8#72781954 - 5war00p

5

这里提供一个替代方案,使用xargsdirname而不是像sedawk那样的工具。

git diff HEAD~1 --name-only | xargs dirname | sort | uniq
  1. git diff … 将列出修改的文件路径。
  2. | xargs dirname 将文件路径转换为目录路径。
  3. | sort | uniq 将删除重复项。

请注意,如果您修改了存储库根目录中的任何文件,则会生成一行.


0

在采用@Lari Hotari的建议中添加split和uniq选项后,可以获取已修改的唯一目录。

$(git diff --name-only HEAD~1 | awk -F "/*[^/]*/*$" '{ print ($1 == "" ? "." : $1); }' | cut -d "/" -f 1 | sort | uniq)

这个命令是做什么的?
  • 首先它找到所有修改过的文件,并返回已更改文件的父目录@Lari Hotari [answer][1]
  • 下一部分是使用“ /”分割字符串数组并返回第一个元素,即更改文件的根目录。

此命令将监视monorepo中子项目的所有更改,并可以使用 npm i -ws 命令仅为更改的工作区安装依赖项


为此,您甚至不需要awk:git diff --name-only | cut -d/ -f1 | uniq还会给出更改模块的根目录。 - The Fool
是的,但在我的脑海中,我只想要根目录而不是文件,所以在 awk 之后添加了这一步骤。因为我正在安装特定的工作区。 - 5war00p
是的,正如我所说,你只能用那个命令获取目录。是 cut 命令在起作用,而不是 awk。你可以完全省略 awk 部分。 - The Fool

-2
使用带有参数--dirstat的git diff,例如:
git diff --dirstat HEAD~100..HEAD

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