如何改写Git提交历史,反转两次提交的状态并调整顺序?
改写Git提交历史的可行方案
背景说明
当前处于feat分支,初始状态下test.txt内容为:
111
创建提交B,新增两行内容,变更如下:
111 + 222 + 333此时提交历史:
B(origin/feat) # adding 222, 333 | A随后创建提交C移除
333,变更如下:111 222 - 333当前提交历史变为:
C(feat) # removing 333 | B(origin/feat) # adding 222, 333 | A
希望将提交历史改写为:
E(origin/feat) # adding 333 (state of B) | D # adding 222 (state of C) | A
由于是该分支唯一开发者,可接受改写历史并强制推送,以下是两种可行方法:
方法一:重置后重新提交(操作简洁直接)
回退到提交A的干净状态:
git reset --hard A(如果不知道A的哈希值,也可以用
git reset --hard HEAD~2直接回退两个提交)编辑
test.txt,保留111并添加222,提交为D:git add test.txt git commit -m "adding 222"再次编辑
test.txt,添加333,提交为E:git add test.txt git commit -m "adding 333"强制覆盖远程分支的历史:
git push -f origin feat
方法二:交互式Rebase拆分提交(保留原始修改逻辑)
启动交互式rebase,针对提交A之后的两个提交进行修改:
git rebase -i A(若无法确定A的哈希,用
git rebase -i HEAD~2也可)在弹出的编辑器中调整提交指令:
- 把提交C的
pick改成drop(丢弃这个移除333的提交) - 把提交B的
pick改成edit(需要拆分这个提交的内容)
修改后的内容示例:
edit b123456 adding 222, 333 drop c789012 removing 333保存并关闭编辑器,Git会自动回到提交B的修改应用后的状态。
- 把提交C的
拆分提交B的修改:
执行命令将B的提交内容转为未暂存状态:git reset HEAD^单独提交添加222的变更(即提交D):
用交互式暂存选择仅包含222的行:git add -p test.txt按照提示输入
y确认添加222的变更,然后提交:git commit -m "adding 222"提交添加333的变更(即提交E):
git add test.txt git commit -m "adding 333"完成rebase流程:
git rebase --continue强制推送改写后的历史到远程:
git push -f origin feat
内容的提问来源于stack exchange,提问作者Hao Wu
相关产品推荐
相关产品推荐

