如何在Git的所有提交中查找所有重命名操作?

7

我在一个代码库迷宫中迷失了方向,里面有一堆文件因为不太好的rebase而被重新添加,而它们的旧版本已被重命名。

无论如何,我想列出所有曾经被重命名的文件,也就是列出所有提交中的已重命名文件。


git log --follow 来自这个问题 - johnMa
抱歉,不行。我想列出所有提交中更改的所有文件,“--follow”仅适用于单个文件。 - Roberto
听起来你处于一个棘手的情况。你能否在变基之前使用 git reflog(或分支,或其他什么)并从那里重新提交你的提交,以便你不会陷入这种境地? - James
3个回答

4
这个命令可以满足您的需求吗?
以下是一个修改过的版本,它将显示已重命名和已删除的文件:
这将给出当前分支及其祖先(包括合并的父级)中所有重命名的文件列表,直到第一个提交。-M5将具有相似度高于50%的文件报告为重命名;这可能是太低的百分比,但您可以更改它(5读作.5,即50%,因此您可以将其更改为M8以达到80%)。请注意,如果有很多提交,它会花费很长时间。
我建议您限制提交范围,例如:
据我所知,您需要从提交开始,我不确定如何一次获取跨所有分支和标签的重命名文件的全面列表。如果您要检查不同的分支或在单个存储库中具有独立提交历史记录的分支,则需要在每个分支上运行建议的命令。

太棒了!谢谢。你能更新你的答案,包括已删除的文件吗? - Roberto
@Roberto 当然,我添加了一个版本,它将显示哪些文件已被删除。 - James
--summary was clipping the file names for me. I used this command instead: git whatchanged -M5 <commit-hash>..HEAD | grep R100 - derpedy-doo

1
您可以使用 --diff-filter 选项从日志中获取该信息。重命名文件的过滤器为R,删除文件的过滤器为D
重命名的文件:
git log --summary --pretty='format:' --diff-filter=R

已删除的文件:
git log --summary --pretty='format:' --diff-filter=D

重命名 + 删除的文件:
git log --summary --pretty='format:' --diff-filter=RD

0

背景

需要注意的是,git中的重命名很特殊。

由于git的工作原理,重命名不会被记录到版本控制系统中。它们是事后重建的,就像diff hunks一样,通过比较修订版本之间文件的二进制内容来完成。

这意味着如果file_a被删除,file_b被添加并且它们的相似度足够高(默认是50%),则认为file_afile_b在两个修订版本之间被“重命名”。请注意,这意味着查找重命名需要更多的计算。

这也意味着,经常只有遍历整个修订版本范围才能检测到重命名。除非在该范围内重命名基本上是唯一的更改,例如在HEADHEAD~100之间,这种情况下也可以使用git diff --name-status --diff-filter=R检测到。

如何列出当前分支中的所有重命名

您不能使用git-rev-list来执行此操作,必须使用git-log

git log --name-status -M90%\
 --diff-filter=R --pretty=format: |
  sed\
  -e '/^$/{N;s@^\n$@@}'\
  -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@'
  • --name-status--pretty=format: 只显示旧名称 <tab> 新名称,不包括正常的 git-log 主题等。
  • -M90%,相似度达到差异 -M100% 为相同(仅重命名)。
  • --diff-filter=R,只显示重命名
  • sed 处理输出
    • -e '/^$/{N;s@^\n$@@}' 剥离没有重命名的提交输出(2x+ \n
    • -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@',将输出转换为 old_name <tab> new_name

示例

在 Git 项目存储库中运行。

$ git log --name-status -M100%\
 --diff-filter=R --pretty=format: \
  v2.38.0..v2.39.0 |
  sed\
  -e '/^$/{N;s@^\n$@@}'\
  -e 's@\(^\n\{0,1\}\)R[0-9]\{3\}\t@\1@' |
  cat -A
fuzz-commit-graph.c^Ioss-fuzz/fuzz-commit-graph.c$
fuzz-pack-headers.c^Ioss-fuzz/fuzz-pack-headers.c$
fuzz-pack-idx.c^Ioss-fuzz/fuzz-pack-idx.c$

你可以看到,在 Git 版本 2.38.02.39.0 之间,有几个文件被移动到了 oss-fuzz/ 目录中。


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