【问题标题】:How does git commit --amend work, exactly?git commit --amend 究竟是如何工作的?
【发布时间】:2014-11-20 22:04:36
【问题描述】:

我见过'git commit --amend' in detached HEAD state。这个问题要求答案比需要的复杂。

我想了解git commit --amend 在正常 HEAD 情况下的工作原理。

【问题讨论】:

    标签: git git-commit git-amend


    【解决方案1】:

    据我所知,amend 是这样工作的:

    对于git commit --amend 作品,要修改的更改必须进入暂存区(SA)

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

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

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

    【讨论】:

      【解决方案2】:

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

      如果你然后运行

      git commit --amend
      

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

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

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


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

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

      或(假设您在此期间没有对 master 进行任何新的提交、重置 master 或以其他方式移动 master 分支参考)

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

      会让你处于以下情况:

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


      【讨论】:

      • 您可以通过checkout 或通过reflog 回到f42c5 吗?我承认这样做很愚蠢,但我很好奇旧的提交是否可以访问 at all
      • @JasonBaker 是的,你可以随时查看修改后的(现在无法访问)提交,只要它没有被垃圾收集,并且你有办法引用它。
      • 呵呵,现在命令不太对劲,git reset always 重置了 current 分支(这意味着不能分离 HEAD , 也)。把checkout master放在第一位,等等……
      • @torek Sh*t...我最终会得到它...这种体操已经太晚了,在我的时区:)
      • 如果您已经在上面,则不会。这只是为了确保我们知道 reset 正在重新设置什么。
      【解决方案3】:

      假设你刚刚提交了“B”

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

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

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

      B' 是由来自 B 的更改加上您在发出 git commit --amend 时暂存的更改组合而成的提交。

      【讨论】:

      • 在此答案的基础上,B' 将包含来自 B 的更改的组合,以及您现在在存储库中进行的任何分阶段更改
      • “组合”到底是什么意思?也许更新答案?
      猜你喜欢
      • 2012-08-18
      • 2013-06-26
      • 1970-01-01
      • 2010-11-30
      • 2017-04-15
      • 2011-06-26
      • 2021-08-15
      • 2012-06-08
      • 2011-10-11
      相关资源
      最近更新 更多