2014-09-26 72 views

回答

16

假设你在一个干净的工作状态,并且您的回购如下所示:

enter image description here

如果你再运行

git commit --amend 

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

  1. 您的暂存区域 - 如果您没有s进行任何新的更改,将与提交f42c5相同 - 用于创建新提交:31b8e。它的父代将与您正在修改的提交(那些)相同:f42c5
  2. master分支引用移至指向新提交(31b8e)。
  3. HEAD参考master

enter image description here

需要注意的是修改后的提交(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 [email protected]{1} 

将使您在以下情况:

enter image description here

但现在,提交31b8e将BEC ome无法访问。


+0

您可以通过“checkout”或通过reflog回到'f42c5'吗?我承认这将是一件愚蠢的事情,但我很好奇,如果可以访问旧提交* * – 2014-09-26 00:59:20

+1

@JasonBaker是的,你总是可以检查修改后的(现在无法访问的)提交,只要它还没有被垃圾收集,你有一个方法来提及它。 – Jubobs 2014-09-26 01:11:29

+1

呵呵,现在命令不太正确,'git reset' * always *会重置* current *分支(这意味着'HEAD'也不能被分离)。把结账大师放在第一位,等等...... – torek 2014-09-26 01:19:44

4

说你只是犯了“B”

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

修订“B”将建立一个平行的承诺成为新的分支头。

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

B”是从提交的从B改变加时发出的git commit --amend你已经上演了变化的组合产生。

+1

要建立在此答案上,B'将包含来自B的更改的组合,以及您现在坐在回购中的任何分阶段更改 – 2014-09-26 00:47:59

+0

@Jason Baker,Added。 – ikegami 2014-09-26 00:50:16

0

据我所知,ammend作品这样的:

git commit --ammend工作的变化ammend必须到脚手架区(SA)

  1. 它使git reset -- soft对带回的变化在SA的最后一次提交(提交给ammend)中提交并将索引移动到先前的提交(在提交之前提交以进行修改)。一切都保持了git commit命令之前的使用。
  2. 它使git add与所有文件添加到新的提交(这将是ammend承诺)。要添加的文件是那些在git reset --soft登陆之前进入SA的文件,重置后此文件将保存到WD中,因此有必要将它们添加到SA以生成推荐提交
  3. 使git提交。它将生成一个新的提交,因此推荐提交的新ID。对于这一点,git的承诺--ammend不应该被用来与推提交

如果使用--no-edit注释重新应用于ammended提交,否则你必须引入一个新的评论(becouse它是一个新的提交,每个提交需要注释)。

有关脚手架区和工作目录的详细信息,请参阅Reset Demystified