Git 如何删除当前标头之后的提交?
在我的Git存储库中,我一行创建了三个提交:Git 如何删除当前标头之后的提交?,git,git-commit,Git,Git Commit,在我的Git存储库中,我一行创建了三个提交:commit1、commit2和commit3 然后我意识到我在commit2和commit3中搞砸了,决定回到commit1。为了做到这一点,我跑了 git checkout commit1 现在我在commit1。如何删除commit2和commit3?您想取消commitcommit3(假设您当前在commit3上-作为头)。您可以执行以下操作: git reset --hard HEAD~1 结果是: commit1 -> commi
commit1
、commit2
和commit3
然后我意识到我在commit2
和commit3
中搞砸了,决定回到commit1
。为了做到这一点,我跑了
git checkout commit1
现在我在
commit1
。如何删除commit2
和commit3
?您想取消commitcommit3
(假设您当前在commit3上-作为头
)。您可以执行以下操作:
git reset --hard HEAD~1
结果是:
commit1 -> commit2
↑
HEAD
您可以按照类似的过程返回到commit1
(即git reset--hard HEAD~2
)。检查分支,然后重置它
根据您的描述,并假设您在签出commit1
之前在名为mybranch
的分支机构工作(C1
,在下面的图表中),您必须处于以下情况:
C1 [HEAD]
\
C2 -- C3 [mybranch]
C1
\
C2 -- C3 [HEAD -> mybranch]
C1 [HEAD -> mybranch]
提交C2
和C3
仍然出现在git log
的输出中,因为它们仍然可以从mybranch
引用访问。另外,请注意,头部
已分离。你应该做的是
HEAD
重新连接到mybranch
git签出mybranch
这将使您处于以下情况:
C1 [HEAD]
\
C2 -- C3 [mybranch]
C1
\
C2 -- C3 [HEAD -> mybranch]
C1 [HEAD -> mybranch]
mybranch
分支重置为其tip的祖辈
git重置——硬mybranch~2
这将使您处于以下情况:
C1 [HEAD]
\
C2 -- C3 [mybranch]
C1
\
C2 -- C3 [HEAD -> mybranch]
C1 [HEAD -> mybranch]
C2
和C3
现在变得不可访问(即“已删除”),所以在最后一个图表中没有显示它们
为什么不先重新连接头部就复位不起作用 这可能有点厚颜无耻,但下面解释一下为什么其他两个答案不起作用。正如cmbuckley在中正确指出的那样
git reset
重置您当前所在分支的状态(因此您需要在分支上执行此操作)。如果您签出了commit1
,则可能不在分支上(分离头状态)
由于OP(Imray)处于分离头部状态,因此在将头部重新连接到分支之前运行git reset不会移动有问题的分支引用。下面是一个玩具的例子来说明这一点
#把事情安排好
$mkdir测试
$cd测试
$git init
已在/Users/jubobs/Desktop/test/.Git中初始化空Git存储库/
#创建第一次提交
$touch自述文件
$git add。
$git commit-m“添加自述”
[master(root提交)85137ba]添加自述
1个文件已更改,0个插入(+),0个删除(-)
创建模式100644自述文件
#创建第二个提交
$printf“foo\n”>自述
$git commit-am“在自述文件中写入'foo'”
[master 3948e84]在自述文件中写“foo”
1个文件已更改,1个插入(+)
#检查日志
$git log--图形--装饰--单线--全部
*3948e84(头,主)在自述中写“foo”
*85137ba添加自述
#查看第二个提交(它分离头部)
$git结帐3948e84
注意:正在签出“3948e84”。
#(样板标准省略了…)
头现在在3948e84。。。在自述中写“foo”
#重置为第一次提交(相当于“git重置--hard 85137ba”)
$git重置--硬头^
HEAD现在位于85137ba添加自述
$git log--图形--装饰--单线--全部
*3948e84(主)在自述文件中编写“foo”
*85137ba(标题)添加自述
请注意,
git reset
命令将HEAD
移动到初始提交,但没有移动master
分支。第二次提交没有被“删除”,因为它仍然可以从主控
访问;因此,出于命名目的,我假设您在回购协议的主分支中,但任何分支都可以。这可以简单地看作是指向提交对象的指针。您还可以将HEAD视为另一个指针,您可以使用git checkout
commit1 -> commit2 -> commit3
^
|
master
如果要将主指针更改为commit1,则需要发出git reset
命令,其他人已经指出了这一点
git reset --hard commit1
这会将上图中的主指针移动到与commit1对象相同的位置
注意,您实际上并没有删除commit2和commit3对象,只是在git中没有指向它们的分支,所以git可以自由地清理它们,或者您可以通过运行垃圾收集来强制它,比如:
git gc --aggressive --prune
在从回购协议中主动清除之前,您仍然可以签出commit2和commit3,因此尽管您将主指针移回commit1(使用git reset
),但如果您意外地将密码提交到存储库并试图恢复-在删除之前,密码仍将在本地回购中。强制您的分支到当前HEAD和Checkout分支
签出分支并强制分支到当前头
第二个选项特别有利,因为您不需要键入branh的名称或当前提交的标识。你甚至可以把它变成别名
编辑:这假设您没有跳转,最近的签出是从您的分支进行的。注意,在执行
签出commit1
(其中commit1
是提交ID、远程分支或标记)后,您位于分离的头上(=不在分支上)。然后,您必须签出您的分支,并按照注释和答案中描述的重置
步骤进行操作。我不在主分支
上,我在不同的分支我不在主分支
上,而是在我的第一分支
上,这有什么关系吗?不,我只是说大师,所以正文的其余部分与那个分支相关。所有分支都只是指针的名称。这个答案不正确。因为OP处于分离头状态,git reset--hard commit1
将