Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 有没有办法恢复在重新基址期间意外跳过的提交?_Git_Git Rebase - Fatal编程技术网

Git 有没有办法恢复在重新基址期间意外跳过的提交?

Git 有没有办法恢复在重新基址期间意外跳过的提交?,git,git-rebase,Git,Git Rebase,当一个有用的提交在重基操作期间被意外跳过时,Git是否有希望保留一个可以重新应用的对它的引用 这是一个包含大量二进制文件的非交互式rebase,我使用git-rebase--skip,长时间沉浸在一种愉快的触发情绪中,因此根本没有错误消息,只是一种糟糕的态度 这似乎是一个硬盘崩溃恢复场景,但与其追逐幻影索引节点,还不如找到一种方法来过滤.git/objects中丢失的树对象,并让它们重新激活。git reflog对您有用吗?我认为它应该仍然在垃圾收集器中,除非您运行git gc当您运行git r

当一个有用的提交在重基操作期间被意外跳过时,Git是否有希望保留一个可以重新应用的对它的引用

这是一个包含大量二进制文件的非交互式rebase,我使用
git-rebase--skip
,长时间沉浸在一种愉快的触发情绪中,因此根本没有错误消息,只是一种糟糕的态度


这似乎是一个硬盘崩溃恢复场景,但与其追逐幻影索引节点,还不如找到一种方法来过滤
.git/objects
中丢失的树对象,并让它们重新激活。

git reflog对您有用吗?我认为它应该仍然在垃圾收集器中,除非您运行
git gc

当您运行
git rebase
(交互式或非交互式)时,git基本上会执行一系列
cherry pick
操作,以将原始提交链复制到新链。让我们对原始提交使用
o
,并为分支
branch
下的分支
main
绘制提交图片段:

        o1 - o2 - o3 - o4   <-- branch
      /
..- * - x                   <-- main
上面的
标签表示指向或指向提交
o4
的git引用(分支名称、标记名称或任何其他合适的标签)。只要有一个指向它们的名字,你所有的旧提交仍然在那里。如果没有名字,它们仍然会一直存在,直到
git-gc
清除它们(但您不希望发生这种情况,所以不要运行
git-gc
:-)

那么,重要的问题是:“我们(和git)可以使用什么名称来查找
o4
?”事实证明至少有两个:

  • “reflog”中的一个或多个,以及
  • 一个拼写为
    ORIG_HEAD
ORIG_HEAD
是最容易使用的名称,但该名称也被其他命令使用(
git merge
),因此您必须查看它是否仍然正确:

$ git log ORIG_HEAD
如果这给了你正确的链接,那么给自己一个更永久的名字,指向commit
o4
。这可以是一个分支名称(因此可以用一个新名称“复活”旧分支),也可以是一个标记名称,或者实际上是除分支和标记以外的任何其他名称:

$ git branch zombie ORIG_HEAD
(您不必这样做,随着对git的使用越来越熟悉,您可以跳过这一步,但在那之前这样做可能会更好。)


如果原始头被重击(例如,通过另一个重基、合并或其他方式),该怎么办?嗯,然后是回流

头有一个reflog,默认情况下,每个分支名称有另一个reflog。在这种情况下,要使用的是
分支的reflog

$ git reflog branch
$ git log -g branch
$ git branch zombie branch@{yesterday}
$ git checkout branch           # if needed
$ git reset --hard feedd0gf00d
但是您可以使用
git reflog
来显示
HEAD
的一个(这一个噪音更大,这就是为什么只查看
分支
的一个可能更好的原因):

在所有输出的某处,您应该能够找到commit
o4
。您可能会发现许多类似于
o4
的其他提交,这就是为什么
git log-g
会很有帮助,因为它可以让您找到真正(或正确的)
o4

在任何情况下,假设您最终提出了一个reflog风格的“相对名称”(如
branch@{1}
branch@{dayed}
),您可以找到原始SHA-1,或使用该相对名称,再次复活
branch
的僵尸版本:

$ git reflog branch
$ git log -g branch
$ git branch zombie branch@{yesterday}
$ git checkout branch           # if needed
$ git reset --hard feedd0gf00d
或:

或者别的什么


所有这些只会给你一个名字,
zombie
,图中有三个问号。您仍然必须使用它来查找删除的提交,在本例中,commit
o2
。您可以通过原始SHA-1(通过读取
git日志
)找到它,然后重新设置基址并将其拉入,或者选择它将副本附加到
n4
,或者其他任何内容

如果您只想将
分支
设置回提交
o4
,您甚至可以完全取消僵尸分支,只需在分支上执行
git reset--hard

$ git reflog branch
$ git log -g branch
$ git branch zombie branch@{yesterday}
$ git checkout branch           # if needed
$ git reset --hard feedd0gf00d
或:

请注意,
reset--hard
之后的事情就是任何commit-ID。
--hard
使
reset
清除您的工作树并将其替换为目标commit,而
reset
操作本身告诉git:“使当前分支指向我将要提供给您的提交ID,而不考虑当前提交的分支提示名称。”

换句话说,在您的
git重设基址
完成后,您发现在创建
n1-n3-n4
链时遗漏了
o2
,如果您立即
git reset--hard ORIG_HEAD
,git会更改为:1


o1-o2-o3-o4没有“垃圾收集器”挂起的提交被存储到哪里,直到它们被垃圾回收。@perlsufi,可能是一个关于如何使用此命令跟踪和恢复跳过的提交的简短回执。我没有太多关于它在这个过程中如何有用的线索,手册页上的那些
purge
词让我毛骨悚然。在reflog之后,获取你想要的SHA1,然后git合并该提交你说的在重新基址期间意外“跳过”的提交是什么意思?您是说在交互式重新基址期间,您将提交排除在编辑器列表之外,还是说重新基址没有像预期的那样应用提交?你使用的命令是什么?错误信息是什么?@Cupcake,这是一个非交互式的rebase,有很多二进制文件,我用
git-rebase-skip
玩得太久了,所以根本没有错误信息,只是态度很糟糕。