我怎样才能恢复我的引用日志列表,以便整个列表也出现在 "git log" 中?
How can I recover my reflog list so that the entire list appears in "git log" as well?
我是 git 的新手,我试图将一些东西推送到我的远程存储库,但当它不起作用时,我重置了我的 git,现在我可以看到我的代码不是走了,(这是我的代码的最后一个运行良好的版本仍然存在)这是一种解脱。但是当我 运行 "git log" 它只显示最后一次提交。我有点喜欢我的提交历史,因为我在我的项目中向前推进,我希望能够看到我以前所有代码的发展和进步。因此,当我执行 "git reflog" 时,我可以看到它们,但是当我执行 "git log" 时,我只能看到最后一个。
所以,在我的例子中,我没有丢失任何东西,我的最后一次提交在那里,我的代码是最新的到它的最后一个版本,只是我看不到我的提交历史。我想像以前一样查看我的提交历史。而已。
有人可以帮忙吗?
P. S. 请尽快帮助我,因为我已经阅读过 reflog 每 90 天清理一次! :(
干杯,
如果您使用了 git reset
,您可能已经移动了分支标签以指向不同的提交(这就是 git reset
所做的,或者更准确地说,是几件事之一 git reset
可以做到1)。也就是说,假设您在名为 xyzbranch
的分支上有一些提交,因此 xyzbranch
指向最尖端的提交,在此处标记为 *
。让我们进一步假设有一个 origin/xyzbranch
指向另一个提交,可能是链中较早的提交,或者甚至可能在链的侧分支上;让我们在这里用更大的(大写)O
标记那个:
xyzbranch
|
v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
此外,假设您当前处于 xyzbranch
(因此 git status
表示 on branch xyzbranch
)。然后,假设您执行以下操作:
$ git reset --hard origin/xyzbranch
这会指示 git 更改您当前分支指向的提交,以便它指向您刚刚命名的提交。结果如下所示:
xyzbranch
|
v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
请注意,提交 *
仍然在那里,尽管可能很难找到。你是对的:它受 reflog 保护 xyzbranch
和 HEAD
。 (不过不是90天,默认是30天。2)
诀窍是为提交 *
找到一个名称。它的 "true name" 是 SHA-1 散列,当然它太长太疯狂以至于不能一直输入,比如 19ca3f07...dd5
之类的。但是,如果您能找到该名称,则可以确定您可以通过提供该 SHA-1 来命名提交 *
。
或者(更简单),您可以使用 git reflog
:
查看您的 reflogs
$ git reflog
ca0bf9d HEAD@{0}: reset: moving to HEAD^
0cba526 HEAD@{1}: commit (merge): temp-commit-ugh
ca0bf9d HEAD@{2}: commit: create new file in master
... [snip]
$ git reflog dev
76c1ae2 dev@{0}: commit: create newfile in dev
696077e dev@{1}: commit: modify sub/one
... [snip]
(这些提交消息很糟糕,因为这是我用来测试某些合并案例的临时存储库)。
最左边的部分是哈希的缩写版本,这是一个您可以随时使用的字符串。下一部分,HEAD@{3}
或 dev@{1}
或其他,是一个 relative 索引(到 @
之前的名称)告诉 git 在那个特定的 reflog 中搜索的深度。每次更新 ref 时——无论是 HEAD
(跟踪 "the current branch",无论是什么分支),或者像 xyxbranch
这样的特定分支,或者在我的例子中,分支 dev
和 master
—git 添加一个新的 reflog 条目(或两个,如果 HEAD
像通常那样命名一个分支)。这会将所有其他 reflog 条目向下推一级,因此无论之前在 HEAD@{3}
中,现在都在 HEAD@{4}
中。
如果这是你所做的,并且你希望 xyzbranch
再次指向提交 *
,你可以使用 git reflog xyzbranch
查看 xyzbranch
曾经指向的位置,以及什么行动改变了它。在我的例子中,我在 HEAD
上进行了重置(这实际上是 master,所以我也可以在 master
上看到它,但我将只使用默认的 HEAD
reflog)。操作 reset: ...
显示了我的 git reset
命令,因此 HEAD
之前指向的任何地方都很有趣。您可以将数字(此处为 0cba526
)或索引名称(此处为 HEAD@{1}
)提供给 git log
或 git show
以查看它。
找到正确的提交后,您可以使用 git reset
将分支标签移回那里。或者,如果您想将分支标签保留在现在的位置,您可以创建一个指向所需提交的 new 分支。假设我想 0cba526
到一个新分支。有两个命令可以做到这一点:
$ git branch newbr 0cba526
或者,如果您希望 git 在 newbr
上——即首先创建指向提交 0cba526
的 newbr
,然后还执行 git checkout newbr
:
$ git checkout -b newbr 0cba526
(请注意,这两者都要求您的工作树是干净的,就像在较早的 git reset --hard
之后一样)。让我们画最后一张图,这就是你在 git branch newbr 0cba526
命令之后得到的图,这次也将 HEAD
添加到图片中:
HEAD
|
v
xyzbranch newbr
| |
v v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
(我相信,如果您将 git 的分支标签视为您粘贴到提交 ID 上的黄色小便签,我相信这会有很大帮助。这些便签会脱落并粘贴到不同的提交上,并且这种情况一直发生并且在 git 中完全正常。同时 HEAD
是另一个便签,通常直接粘贴在其中一个分支标签便签的顶部,以便您同时移动两者—但是您可以将它们分开,然后将 HEAD
粘在提交节点上,然后 HEAD
继续在提交节点上漫游,直到您使用 git checkout <branch>
剥离 HEAD
关闭提交节点并将其粘贴到 <branch>
.)
的黄色便利贴上
1我坚信 git reset
做了 太多 事情,这是难以解释的部分原因.但我们坚持这样做,在 git.
2更准确地说,reflog 条目本身会过期:有些会在 30 天后过期,有些会在 90 天后过期。一旦 reflog 条目本身过期,then 它们保护的提交将不再受到保护。 30 天的期限适用于指向从相应引用可达 的提交的引用日志条目:也就是说,如果这是 master
引用日志,并且 master@{123}
指向提交 faded00
,master
指向提交 ac0ffee
,然后我们决定 master@{123}
现在是否存活,首先做:
git merge-base --is-ancestor faded00 ac0ffee
如果答案是"yes, faded00
is an ancestor of ac0ffee
"那么我们选择90天,否则我们选择30天。然后我们检查 master@{123}
的日期戳,如果它太旧,我们将其丢弃,这样 master@{124}
向下移动一个并成为新的 master@{123}
.
一旦 reflog 条目被丢弃,它就不再保护提交(在本例中为提交 faded00
)。如果 else 仍然保护提交,提交仍然是安全的。但是,如果没有保护它,它可能会被垃圾收集并最终被删除。
我是 git 的新手,我试图将一些东西推送到我的远程存储库,但当它不起作用时,我重置了我的 git,现在我可以看到我的代码不是走了,(这是我的代码的最后一个运行良好的版本仍然存在)这是一种解脱。但是当我 运行 "git log" 它只显示最后一次提交。我有点喜欢我的提交历史,因为我在我的项目中向前推进,我希望能够看到我以前所有代码的发展和进步。因此,当我执行 "git reflog" 时,我可以看到它们,但是当我执行 "git log" 时,我只能看到最后一个。
所以,在我的例子中,我没有丢失任何东西,我的最后一次提交在那里,我的代码是最新的到它的最后一个版本,只是我看不到我的提交历史。我想像以前一样查看我的提交历史。而已。
有人可以帮忙吗?
P. S. 请尽快帮助我,因为我已经阅读过 reflog 每 90 天清理一次! :(
干杯,
如果您使用了 git reset
,您可能已经移动了分支标签以指向不同的提交(这就是 git reset
所做的,或者更准确地说,是几件事之一 git reset
可以做到1)。也就是说,假设您在名为 xyzbranch
的分支上有一些提交,因此 xyzbranch
指向最尖端的提交,在此处标记为 *
。让我们进一步假设有一个 origin/xyzbranch
指向另一个提交,可能是链中较早的提交,或者甚至可能在链的侧分支上;让我们在这里用更大的(大写)O
标记那个:
xyzbranch
|
v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
此外,假设您当前处于 xyzbranch
(因此 git status
表示 on branch xyzbranch
)。然后,假设您执行以下操作:
$ git reset --hard origin/xyzbranch
这会指示 git 更改您当前分支指向的提交,以便它指向您刚刚命名的提交。结果如下所示:
xyzbranch
|
v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
请注意,提交 *
仍然在那里,尽管可能很难找到。你是对的:它受 reflog 保护 xyzbranch
和 HEAD
。 (不过不是90天,默认是30天。2)
诀窍是为提交 *
找到一个名称。它的 "true name" 是 SHA-1 散列,当然它太长太疯狂以至于不能一直输入,比如 19ca3f07...dd5
之类的。但是,如果您能找到该名称,则可以确定您可以通过提供该 SHA-1 来命名提交 *
。
或者(更简单),您可以使用 git reflog
:
$ git reflog
ca0bf9d HEAD@{0}: reset: moving to HEAD^
0cba526 HEAD@{1}: commit (merge): temp-commit-ugh
ca0bf9d HEAD@{2}: commit: create new file in master
... [snip]
$ git reflog dev
76c1ae2 dev@{0}: commit: create newfile in dev
696077e dev@{1}: commit: modify sub/one
... [snip]
(这些提交消息很糟糕,因为这是我用来测试某些合并案例的临时存储库)。
最左边的部分是哈希的缩写版本,这是一个您可以随时使用的字符串。下一部分,HEAD@{3}
或 dev@{1}
或其他,是一个 relative 索引(到 @
之前的名称)告诉 git 在那个特定的 reflog 中搜索的深度。每次更新 ref 时——无论是 HEAD
(跟踪 "the current branch",无论是什么分支),或者像 xyxbranch
这样的特定分支,或者在我的例子中,分支 dev
和 master
—git 添加一个新的 reflog 条目(或两个,如果 HEAD
像通常那样命名一个分支)。这会将所有其他 reflog 条目向下推一级,因此无论之前在 HEAD@{3}
中,现在都在 HEAD@{4}
中。
如果这是你所做的,并且你希望 xyzbranch
再次指向提交 *
,你可以使用 git reflog xyzbranch
查看 xyzbranch
曾经指向的位置,以及什么行动改变了它。在我的例子中,我在 HEAD
上进行了重置(这实际上是 master,所以我也可以在 master
上看到它,但我将只使用默认的 HEAD
reflog)。操作 reset: ...
显示了我的 git reset
命令,因此 HEAD
之前指向的任何地方都很有趣。您可以将数字(此处为 0cba526
)或索引名称(此处为 HEAD@{1}
)提供给 git log
或 git show
以查看它。
找到正确的提交后,您可以使用 git reset
将分支标签移回那里。或者,如果您想将分支标签保留在现在的位置,您可以创建一个指向所需提交的 new 分支。假设我想 0cba526
到一个新分支。有两个命令可以做到这一点:
$ git branch newbr 0cba526
或者,如果您希望 git 在 newbr
上——即首先创建指向提交 0cba526
的 newbr
,然后还执行 git checkout newbr
:
$ git checkout -b newbr 0cba526
(请注意,这两者都要求您的工作树是干净的,就像在较早的 git reset --hard
之后一样)。让我们画最后一张图,这就是你在 git branch newbr 0cba526
命令之后得到的图,这次也将 HEAD
添加到图片中:
HEAD
|
v
xyzbranch newbr
| |
v v
... <- o <- ... <- O <- o <- *
^
|
origin/xyzbranch
(我相信,如果您将 git 的分支标签视为您粘贴到提交 ID 上的黄色小便签,我相信这会有很大帮助。这些便签会脱落并粘贴到不同的提交上,并且这种情况一直发生并且在 git 中完全正常。同时 HEAD
是另一个便签,通常直接粘贴在其中一个分支标签便签的顶部,以便您同时移动两者—但是您可以将它们分开,然后将 HEAD
粘在提交节点上,然后 HEAD
继续在提交节点上漫游,直到您使用 git checkout <branch>
剥离 HEAD
关闭提交节点并将其粘贴到 <branch>
.)
1我坚信 git reset
做了 太多 事情,这是难以解释的部分原因.但我们坚持这样做,在 git.
2更准确地说,reflog 条目本身会过期:有些会在 30 天后过期,有些会在 90 天后过期。一旦 reflog 条目本身过期,then 它们保护的提交将不再受到保护。 30 天的期限适用于指向从相应引用可达 的提交的引用日志条目:也就是说,如果这是 master
引用日志,并且 master@{123}
指向提交 faded00
,master
指向提交 ac0ffee
,然后我们决定 master@{123}
现在是否存活,首先做:
git merge-base --is-ancestor faded00 ac0ffee
如果答案是"yes, faded00
is an ancestor of ac0ffee
"那么我们选择90天,否则我们选择30天。然后我们检查 master@{123}
的日期戳,如果它太旧,我们将其丢弃,这样 master@{124}
向下移动一个并成为新的 master@{123}
.
一旦 reflog 条目被丢弃,它就不再保护提交(在本例中为提交 faded00
)。如果 else 仍然保护提交,提交仍然是安全的。但是,如果没有保护它,它可能会被垃圾收集并最终被删除。