我已经看到 *'git commit --amend'处于分离的HEAD状态 *。这个问题的答案需要比实际需要的更复杂。我想了解git commit --amend在正常的HEAD情况下是如何工作的。
git commit --amend
xlpyo6sf1#
假设您处于干净得工作状态,并且存储库如下所示:
如果你再跑
编写提交消息、保存并退出编辑器时,会发生以下情况:1.您的暂存区-如果您没有暂存任何新的更改,它将与commit * f42 c5 * 相同-用于创建一个新的commit:* 31 b8 e 。它的父级将与您正在修改的提交的父级相同: f42 c5 * 的数据。1.master 分支引用被移动以指向该新提交(* 31 b8 e *)。1.HEAD 引用跟在 master 后面。
请注意,修改后的提交(* f42 c5 *)现在无法从仓库中的任何引用访问到(因此在我的图中它是“透明”的)。它仍然存在于仓库的对象数据库中,但最终会被永久删除,当Git运行其周期性的内务管理时,或者如果您通过运行git gc(垃圾收集)显式触发它。
git gc
附录(基于Jason Baker的意见):请注意,只要修改后的提交 * f42 c5 * 仍然存在于仓库中,并且您有办法找到它的提交ID(例如,通过从 master 分支的reflog中找到它),您仍然可以将它 checkout 。
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}
会让您处于以下情况:
但现在,提交 * 31 b8 e * 将变得不可访问。
wa7juj8i2#
假设你犯了B罪
... --- A --- B ^ | master HEAD
修改“B”将创建一个成为新分支头的并行提交。
+---- B | ... --- A --- B' ^ | master HEAD
B'是B的变更加上您发出git commit --amend时所暂存的变更组合所产生的认可。
6pp0gazn3#
据我所知,amend 作品:对于git commit --amend工程,要修改的变更必须进入 * 交错区(SA)*1.它使用git reset -- soft将上次提交(提交修改)中提交的更改带回到SA,并将索引移动到上一次提交(提交修改之前的提交)。所有内容都保持使用git commit命令之前的状态。1.它使git add与所有文件一起添加到新提交(它将是 * 修正提交 *)。要添加的文件是那些在git reset --soft着陆之前进入SA的文件,并且在重置后这些文件被保存在工作目录(WD)中,因此有必要将它们添加到SA以生成 * 修正提交 *。1.它会生成一个新的提交,并为 amended commit 生成一个新的id。因此,git commit --amend不应该与 pushed commit * 一起使用。如果你使用--no-edit,注解会在 * amded commit 中被重用,否则你必须引入一个新的注解(因为这是一个新的提交,每个提交都需要一个注解)。如需有关临时区域和工作目录的详细信息,请参阅 Reset Demystified。
git reset -- soft
git commit
git add
git reset --soft
--no-edit
hof1towb4#
假设您创建了两个文件test1.txt和test2.txt,然后运行
git add test1.txt && git commit -m “test1.txt and test2.txt “
后来你记得你没有添加test2.txt所以你想添加缺少的test2.txt文件并修改之前的提交git add test2.txt
git commit --amend -m "test1.txt & test2.txt added" git log [to see that the previous commit message updated and test2.txt file added]
4条答案
按热度按时间xlpyo6sf1#
假设您处于干净得工作状态,并且存储库如下所示:
如果你再跑
编写提交消息、保存并退出编辑器时,会发生以下情况:
1.您的暂存区-如果您没有暂存任何新的更改,它将与commit * f42 c5 * 相同-用于创建一个新的commit:* 31 b8 e 。它的父级将与您正在修改的提交的父级相同: f42 c5 * 的数据。
1.master 分支引用被移动以指向该新提交(* 31 b8 e *)。
1.HEAD 引用跟在 master 后面。
请注意,修改后的提交(* f42 c5 *)现在无法从仓库中的任何引用访问到(因此在我的图中它是“透明”的)。它仍然存在于仓库的对象数据库中,但最终会被永久删除,当Git运行其周期性的内务管理时,或者如果您通过运行
git gc
(垃圾收集)显式触发它。附录(基于Jason Baker的意见):请注意,只要修改后的提交 * f42 c5 * 仍然存在于仓库中,并且您有办法找到它的提交ID(例如,通过从 master 分支的reflog中找到它),您仍然可以将它 checkout 。
或者(假设您在此期间没有在 master 上进行任何新的提交,重置 master,或者移动 master 分支引用)
会让您处于以下情况:
但现在,提交 * 31 b8 e * 将变得不可访问。
wa7juj8i2#
假设你犯了B罪
修改“B”将创建一个成为新分支头的并行提交。
B'是B的变更加上您发出
git commit --amend
时所暂存的变更组合所产生的认可。6pp0gazn3#
据我所知,amend 作品:
对于
git commit --amend
工程,要修改的变更必须进入 * 交错区(SA)*1.它使用
git reset -- soft
将上次提交(提交修改)中提交的更改带回到SA,并将索引移动到上一次提交(提交修改之前的提交)。所有内容都保持使用git commit
命令之前的状态。1.它使
git add
与所有文件一起添加到新提交(它将是 * 修正提交 *)。要添加的文件是那些在git reset --soft
着陆之前进入SA的文件,并且在重置后这些文件被保存在工作目录(WD)中,因此有必要将它们添加到SA以生成 * 修正提交 *。1.它会生成一个新的提交,并为 amended commit 生成一个新的id。因此,
git commit --amend
不应该与 pushed commit * 一起使用。如果你使用
--no-edit
,注解会在 * amded commit 中被重用,否则你必须引入一个新的注解(因为这是一个新的提交,每个提交都需要一个注解)。如需有关临时区域和工作目录的详细信息,请参阅 Reset Demystified。
hof1towb4#
假设您创建了两个文件test1.txt和test2.txt,然后运行
后来你记得你没有添加test2.txt所以你想添加缺少的test2.txt文件并修改之前的提交git add test2.txt