如果我正在探索项目的历史记录,有时我会在提交时查看一个文件,该文件与当前工作目录中的路径不同。
基本上,如果我有一个提交ID,并且该提交id的文件的旧路径,是否有任何git命令或bash脚本,我可以用来找出该文件的当前路径,在当前重命名/移动工作目录?我正在考虑像git log --follow
这样的东西,但反过来,并没有花太多时间去运行。
我希望能够将此方法与vim-fugitive结合使用,因此一个性能良好的解决方案(给定git结构功能)将是一个不错的选择。
那里有什么好主意吗?
答案 0 :(得分:1)
您可以使用git log --name-status
--diff-filter
显示所有文件操作 - 这会显示所有文件事件,以及显示发生了哪种修改的字母。您想要过滤R
(重命名)和/或C
(更改)事件:
git log --name-status --oneline --diff-filter=RC
从手册页:
- DIFF-滤波器= [(A | C | d | M | R | T | U | X | B)... [*]]
仅选择添加(A),复制(C),删除(D),修改(M), 重命名(R),改变它们的类型(即常规文件,符号链接,子模块......) (T),Unmerged(U),Unknown(X),或已配对破碎(B)。
答案 1 :(得分:1)
我会尽量避免在这里咆哮。 : - )
您想要的是git log --follow --reverse
,您提供旧路径名称,也许还有修订范围:git log --follow stop^..start path
。
唉,这实际上并不奏效。
问题是git log --follow
是使用可怕的黑客实现的。 git log
代码照常工作,进行历史记录简化并查找提交,其差异或组合差异对其父代显示对命名 path
的修改。如果修改的类型是--follow
暗示--find-renames
的重命名注释 - git log
代码注意到这一点,并且在转移到父提交时,< em>更改它正在寻找的名称。现在,它不是寻找new/path/to/file.ext
,而是寻找old/different/name
,例如。
这仅在您知道最终名称时才有效,因为它只会在“后退”方向更改名称。似乎应该可以正常工作来反转diff-name-change的意义,找到修改并在“前进”方向上将名称更改为 new 名称,但事实上,{{ 1}}根本没有前进。它仍在“向后”进行分析:在找到提交后,它只是反转--reverse
的输出。
从根本上说,Git 必须向后工作,因为提交知道他们的父母但不了解他们的孩子。不过,它应该有一个“慢模式”,它可以生成列表,然后反过来,父对子而不是子对父。然而,将这个添加到git log
变得非常重要(我几年前曾尝试过这样做,并且失败了)。如果您愿意为此问题投入大量内存和至少一个额外流程,则可以运行git log --follow
(也许还可以使用git log --find-renames --topo-order --name-status
)并对重命名列表进行后处理。