如何撤消git提交--修改
我不小心输入了一个git commit--amend。这是一个错误,因为我意识到提交实际上是全新的,应该使用新消息提交。我想做出新的承诺。如何撤消此操作?是关键。下面是两个命令序列,用于执行您想要的操作:如何撤消git提交--修改,git,Git,我不小心输入了一个git commit--amend。这是一个错误,因为我意识到提交实际上是全新的,应该使用新消息提交。我想做出新的承诺。如何撤消此操作?是关键。下面是两个命令序列,用于执行您想要的操作: git reset --soft @{1} git commit -C @{1} 以及如何工作的解释 描述 当您进行新的提交时,Git通常会使用以下事件序列: 读取当前提交的ID(SHA-1散列,如a123456…)(通过HEAD,它为我们提供了当前分支)。让我们将此ID称为C(当前)。请注
git reset --soft @{1}
git commit -C @{1}
以及如何工作的解释
描述
当您进行新的提交时,Git通常会使用以下事件序列:
a123456…
)(通过HEAD
,它为我们提供了当前分支)。让我们将此ID称为C(当前)。请注意,此当前提交有一个父提交;让我们调用它的ID P(对于父对象)--amend
Git时,会稍微改变流程。它仍然像以前一样编写新的提交,但在步骤3中,它不是使用parent=C编写新的提交,而是使用parent=P编写新的提交
图画
从图像上看,我们可以这样画出发生了什么。我们从一个以P--C
结尾的提交图开始,由分支
指向:
...--P--C <-- branch
当我们使用--amend
时,我们得到的是:
C
/
...--P--N <-- branch
我们不能完全做到这一点,我们不能改变;Git在repo中存储任何commit(或任何其他对象)后都无法更改它,但请注意,..--P--C
链仍然在那里,完全完好无损。您可以通过reflogs找到commitC
,这就是@{1}
语法的作用。(具体来说,这是currentbranch@{1}
,2的缩写,意思是“其中currentbranch
在一步之前指向了”,即“提交C
”
因此,我们现在运行git reset--soft@{1}
,它可以:
C <-- branch
/
...--P--N
其中,N2
将是我们的新(第二个新?)提交
我们甚至可以通过commitN
重新使用commit的提交消息。git commit
命令有一个--reuse message
参数,也拼写为-C
;我们所要做的就是给它一些东西,让它找到原始的新提交N
,从中复制消息,并使用N2
。我们怎么做?答案是:它在reflog中,就像我们需要执行git重置时的C
一样
事实上,这是相同的@{1}
记住,@{1}
的意思是“它刚才在哪里”,而git reset
刚刚更新了它,将它从C
移动到N
。我们尚未进行新的提交N2
。(一旦我们这样做,N
将成为@{2}
,但我们还没有做到。)
因此,综合起来,我们得到:
git reset --soft @{1}
git commit -C @{1}
1此描述的细分位置包括修改合并时、位于分离的头部时以及使用替代索引时。尽管如此,如何修改描述还是很明显的 2如果
HEAD
被分离,因此没有当前分支,则含义变为HEAD@{1}
。请注意,@
本身是HEAD
的缩写,因此@{n}
引用当前分支而不是HEAD
本身的事实有点不一致
看看它们是如何不同的,请考虑<代码> Git签出开发后面跟着“代码> Git签出主< /代码>(假设两个分支都存在)。第一个
签出
更改头
指向开发
,第二个更改头
指向主
。这意味着master@{1}
是上次更新master
之前提交master
所指向的内容;但是HEAD@{1}
是提交develope
指向现在可能是其他提交的
(重述:在这两个
git checkout
命令之后,{1}
意味着master{1}
现在,HEAD{1}
意味着与develope
现在相同的提交,而
意味着HEAD
。如果你感到困惑,那么,我也是,显然我并不孤单:请参阅注释。)git reset--soft
git reset--soft@{1}
对我不起作用。我只是恢复提交,然后挤压它们。解决了这个问题。{1}
是当前分支{1}
的缩写,而不是头{1}
@PetSerAl:啊哈,你说得对!虽然如果HEAD被分离,它将作为HEAD@{1}
工作。这似乎有点不一致,因为@
意味着头
,但我认为头{0}
和当前分支{0}
必须是同义词,如果存在当前分支的话。谢谢,我会解决这个问题。@andrybak:通过移动头部和/或一些分支几次,分离头部,再移动一些,然后重新连接来测试它。语义比语法更复杂。@andrybak即使是HEAD
也是符号ref,{1}
和{1}
有不同的含义。@8bit瘾君子:不要盲目地使用{1}
,因为如果你在git提交--amend
之后做了任何事情,它就不再是1
。如果需要,运行git reflog
,为@{…}
语法找到正确的哈希ID或数字。
C <-- branch
/
...--P--N
C--N2 <-- branch
/
...--P--N
git reset --soft @{1}
git commit -C @{1}