【发布时间】:2014-11-20 22:04:36
【问题描述】:
我见过'git commit --amend' in detached HEAD state。这个问题要求答案比需要的复杂。
我想了解git commit --amend 在正常 HEAD 情况下的工作原理。
【问题讨论】:
标签: git git-commit git-amend
我见过'git commit --amend' in detached HEAD state。这个问题要求答案比需要的复杂。
我想了解git commit --amend 在正常 HEAD 情况下的工作原理。
【问题讨论】:
标签: git git-commit git-amend
据我所知,amend 是这样工作的:
对于git commit --amend 作品,要修改的更改必须进入暂存区(SA)
git reset -- soft 将上次提交(提交修改)中提交的更改带回 SA,并将索引移动到上一次提交(提交前提交修改)。一切都保持在使用git commit 命令之前的状态。git add 将所有文件添加到新提交中(它将是修改后的提交)。要添加的文件是在git reset --soft 登陆之前进入 SA 的文件,重置后这些文件保存在工作目录 (WD) 中,因此有必要将它们添加到 SA 以生成 修改的提交。git commit --amend 不应与 推送的提交 一起使用。如果你使用--no-edit,评论会在修改后的提交中重复使用,否则你必须引入一个新的评论(因为它是一个新的提交,每个提交都需要一个评论)。
有关暂存区和工作目录的更多信息,请参阅Reset Demystified。
【讨论】:
假设您处于干净的工作状态并且您的存储库如下所示:
如果你然后运行
git commit --amend
编写提交消息,保存并退出编辑器,会发生以下情况:
请注意,修改后的提交 (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
git reset always 重置了 current 分支(这意味着不能分离 HEAD , 也)。把checkout master放在第一位,等等……
:)
reset 正在重新设置什么。
假设你刚刚提交了“B”
... --- A --- B
^
|
master
HEAD
修改“B”将创建一个并行提交,它成为新的分支头。
+---- B
|
... --- A --- B'
^
|
master
HEAD
B' 是由来自 B 的更改加上您在发出 git commit --amend 时暂存的更改组合而成的提交。
【讨论】: