【问题标题】:git checkout removes git log historygit checkout 删除 git log 历史记录
【发布时间】:2023-01-30 05:32:57
【问题描述】:

我的 git log 有两个提交

commit a38056f9da4dcf48c188e79fe632b3624e6ffef4 (HEAD, main)
Author: user
    commit 2

commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user

    commit 1

,我想返回提交 1,我可以使用 git checkout 801608941f024901799208e328bb0d3908c2ba7a 来完成。 问题是,当我这样做时,我的git log 转向

commit 801608941f024901799208e328bb0d3908c2ba7a
Author: user

    commit 1

而且我再也找不到提交 2 的 SHA。如果我通过向上滚动到我的第一个git log 然后是git checkout 提交 2 的 SHA 找到提交 2 的 SHA,我会按预期返回提交 2 的快照,但令人讨厌的是 git log 不显示提交 2 的 SHA 是这个普通的?如果是这样,我现在应该如何找到commit 2 的提交历史?

【问题讨论】:

  • 如果你只运行git log,它会显示你当前所在的提交的历史……所以,你回到历史的第一个提交,git log 只会显示那个提交。 .. 您可以随时要求记录其他内容,例如 git log maingit log -a(以显示所有分支/标签)。您也可以返回主界面,然后在那里登录。 git checkout main; git log
  • 或者您可以使用git reflog 来查看。此 thread 包含对 git loggit reflog 之间差异的讨论。

标签: git


【解决方案1】:

概括

跑步:

git switch main

或者:

git checkout main

细节

吉特没有删除任何事物。你就是不能它。原因如下:git log 命令的工作原理是倒退.

在 Git 存储库中,历史只不过是该存储库中的提交。混帐发现通过他们丑陋的大哈希 ID 提交:

  • a38056f9da4dcf48c188e79fe632b3624e6ffef4
  • 801608941f024901799208e328bb0d3908c2ba7a

混帐迫切需要这些哈希 ID 以便找到提交。但是这些哈希 ID 对人类非常不利(快点,801608941f024901799208e328bb0d3908c2ba7a801608941f024901797208e328bb0d3908c2ba7a 一样吗?)。所以我们通常不使用哈希 ID。混帐使用哈希 ID,但 Git 为我们提供了分支名称标签名称和许多其他种类的名字。那些是我们通常使用的。

每个提交存储两件事:

  • 直接地,每个提交存储一些metadata,提供提交人的姓名和电子邮件地址等信息。
  • 间接地,每个提交存储一个每个文件的完整快照.

所有这些东西,一旦进入提交,就完全是只读的:它永远无法更改,即使 Git 本身也不能更改,只要你取回通过其丑陋的大哈希 ID 提交。该哈希 ID 是该提交的“真实名称”。

在每个提交的元数据中,Git 存储一个列表以前的提交,这就是 git log 实际工作的方式:它从某个特定的提交开始,它有一些特别大的丑陋的哈希 ID,git log 向您显示该提交。然后git log 使用那个提交的metadata找到以前的犯罪。 git log 命令现在显示提交,然后使用其元数据再次向后退一步。

这样做的最终结果是您一次看到所有提交,向后,从你开始的任何地方(或者它是“结束”?),遵循 Git 在你工作时建立的内部链:

... <-F <-G <-H

这里的大写字母代表那些丑陋的大哈希 ID,所以 H 是一些哈希的缩写。如果你给 Git H 的散列 ID,它会显示你 H,然后它使用 H 找到 G 的散列 ID。我们说提交H指着较早提交G。 Git 然后显示G,然后使用G 的元数据来查找F 的哈希 ID,依此类推。

但是:如果你运行git log没有给它一个哈希 ID,它怎么知道从哪里开始呢?答案是 Git 有一个概念当前提交,Git 使用特殊的魔法名称 HEAD 找到它。

HEAD 通常包含一个分店名称

因为哈希 ID 对人类不利,所以我们倾向于不使用它们。 Git 为我们提供了创建任意数量的选项的选项分支名称.每个分支名称只存储一个哈希 ID,分支名称“内部”的哈希 ID 就是最后的提交那个“在”那个分支上:

... <-F <-G <-H   <--main

这里的名字main指着H,正如H指向GG指向F等。所以git log main将从H开始并向后计算。

我们可以有任意多个分支名称,都直接指向提交 H

...--G--H   <-- main, develop, feature1, feature2

要记住哪个名字是个现名,Git 会将特殊名称 HEAD 附加到这些分支名称之一:

...--G--H   <-- main, develop, feature1 (HEAD), feature2

这里我们在分支feature1上——运行git status会说on branch feature1——而git log,没有任何起点,将使用名称feature1找到提交H,并显示提交,然后是GF等等。

分离头模式

但是,如果我们运行:

git checkout <hash-id>

对于一些丑陋的大哈希 ID,Git 存储该哈希 ID直接地在特殊名称HEAD 中,现在我们有:

...--F   <-- HEAD
      
       G--H   <-- main, develop, ...

运行 git log 现在从提交 F 开始并向后运行。提交 GH 发生了什么?什么也没有:他们还在里面。你只需要开始git log提交H,看看他们。为此,您可以运行:

git log main

因为main指向H;或者你可以git switch maingit checkout main重新连接HEAD 到分支名称,以便 git log 从那里开始。

请注意,提交通常在许多分支上

鉴于:

...--G--H   <-- main, develop, feature1 (HEAD), feature2

提交在哪个分支上?

答案是:他们全部!

如果我们做一个新的不过,现在提交,会发生以下情况:

...--G--H   <-- main, develop, feature2
         
          I   <-- feature1 (HEAD)

Git 不仅会写出新的提交,给它一个新的唯一的哈希 ID(丑陋的大哈希 ID 是唯一的),它还会设置新的提交,以便它指向提交 H——我们的提交用作刚才的当前提交——然后写新的提交的哈希 ID 到当前分店名称.

这就是分支正常增长的方式,一次一个提交。

还有很多,但这些是使用 Git 的基本知识。

【讨论】:

    猜你喜欢
    • 2013-09-15
    • 2016-02-24
    • 2017-06-16
    • 2016-10-09
    • 2014-06-19
    • 2020-03-20
    • 2019-11-29
    • 1970-01-01
    • 2011-10-08
    相关资源
    最近更新 更多