如何修改旧的Git提交?

我做了3个git提交,但没有被推送。 我怎样才能修改不是最新的那个(ddc6859af44)和(47175e84c)?

$git log commit f4074f289b8a49250b15a4f25ca4b46017454781 Date: Tue Jan 10 10:57:27 2012 -0800 commit ddc6859af448b8fd2e86dd0437c47b6014380a7f Date: Mon Jan 9 16:29:30 2012 -0800 commit 47175e84c2cb7e47520f7dde824718eae3624550 Date: Mon Jan 9 13:13:22 2012 -0800 
 git rebase -i HEAD^^^ 

现在用edite标记你想要修改的那个(replacepick )。 现在保存并退出。

那么现在进行更改

 git add -A git commit --amend --no-edit git rebase --continue 

如果你想添加一个额外的删除从提交命令中删除选项。 如果您想调整消息,请忽略--no-edit选项。

我准备了一个我想用一个更老的修改的承诺,并且很惊讶地看到rebase -i抱怨说我有一些不确定的变化。 但我不想再指定更旧提交的编辑选项进行更改。 所以解决scheme非常简单直接:

  1. 准备更新到更旧的提交,添加并提交
  2. git rebase -i <commit you want to amend>^注意^所以你在文本编辑器中看到了这个提交
  3. 你会得到这样的sometihng:

     pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies pick e23d23a fix indentation of jgroups.xml 
  4. 现在结合e23d23a与8c83e24你可以改变线的顺序,并使用像这样的壁球:

     pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync squash e23d23a fix indentation of jgroups.xml pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies 
  5. 写入和退出文件,您将出现一个编辑器来合并提交消息。 这样做并保存/退出文本文档

  6. 你完成了,你的提交被修改了

信贷去: http : //git-scm.com/book/en/Git-Tools-Rewriting-History还有其他有用的演示git魔术。

你可以使用git rebase --interactive ,在你想修改的提交上使用edit命令。

你可以使用git rebase来重写提交历史logging。 这可能对您的更改具有潜在破坏性,请小心使用。

首先将您的“修改”更改提交为正常提交。 然后,从最早的提交的父项开始进行交互式重新分页

 git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^ 

这将启动您的编辑与所有提交。 对它们进行重新sorting,以便您的“修改”提交低于您要修改的提交。 然后用s的“修改”提交replace行中的第一个单词,这将与之前的提交相结合。 保存并退出编辑器并按照说明操作。

我用了另一种方式几次。 事实上,这是一个手动的git rebase -i ,当你想重新排列几个提交包括挤压或拆分其中的一些时,它是有用的。 主要优点是您不必一次就决定每个提交的命运。 在这个过程中,您也将拥有所有Gitfunction,而不像在重新绑定期间一样。 例如,您可以随时显示原始历史logging和重写历史logging,甚至可以进行另一次变更!

我将以下面的方式引用提交,所以它很容易读取:

 C # good commit after a bad one B # bad commit A # good commit before a bad one 

一开始你的历史就是这样的:

 x - A - B - C | | | master | origin/master 

我们将以这种方式重新创build它:

 x - A - B*- C' | | | master | origin/master 

这是程序:

 git checkout B # get working-tree to the state of commit B git reset --soft A # tell git that we are working before commit B git checkout -b rewrite-history # switch to a new branch for our alternative history 

现在使用git addgit add -igit stash等)来改进你的旧提交。 你甚至可以将旧的提交分成两个或更多。

 git commit # recreate commit B (result = B*) git cherry-pick C # copy C to our new branch (result = C') 

中间结果:

 x - A - B - C | \ | | \ master | \ | B*- C' | | | rewrite-history | origin/master 

我们来完成:

 git checkout master git reset --hard rewrite-history # make this branch master 

就是这样,你现在可以push你的进步。

如果OP想要将指定的2个提交压缩为1,则这是另一种不用重新绑定的方法

 git checkout HEAD^ # go to the first commit you want squashed git reset --soft HEAD^ # go to the second one but keep the tree and index the same git commit --amend -C HEAD@{1} # use the message from first commit (omit this to change) git checkout HEAD@{3} -- . # get the tree from the commit you did not want to touch git add -A # add everything git commit -C HEAD@{3} # commit again using the message from that commit 

@{N)语法很方便知道,因为它可以让你引用你的引用的历史。 在这种情况下,它是代表你当前提交的HEAD。