git reflog

本页详细讨论了 git reflog 命令。Git 使用一种引用日志机制来跟踪分支尖端的更新。许多 Git 命令都接受参数来指定引用,这是指向提交的指针。常见示例包括:

  • git checkout
  • git reset
  • git merge

引用日志会跟踪本地存储库中 Git 引用的更新时间。除了分支尖端引用日志外,还为 Git stash 维护了一个特殊引用日志。引用日志存储在本地存储库 .git 目录下的目录中。git reflog 目录可以在 .git/logs/refs/heads/.git/logs/Head 还有 .git/logs/refs/stash 上找到,前提是在代码存储库中使用了 git stash

我们详细讨论了 git reflog(在重写历史记录页面上)。本文档将涵盖:git reflog 的扩展配置选项、git reflog 的常见用例和陷阱、如何使用 git reflog 撤销变更等等。

基本用法

最基本的引用日志用例是调用:

git reflog

这本质上是一条捷径,相当于:

git reflog show HEAD

这将输出 HEAD 引用日志。您应该看到类似于以下内容的输出:

eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from main to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to main
39b159a HEAD@{4}: commit: expand on git context 
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support 
9962aed HEAD@{7}: commit: a git editor -> the Git editor

访问重写历史记录页面,查看常见引用日志访问的另一个示例。

引用日志引用

默认情况下,git reflog 将输出 HEAD 引用的引用日志。HEAD 是对当前活动分支的符号引用。引用日志也可用于其他引用。访问 git ref 的语法是 name@{qualifier}。除了 HEAD 引用外,还可以引用其他分支、标记、远程存储库和 Git stash。

您可以通过执行以下命令来获得所有引用的完整引用日志:

  git reflog show --all 

要查看特定分支的引用日志,请将该分支名称传递给 git reflog show

 git 引用日志显示其他分支 9a4491f otherbranch@{0}:提交:将文章分成分支 PR 35aee4a otherbranch{1}:提交(初始):初始提交添加 git-init 和 seting-up-a-repo 文档 

执行本示例将显示 otherbranch 分支的引用日志。以下示例假设您之前使用 git stash 命令存储了一些变更。

 git reflog stash 0d44de3 stash@{0}:git_reflog 上的 WIP:c492574 充实简介 

这将为 Git stash 输出引用日志。返回的引用指针可以传递给其他 Git 命令:

 git diff stash@{0} otherbranch@{0} 

执行后,此示例代码将显示 Git 比对输出,将 stash@{0} 的变更与 otherbranch@{0} 引用进行比较。

定时引用日志

每个引用日志条目都附有时间戳。这些时间戳可用作 Git 引用指针语法的 qualifier 令牌。这允许按时间过滤 Git 引用日志。以下是一些可用时间限定符示例:

  • 1.minute.ago
  • 1.hour.ago
  • 1.day.ago
  • 昨天
  • 1.week.ago
  • 1.month.ago
  • 1.year.ago
  • 2011-05-17.09:00:00

时间限定符可以组合使用(例如 1.day.2.hours.ago),此外,还接受复数形式(例如 5.minutes.ago)。

时间限定符引用可以传递给其他 git 命令。

  git diff main@{0} main@{1.day.ago} 

此示例将把当前的主分支与一天前的主分支进行比对。如果您想知道某个时间范围内发生的变更,此示例非常有用。

子命令和配置选项

git reflog 接受少量被视为子命令的添加参数。

显示 - git reflog show

show 默认是隐式传递的。例如,以下命令:

 git reflog main@{0} 

等同于以下命令:

 git reflog show main@{0} 

此外,git reflog showgit log -g --abbrev-commit --pretty=oneline 的别名。正在执行 git reflog show 将显示已传递的 的日志。

过期 - git reflog expire

expire 子命令清除旧的或无法访问的引用日志条目。expire 子命令可能会丢失数据。此子命令通常不由最终用户使用,而是由 git 内部使用。将 -n--dry-run 选项传递给 git reflog expire 将执行“试运行”,这将输出哪些引用日志条目被标记为已修剪,但实际上不会对其进行修剪。

