如何修改旧的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^^^
现在用edit
或e
标记你想要修改的那个(replacepick
)。 现在保存并退出。
那么现在进行更改
git add -A git commit --amend --no-edit git rebase --continue
如果你想添加一个额外的删除从提交命令中删除选项。 如果您想调整消息,请忽略--no-edit
选项。
我准备了一个我想用一个更老的修改的承诺,并且很惊讶地看到rebase -i抱怨说我有一些不确定的变化。 但我不想再指定更旧提交的编辑选项进行更改。 所以解决scheme非常简单直接:
- 准备更新到更旧的提交,添加并提交
-
git rebase -i <commit you want to amend>^
注意^
所以你在文本编辑器中看到了这个提交 -
你会得到这样的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
-
现在结合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
-
写入和退出文件,您将出现一个编辑器来合并提交消息。 这样做并保存/退出文本文档
- 你完成了,你的提交被修改了
信贷去: 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 add
( git add -i
, git 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。