如何仅列出在 Git 中修改过的 .png 文件

How to only list .png files that have been modified in Git

如何只列出 Git 当前分支中已修改的 png 文件?

我的目标是将这些文件复制到不同的目录(我需要发送电子邮件)。

假设我有:

$ git status
On branch update_assessment_pt1
Your branch is up-to-date with 'upstream/devel'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   assessment/LWR/validation/HbepR1/analysis/hbepr1_plot.py
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/AxialPowerProfile.pdf
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/AxialProfile.pdf
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/CladDisp.pdf
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/FissionGas.pdf
    modified:   assessment/LWR/validation/HbepR1/doc/figures/FissionGas.png
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/InterGasPress.pdf
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/Mesh.pdf
    deleted:    assessment/LWR/validation/HbepR1/doc/figures/Power.pdf
    modified:   assessment/LWR/validation/HbepR1/doc/figures/Power.png
    new file:   assessment/LWR/validation/IFA_431/analysis/ifa431_plot.py
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431_bol_rod_power.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r1.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r2.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r3.png

我如何获得以下文件,以便复制这些文件?

    modified:   assessment/LWR/validation/HbepR1/doc/figures/FissionGas.png
    modified:   assessment/LWR/validation/HbepR1/doc/figures/Power.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431_bol_rod_power.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r1.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r2.png
    modified:   assessment/LWR/validation/IFA_431/doc/figures/431r3.png

使用git diff --cached --diff-filter=M --name-only获取这些文件名。如果需要,请添加 -- '*.png' 以将列表过滤为仅 *.png 个文件——该命令将列出 any to be committed 状态为 M 的文件](已修改)。

避免仅作为 "use this magic command" 答案的注意事项

在文本中,您首先调用了这些在当前分支中修改。这个短语并不意味着任何一件具体的事情。幸运的是,您随后继续显示 git status 输出,它们列在 Changes to be committed.

Git 根本 store 差异。 Git 存储 快照 — 完整的完整文件,在主要存储单元内,即提交。这意味着为了看到 更改 ,您必须选择 两个 提交:$old 和 $new。 Git 将提取两者,然后比较它们。无论提交 $old 和提交 $new 之间有什么不同,Git 都会告诉你。实际更改可以是许多更改状态中的任何一个:

  • A表示已添加:文件不在$old中,在$new中。
  • M 表示已修改:$old 和 $new 之间的文件不同。区别可能只是文件的模式:是否可执行。
  • D 表示已删除:文件在 $old 中,但不在 $new 中。
  • RCT 和其他一些罕见的情况也可能发生,尽管其中一些可能需要额外的标志才能 git diff:你不会例如,除非您启用重命名检测,否则看不到 R 状态。 (重命名检测在最现代的 Git 版本中默认为 on,但在较旧的 Git 版本中默认为 off。)

使用 --name-statusgit diff 将显示文件名和状态字母,而不是显示实际差异。 (试试这个看看。)--diff-filter 参数让你告诉 Git: 只告诉我状态符合我选择的字母的文件。

请注意,顺便说一句,特殊名称 HEAD 始终表示 当前提交 。您如何使此提交成为当前提交并不重要,尽管一种典型的方法是使用 git checkout:您 git checkout 通过其哈希 ID 提交,例如,该提交现在已检出并且是当前提交。或者,您 git checkout 一个分支名称,并且该分支的 tip 提交现在已经结束并且是当前提交。总是有1一个当前提交,你可以通过全大写写名字HEAD来命名它。2

以上所有关于比较提交的讨论,但文件可以存在的其他两个地方不是提交。注意这两个都是暂时的:它们会被各种操作抹掉,一旦被抹掉,无法在[=195=中恢复]:您必须从这些临时位置复制到实际提交中,以使文件永久化。一旦文件提交,它们就会一直冻结,并且可以在将来恢复到有用的形式,只要提交本身存在(通常是 "forever",或者只要存储库存在)。

这两个地方是:

  • 索引,Git也称为暂存区或(很少)缓存,以及
  • work-treeworking tree 或此名称的多个变体中的任何一个。

索引中的文件现在已准备好提交。 每个 将被提交的文件 现在在索引中 ,即使索引副本与当前 (HEAD) 提交副本匹配.

您可以随时将 HEAD 提交与当前索引中的任何内容进行比较。执行此操作的一个命令是 git diff --cached。对于索引中 HEAD and/or 中的每个文件,Git 比较文件的两个副本。如果它们不同,则修改文件。如果索引文件存在但HEAD中没有这样的文件,则添加该文件。如果文件存在于 HEAD 但不在索引中,则文件被删除。

您还可以随时将 HEAD 与工作树进行比较,或将索引与工作树进行比较。执行此操作的命令是 git diff HEADgit diff(没有名称)。同样,对于左侧的每个文件(HEAD 或索引)和右侧的每个文件(在工作树中),Git 比较文件。

最后,请注意 git status 运行 两次 git diff 秒。它会快速 git diff --cached 来比较 HEAD 与索引。无论此处有何不同,git status 将该文件列为 待提交 。它还会快速 git diff(除了 --name-only 之外没有额外的参数)来比较索引与工作树。无论此处有何不同,git status 将该文件列为 未暂存提交的更改

您想比较 HEAD 与索引,所以您想要 git diff --cached。然后您只想列出那些 M 修改的文件,因此您可以添加 --diff-filter=M。您不想看到实际的差异——甚至状态信件也不想看到;请仅提供文件名!—这样您就可以添加 --name-only。您还只想列出名称与 *.png 匹配的文件,因此添加 -- '*.png'——引号保护 * 不受 shell 的影响;我们希望 Git 看到 * 以便 Git 可以将其视为 pathspec—得到那些。


1实际上,这真的是几乎总是。有一种特殊状态,其中 HEAD 存在并包含分支名称,但分支名称本身 不存在 。这种状态主要发生在您创建一个新的、完全空的存储库时。 Git 需要像 master 这样的分支名称来标识一些现有的有效提交哈希 ID。没有提交,所以没有有效的哈希 ID,所以 master 本身不允许存在。尽管如此,HEAD 持有 name master,因此 Git 将 创建 master 第一次提交时分支。

2在 Windows 和 MacOS 上,您有时可以使用 head(小写)而不是 HEAD(全-大写)。如果您开始使用 git worktree add,这会出现问题,因此养成这种习惯是不好的。如果您不喜欢全部大写输入 HEAD,请考虑使用符号 @,它是 HEAD.

的同义词