默认情况下,引用日志过期日期设置为 90 天。过期时间可以通过将命令行参数 --expire=time 传递给 git reflog expire 或设置 gc.reflogExpire 的 git 配置名称来指定。

删除 - git reflog delete

delete 子命令不言自明,它将删除传入的引用日志条目。与 expire 一样,delete 有可能丢失数据,最终用户通常不会调用。

恢复丢失的提交

Git 永远不会真正丢失任何东西,即使在执行历史记录重写操作(如重基或提交修改)时也是如此。在下一个示例中,我们假设我们对代码存储库做出了一些新变更。我们的 git log --pretty=oneline 如下所示:

 338fbcb41de10f7f2e54095f5649426cb4bf2458 扩展内容 1e63ceab309da94256db8fb1f35b1678fb74abd4 一堆内容 c49257493a95185997c87e0bc3a9481715270086 充实简介 eff544f986d270d7f97c77618314a06f024c7916 迁移现有内容 bf871fd762d8ef2ef2e146d7f0226e81a92f91975ad 添加 Git 引用日志概述 35aee4a4404c42128bee8468a9517418ed0eb3dc 初始提交添加 git-init 和 setting-up-a-repo 文档 

然后,我们提交这些变更并执行以下操作:

 #变更 HEAD git commit -am “一些 WIP 变更” 

添加了新提交。现在,日志如下所示:

 37656e19d4e4f1a9b419f57850c8f1974f871b07 一些 WIP 变更 338fbcb41de10f7f2e54095f5649426cb4bf2458 扩展内容 1e63ceab309da94256db8fb1f35b1678fb74abd4 一堆内容 c49257493a95185997c87e0bc3a9481715270086 充实简介 eff544f986d270d7f97c77618314a06f024c7916 迁移现有内容 bf871fd762d8ef2ef2e146d7f0226e81a92f91975ad 添加 Git 引用日志概述 35aee4a4404c42128bee8468a9517418ed0eb3dc 初始提交添加 git-init 和 setting-up-a-repo 文档 

此时,我们通过执行以下命令对主分支进行交互式变基

 git rebase -i origin/main 

变基期间,我们使用 s 变基子命令标记提交用于压缩。变基期间,我们将一些提交压缩到最近的“一些 WIP 变更”提交中。

因为我们压缩了提交,所以 git log 输出现在如下所示:

 40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs 一些 WIP 变更 35aee4a4404c42128bee8468a9517418ed0eb3dc 初始提交添加 git-init 和 setting-up-a-repo 文档 

如果我们现在查看 git log,就会发现似乎已经没有被标记为压缩的提交了。如果我们想对其中一个压缩的提交进行操作,该怎么办?也许要从历史记录中删除它的变更?这就是引用日志的用武之地了。

 git reflog 37656e1 HEAD@{0}:rebase-i(完成):返回 refs/heads/git_reflog 37656e1 HEAD@{1}:rebase-i(开始):签出源/主 37656e1 HEAD@{2}:提交:一些 WIP 变更 

我们可以看到 rebase 的开始和结束有引用日志条目,在此之前是我们的“一些 WIP 变更”提交。我们可以将引用日志引用传递给 git reset,然后重置为变基之前的提交。

 git reset HEAD@{2} 

执行此重置命令会将 HEAD 移至添加了“一些 WIP 变更”的提交,实质上是恢复其他压缩的提交。

摘要

在本教程中,我们讨论了 git reflog 命令。涵盖的一些关键点包括:

  • 如何查看特定分支的引用日志
  • 如何使用引用日志撤销 git 变基
  • 如何指定和查看基于时间的引用日志条目

我们简要提到 git reflog 可以与其他 git 命令一起使用,例如 git checkoutgit resetgit merge。在各自的页面上了解更多信息。有关引用和引用日志的更多讨论,请在此处了解更多信息

准备好了解 Git 了吗?

试用本交互式教程。

立即开始