18

我已经看到'git commit --amend' 处于分离的 HEAD 状态。这个问题要求答案比需要的更复杂。

我想了解git commit --amend在正常的 HEAD 情况下是如何工作的。

4

3 回答 3

32

假设您处于干净的工作状态并且您的存储库如下所示:

在此处输入图像描述

如果你然后运行

git commit --amend

编写提交消息,保存并退出编辑器,会发生以下情况:

  1. 您的暂存区域(如果您没有暂存任何新更改,将与提交f42c5相同)用于创建新提交:31b8e。它的父级将与您正在修改的提交的(那些)相同:f42c5
  2. 主分支引用被移动以指向该新提交(31b8e
  3. HEAD参考遵循master

在此处输入图像描述

请注意,修改后的提交 ( f42c5 ) 现在无法从您的存储库中的任何引用中访问(因此在我的图表中它的“透明”样式)。它仍然存在于您的存储库的对象数据库中,但是当 Git 运行其定期内务管理时,或者您通过运行git gc(垃圾收集)显式触发它时,它最终会被永久删除。


附录(基于Jason Baker 的评论):请注意,只要修改后的提交f42c5仍然存在于您的存储库中,并且您有办法找出它的提交 ID(例如,通过从master分支的 reflog中找出它) ),您仍然可以查看它。跑步

git checkout master # just to be sure that master is the current branch
git reset --hard f42c5

或(假设您在此期间没有对master、reset master或以其他方式移动master分支引用进行任何新提交)

git checkout master # just to be sure that master is the current branch
git reset --hard master@{1}

会让你处于以下情况:

在此处输入图像描述

但是现在,提交31b8e将变得无法访问。


于 2014-09-26T00:53:12.070 回答
8

假设你刚刚提交了“B”

... --- A --- B
              ^
              |
            master
             HEAD

修改“B”将创建一个并行提交,它成为新的分支头。

        +---- B
        |
... --- A --- B'
              ^
              |
            master
             HEAD

B' 是来自 B 的更改加上您在发布git commit --amend.

于 2014-09-26T00:46:53.657 回答
1

据我所知,修改作品如下:

对于git commit --amend工程,修改的更改必须进入临时区域 (SA)

  1. 它使git reset -- soft在最后一次提交(提交修改)中提交的更改恢复到 SA,并将索引移动到上一次提交(在提交修改之前提交)。git commit一切都保持在使用命令之前的状态。
  2. 它使git add所有文件都添加到新提交中(它将是修改后的提交)。要添加的文件是登陆前SA中的git reset --soft文件,重置后这些文件保存在工作目录(WD)中,因此有必要将它们添加到SA中以生成修改后的提交
  3. 它进行 Git 提交。它将生成一个新的提交,从而为修改后的提交生成一个新的 id 。为此,git commit --amend不应与push commits一起使用。

如果你使用的评论在修改后的提交--no-edit中被重用,否则你必须引入一个新的评论(因为它是一个新的提交,每个提交都需要一个评论)。

有关暂存区和工作目录的更多信息,请参阅Reset Demystified

于 2017-10-17T15:50:12.693 回答