在 git 日志中获取文件重命名前后的完整文件路径
get the full filepath before and after file renaming in git log
假设我知道一个文件已被重命名(重命名可以通过重命名文件名或将文件移动到另一个目录来实现)到特定的提交中。 git show --summary <sha>
显示提交中此类重命名的所有实例。但是,git 仅标出新旧文件路径之间的差异。下面是两个例子-
rename xbmc/interfaces/{ => builtins}/Builtins.cpp (100%)
rename xbmc/cores/AudioEngine/Engines/ActiveAE/{ActiveAEResample.cpp => ActiveAEResampleFFMPEG.cpp} (100%)
如何高效解析重命名前后的完整文件路径,因为它可以通过多种方式完成?或者是否有另一个 git 命令以更简单的方式显示此信息?
TL;DR
鉴于您知道提交哈希 <hash>
,您可能需要:
git diff-tree --find-renames -r --name-status --diff-filter=R --no-commit-id <hash>
或同加-z
。您可能还想指定合并的(第一个)父级,在这种情况下 --no-commit-id
是不必要的。
长
有多种方法可以执行此操作,具体取决于您想要输出的内容的各种详细信息。关键是从可预测的 plumbing 命令开始。在 Git 中,管道命令本质上是为其他程序使用而设计的命令,因此它具有机器可读、可预测、可靠的输出格式。你现在得到的是 git diff --summary
的输出,而 git diff
是一个 porcelain 命令,旨在具有人类可读的输出:
$ git diff --summary 99177b34db^ 99177b34db
rename contrib/hooks/multimail/{README => README.rst} (95%)
其中 git show --summary
运行 在其其他操作结束时。
对于机械可解析的输出,我们可以切换到 git diff-tree
。如果我们想要每个修改文件的名称和状态,我们可以要求:
$ git diff-tree --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
D contrib/hooks/multimail/README
M contrib/hooks/multimail/README.Git
A contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
我们可以立即看出这里有一个缺陷:我们没有观察到重命名。这是因为在提交 99177b34db
(99177b34db^
) 的(第一个也是唯一的)父级和提交 99177b34db
本身之间,没有实际的重命名。两个快照只有两组文件。我们看到的重命名是 git diff --summary
做出的 猜测 。要指示 Git 在使用 git diff-tree
时做出相同的猜测,我们必须添加 --find-renames
——这让 us 选择算作重命名的相似度阈值,但默认为我们为摘要获得的相同 50%:
$ git diff-tree --find-renames --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
M contrib/hooks/multimail/README.Git
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
R095
行包含我们想要的内容:检测到的重命名、相似度值(在本例中为 95%)以及两个文件名,在本例中由制表符分隔。
我们可以使用 --diff-filter
缩小输出以包含 仅 重命名:
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db^ 99177b34db
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
请注意,我们可以 运行 git diff-tree
仅使用一个提交哈希。当提交是普通(非合并)提交时,这很有效:
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db
99177b34db1d473e8f90544cf0bf83f47308e9ad
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
但是,现在我们在输出中得到了完整的哈希 ID。添加 --no-commit-id
表示不包含哈希 ID。
如果我们指定的提交是合并提交,它的工作方式也会不同。我不打算在这里说明这一点,因为我没有方便的合并来以这种方式查看,但请密切注意 the documentation's description of the diff format for merges and the separate note about the combined format 告诉我们有时我们根本看不到一些文件。
删除 --name-status
后我们得到了另一种格式,它更长,有时更有用:
$ git diff-tree --find-renames -r --diff-filter=R 99177b34db^ 99177b34db
:100644 100644 5105373aea044f2d8fde0c4fd927c8c492d02585 7c0fc4a6ef00362dcff476497a6045a420562d05 R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
这里我们得到了两个文件的blob哈希值,前面有两个模式(100644
),都以一个冒号:
作为前缀。如果我们得到合并提交的输出,细节将会改变。
在所有这些情况下,您都可以添加 -z
选项。这将输出更改为机器可读性更高(但人类无法阅读):每个输出记录的各个部分都使用 ASCII NUL (0x00) 字节来分隔它们。此选项也是 described in the documentation,以及当您 不 使用 -z
.
时对路径名进行哪些修改的一些详细信息
假设我知道一个文件已被重命名(重命名可以通过重命名文件名或将文件移动到另一个目录来实现)到特定的提交中。 git show --summary <sha>
显示提交中此类重命名的所有实例。但是,git 仅标出新旧文件路径之间的差异。下面是两个例子-
rename xbmc/interfaces/{ => builtins}/Builtins.cpp (100%)
rename xbmc/cores/AudioEngine/Engines/ActiveAE/{ActiveAEResample.cpp => ActiveAEResampleFFMPEG.cpp} (100%)
如何高效解析重命名前后的完整文件路径,因为它可以通过多种方式完成?或者是否有另一个 git 命令以更简单的方式显示此信息?
TL;DR
鉴于您知道提交哈希 <hash>
,您可能需要:
git diff-tree --find-renames -r --name-status --diff-filter=R --no-commit-id <hash>
或同加-z
。您可能还想指定合并的(第一个)父级,在这种情况下 --no-commit-id
是不必要的。
长
有多种方法可以执行此操作,具体取决于您想要输出的内容的各种详细信息。关键是从可预测的 plumbing 命令开始。在 Git 中,管道命令本质上是为其他程序使用而设计的命令,因此它具有机器可读、可预测、可靠的输出格式。你现在得到的是 git diff --summary
的输出,而 git diff
是一个 porcelain 命令,旨在具有人类可读的输出:
$ git diff --summary 99177b34db^ 99177b34db
rename contrib/hooks/multimail/{README => README.rst} (95%)
其中 git show --summary
运行 在其其他操作结束时。
对于机械可解析的输出,我们可以切换到 git diff-tree
。如果我们想要每个修改文件的名称和状态,我们可以要求:
$ git diff-tree --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
D contrib/hooks/multimail/README
M contrib/hooks/multimail/README.Git
A contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
我们可以立即看出这里有一个缺陷:我们没有观察到重命名。这是因为在提交 99177b34db
(99177b34db^
) 的(第一个也是唯一的)父级和提交 99177b34db
本身之间,没有实际的重命名。两个快照只有两组文件。我们看到的重命名是 git diff --summary
做出的 猜测 。要指示 Git 在使用 git diff-tree
时做出相同的猜测,我们必须添加 --find-renames
——这让 us 选择算作重命名的相似度阈值,但默认为我们为摘要获得的相同 50%:
$ git diff-tree --find-renames --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
M contrib/hooks/multimail/README.Git
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
R095
行包含我们想要的内容:检测到的重命名、相似度值(在本例中为 95%)以及两个文件名,在本例中由制表符分隔。
我们可以使用 --diff-filter
缩小输出以包含 仅 重命名:
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db^ 99177b34db
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
请注意,我们可以 运行 git diff-tree
仅使用一个提交哈希。当提交是普通(非合并)提交时,这很有效:
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db
99177b34db1d473e8f90544cf0bf83f47308e9ad
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
但是,现在我们在输出中得到了完整的哈希 ID。添加 --no-commit-id
表示不包含哈希 ID。
如果我们指定的提交是合并提交,它的工作方式也会不同。我不打算在这里说明这一点,因为我没有方便的合并来以这种方式查看,但请密切注意 the documentation's description of the diff format for merges and the separate note about the combined format 告诉我们有时我们根本看不到一些文件。
删除 --name-status
后我们得到了另一种格式,它更长,有时更有用:
$ git diff-tree --find-renames -r --diff-filter=R 99177b34db^ 99177b34db
:100644 100644 5105373aea044f2d8fde0c4fd927c8c492d02585 7c0fc4a6ef00362dcff476497a6045a420562d05 R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
这里我们得到了两个文件的blob哈希值,前面有两个模式(100644
),都以一个冒号:
作为前缀。如果我们得到合并提交的输出,细节将会改变。
在所有这些情况下,您都可以添加 -z
选项。这将输出更改为机器可读性更高(但人类无法阅读):每个输出记录的各个部分都使用 ASCII NUL (0x00) 字节来分隔它们。此选项也是 described in the documentation,以及当您 不 使用 -z
.