这篇答案提供了如何找到答案的指导。
使用提交图形查看器(或只是“git log --graph”,通常最好作为“git log --graph --oneline --decorate --all”调用),以查看您特定的提交在Git DAG中的位置。如果图形很线性,那么就很容易跟随。如果它充满了分支和合并操作,那么它将更加棘手,并且很可能是由于某个错误的合并引入了问题。如果它充满了未合并的分支,甚至只有一个未合并的分支,那么也许这就是问题所在。
(使用“--all”将向您显示所有标签,包括所有分支名称,并使用“--decorate”将标签附加到它们指向的提交上。“--oneline”选项仅将日志输出压缩为每个提交一行,适合在文本窗口中放置更多内容。)
使用“git show”查看任何普通(非合并)提交:这会显示提交元数据(作者、时间、日志消息)并运行“git diff”以比较该提交的树与该提交的父级的树。例如,“git show ABCD”应该显示您的更改,因为您提交的树对该文件进行了更改,与您在进行提交“ABCD”之前开始的树进行了比较。
假设您的提交“ABCD”位于您希望它在图形中的位置,再查看后续提交(再次使用“git show”)——后续提交是靠近“HEAD”的提交——以查看谁撤销了您的更改。然后,您可以尝试弄清楚他们是如何做到的,也许通过与他们交谈。
如果后续提交是合并——具有两个或更多父项的提交——“git show”通常不会向您显示太多内容,您需要使用“git show -m”,或手动运行“git diff”,以查看两个比较:从第一个父项到该提交,以及从第二个父项到该提交。“-m”标志告诉“git show”为您执行两个单独的差异。(您可以为非合并提交提供“-m”;它对它们没有任何作用。它不是默认值,因为通常合并会显示大量冗余更改。)
顺便提一下,
git log -- path
并没有真正“显示文件历史”,因为Git没有每个文件的历史记录。相反,这个
git log
从
HEAD
开始沿着提交图向后遍历,找到所有可达的提交,但是然后舍弃似乎不影响所询问的文件的提交。目前不清楚您为什么在此处没有看到您的
ABCD
提交,但是日志的图形版本和
git show
输出应该会更清晰地解释原因。
根据下面的评论:当检出标记为
4
和
5
的提交时查看
git log
输出的描述(当检出
5
时,我们可以看到 5、4、3、2 和 1,但是当检出
3
时,我们只会看到 3 和 2),至少有一个是合并提交。
假设 4 是唯一的合并提交,则我们可以将此特定的图形片段绘制如下:
... <- 1 <
/
... <- 2 <- 3 <
这里的分支(
master
)指向提交
5
,这是一个普通的非合并提交,而提交
5
指向提交
4
:提交
4
是合并提交,合并了提交
1
和
3
的内容;它有两个父提交,
3
和
1
(以某种顺序)。提交
3
是一个非合并提交,其父提交为
2
。我们对提交
1
和
2
几乎一无所知:我将它们绘制成具有不同父提交的形式,但也许它们有相同的父提交。
提交
5
可能是合并提交,或者
4
和
5
都是合并提交;我们唯一能确定的是,基于从
5
执行
git log
命令时会显示
1
,而从
3
执行
git log
命令时不会显示
1
,因此
1
不在
3
的历史记录中。
请注意,历史记录是通过按箭头指向的方向进行跟踪而发现的,永远不要逆着箭头走。如果我们从
5
开始,而
4
是合并提交,它有
两个出站箭头,因此我们跟随
两个历史记录以获取
4
的历史记录。
虽然
git log --graph
将历史记录垂直绘制(并且不放置箭头),但它显示了相同的信息,如果没有
--graph
,你就看不到这些信息,但这对于未来操作(如依赖当前图形的合并)非常重要。
请注意,
如果上述图形片段准确无误(我仍在猜测,因为您尚未发布
git log --graph --oneline --decorate --all
输出片段),那么我们几乎可以确定发生了什么事情:在
4
中进行合并的人告诉Git清除了您的更改,取代了提交
3
中的内容。