了解 Git 历史记录简化
Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019 |TFS 2018
Git 历史记录简化可能是一个令人困惑的野兽。 99% 的时间,你甚至不知道它的存在,但偶尔它会跳出 Git 的黑暗角落,咬你。 在本文中,我们将探讨什么是历史记录简化,以及它在查看文件历史记录时如何引起混淆。
让我们从一个常见方案开始:
- 将更改推送到文件,然后将更改合并到 main 中。
- 一些同事还会将其分支合并到主分支。
- 稍后会回来,并注意到缺少更改。
- 查找罪魁祸首,请查看文件历史记录并注意...你的更改甚至未列出!?
Git 提交历史记录是一个树。 有时,按时间顺序排列的历史记录与实际的文件树历史记录不同。 当合并提交将文件还原到其原始状态时,这种情况最常发生。 在这种情况下,默认历史记录视图 实际上不会显示所有更改,因为从技术上讲,文件不会更改。 在此方案中,Git 意识到它可以简化历史记录,并且你最有可能查找的“更改”将从日志中删除。
除非你以前遇到过它, 否则你可能会感到沮丧, 想知道 我的改变去了哪里?
历史记录简化:默认启用
默认情况下,对文件 git log file.txt
运行 log 命令将自动简化历史记录,可能会从其输出中隐藏某些提交。 有关详细信息,请参阅 git 日志手册页。
增加混淆的是,如果只运行 git log
,则不会进行历史记录简化,因为你正在查看所有更改,没有什么可简化的。
若要关闭历史记录简化,需要使用命令行开关 --full-history
。
历史简化示例
为了更好地了解简化的工作原理,我们创建了自己的历史简化示例。 首先,让我们看一下要创建的历史图:
如你所看到的,我们将:
- 创建一个文件。
- 在分支 (动物) 向该文件添加一行。
- 将另一行添加到另一个分支中的该文件, (水果) 。
- 将分支 动物 合并回主分支。
- 将分支 水果 合并回 main,并从水果分支中选择文件的整个副本。
- 检查文件的历史记录。
Git 将为我们简化历史记录。 步骤 5 是此处的关键。 我们忽略了 动物 分支的所有变化。 Git 会注意到,我们的文件在步骤 1 和步骤 5 之间基本上 没有更改 ,因此它只会向我们显示 两个历史记录条目。
首先,创建 文件并将其添加到存储库:
> cd sample
> git init
> echo "some content" > test.txt
> git add test.txt
> git commit -m "Initial commit"
现在,我们决定将文本“donkeys”追加到动物分支中的文件中:
> git checkout -b animals
> echo "donkeys" >> test.txt
> git commit -am "We have added an animal"
在进行试验时,我们决定可能要在文件中改用水果,因此我们创建了另一个分支,并在文件末尾追加文本“香蕉”:
> git checkout main -b fruit
> echo "bananas" >> test.txt
> git commit -am "We have added a fruit"
对我们的变化感到满意后,我们决定将动物分支合并回主分支:
> git checkout main
> git merge animals
现在,让我们看一下文件的日志 test.txt
:
> git log test.txt
commit 6b33d99b996c430a60c9552b79245d1aa8320339
Date: Mon Feb 15 10:45:33 2016 -0500
We have added an animal
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
到目前为止这么好,对吧? 日志输出中没有任何异常。 现在,假设我们改变了主意,并决定合并我们的水果分支:
>git merge fruit
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
哦,合并冲突。 经过一番考虑,我们决定使用水果分支 中的整个 test.txt
文件 。 通常,你会使用某种文本编辑器或合并工具,但我们只需重新创建整个文件,因为它只有两行:
> echo "some content" > test.txt
> echo "bananas" >> test.txt
> git commit -am "Fixed merge conflict"
现在,我们来看看文件的历史记录 test.txt
:
> git log test.txt
commit fdd4dfd816c4efebc5bdb240f49e934e299db581
Date: Mon Feb 15 10:51:06 2016 -0500
We have added a fruit
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
果然,我们在日志中看不到第一个试验的任何更改,也没有看到合并! 他们还在那里吗? Git 是否完全消除了更改?
> git log --full-history test.txt
如你所看到的,尽管它简化了没有 标志的 full-history
日志,但 Git 保留了我们的所有更改:
> commit 5d0bb77a24e265dc154654fb3b5be331b53bf977
Merge: 6b33d99 fdd4dfd
Date: Mon Feb 15 10:59:34 2016 -0500
Fixed merge conflict
commit fdd4dfd816c4efebc5bdb240f49e934e299db581
Date: Mon Feb 15 10:51:06 2016 -0500
We have added a fruit
commit 6b33d99b996c430a60c9552b79245d1aa8320339
Date: Mon Feb 15 10:45:33 2016 -0500
We have added an animal
commit 206613ccd9a54b055b184c7b6c16f2ece8067e51
Date: Mon Feb 15 10:44:18 2016 -0500
Initial commit
Git 历史记录简化摘要
简化历史的是,大多数时候你永远不会注意到它。 但是,当合并冲突出错并且你想知道发生了什么情况时,你可能会发现自己正在查看 git 日志历史记录,并想知道更改的发生位置。
现在,你不必惊慌,而是知道:
- 默认情况下,文件历史记录简化处于打开状态
- 标志
--full-history
将提供更全面的文件历史记录
更新:自从我写这篇文章以来,Azure DevOps Services在 Web 上引入了许多出色的历史记录查看选项。 这意味着,如果不想通过命令行进行日志记录,只需在资源管理器中拉取要查看其历史记录的文件,将显示以下历史记录筛选器,可在其中指定简单或非简单历史记录视图:
(c) 2016 Microsoft Corporation。 保留所有权利。 本文档“按原样”提供。本文档中表达的信息和视图(包括 URL 和其他 Internet 网站引用)可能会更改,恕不另行通知。 您自行承担其使用风险。
本文档未向您提供任何 Microsoft 产品中任何知识产权的任何合法权利。 可以复制本文档并将其用于进行内部参考。