Git日志(--follow)无法显示重命名后的历史记录
我试图通过gitlog在git中显示文件的完整历史记录。 问题是该文件的partent文件夹在历史记录中被重命名,我希望看到完整的历史记录 表示参数Git日志(--follow)无法显示重命名后的历史记录,git,version-control,git-log,Git,Version Control,Git Log,我试图通过gitlog在git中显示文件的完整历史记录。 问题是该文件的partent文件夹在历史记录中被重命名,我希望看到完整的历史记录 表示参数--follow和-M在重命名后显示make git log 我尝试了gitlog参数的不同组合,如 git log-M--oneline--all--follow newpath/my file.php git log-M--oneline--all--newpath/my file.php 甚至 git rev list--all--newpat
--follow
和-M
在重命名后显示make git log
我尝试了gitlog参数的不同组合,如
git log-M--oneline--all--follow newpath/my file.php
git log-M--oneline--all--newpath/my file.php
甚至
git rev list--all--newpath/my-file.php--objects--in提交顺序| git log--no walk--oneline--stdin
但是无论我尝试什么,历史总是在提交时结束,文件的父文件夹被重命名
我已经可以确认:
- 在重命名提交中,只有文件夹被重命名,文件的内容100%不变,因此git应该简单地发现旧路径上的文件和新路径上的文件是相同的,并且yust已重命名
- 重命名提交的git shot name status显示
(确认文件内容100%相同)R100 oldpath/my-file.php newpath/my file.php
- 历史的“旧的一半”和“新的一半”似乎都是正确的,都包括重命名commt
- 当我运行
最早的提交是git log-M--oneline--all--follow newpath/my file.php时
0979744重命名:oldpath/->newpath/
- 当我运行
时,最新的提交是git log-M--oneline--all--follow oldpath/my file.php
0979744重命名:oldpath/->newpath/
-M
和--follow
选项时,重命名提交时历史记录仍然中断?因为--follow
选项必须位于指示选项列表结束的独立--
之前
即使这样,下面的重命名现在也似乎起作用了,当我添加
--grep=“rename”-invert grep
以删除“rename”提交时,我得到了0个结果
这是有道理的(但这是一种缺陷),1因为--follow
的工作方式。这里的问题是Git根本没有任何类型的文件历史记录。Git所拥有的只是存储库中的一组提交。提交是历史记录:
- 每个提交都通过其丑陋的大散列ID进行编号,该ID对于该特定提交是唯一的。任何Git repository2中的其他提交都没有该散列ID
- 每次提交都有每个文件的完整快照
- 每个提交还存储以前提交的哈希ID,对于合并提交,存储两个或多个以前提交的哈希ID
... <-F <-G <-H
要显示所有提交,git log
必须遍历commitO
,然后N
,然后M
,然后K
和L
(按一定顺序),然后K
之前的所有提交和L
之前的所有提交返回到C
和D
,然后在commitB
处重新加入一个线程,并从那里向后继续
但是,如果我们不打算显示所有提交,可能只是在提交M
时,我们可以返回到只提交K
或只提交L
并完全忽略合并的另一面。这将节省大量工作和时间,并避免向您展示无关的内容。这通常是一件非常好的事情
然而,对于——遵循,这通常是一件非常糟糕的事情。这是——follow
的问题之一:有时候Git在进行这种简化时会走上“错误的道路”。添加--完整历史记录可以避免这种情况,但我们立即陷入另一个问题。--follow
选项只有一个文件名。如果我们在提交的两个分支中有一个重命名,但在另一个分支中没有,并且git log
首先进入重命名分支,那么它在进入另一个分支时可能会查找错误的名称
如果文件在两个分支中都被重命名,那么它将从M
重新命名为K
,从M
重新命名为L
,或者如果Git恰好在第一个位置进入了正确的分支,而您不关心另一个分支,那么一切都正常。但这是需要注意的。(这不是--grep
给您带来的问题,或者在没有--grep
的情况下会发生)
我认为您看到的错误是,--grep
正在“太早”启动。--grep
选项的工作原理是,从git log
的输出中删除任何提交消息中包含(--invert grep
)或缺少(--grep
而不包含--invert grep
)某些特定文本的提交。那么,假设重命名commit导致-git log--follow
知道使用名称oldpath/my file.php
——被--grep
选项跳过。Git不会看到R
状态,也不会知道将名称从newpath/my file.php
更改为oldpath/my file.php
。因此,git log--follow
将继续查找新路径,并且您将只得到那些既满足grep标准又使用新名称修改文件的提交
这个bug可以通过让git log--follow
运行diff引擎来修复,即使它会因为其他原因跳过提交。但更一般地说,follow需要完全重写:它有一堆奇怪的特殊情况代码
I--J <-- feature1
/
...--F--G--H
\
K--L <-- feature2
C--...--K
/ \
...--A--B M--N--O <-- branch
\ /
D--...--L