You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何改写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

由于是该分支唯一开发者,可接受改写历史并强制推送,以下是两种可行方法:


方法一:重置后重新提交(操作简洁直接)

  1. 回退到提交A的干净状态:

    git reset --hard A
    

    (如果不知道A的哈希值,也可以用git reset --hard HEAD~2直接回退两个提交)

  2. 编辑test.txt,保留111并添加222,提交为D:

    git add test.txt
    git commit -m "adding 222"
    
  3. 再次编辑test.txt,添加333,提交为E:

    git add test.txt
    git commit -m "adding 333"
    
  4. 强制覆盖远程分支的历史:

    git push -f origin feat
    

方法二:交互式Rebase拆分提交(保留原始修改逻辑)

  1. 启动交互式rebase,针对提交A之后的两个提交进行修改:

    git rebase -i A
    

    (若无法确定A的哈希,用git rebase -i HEAD~2也可)

  2. 在弹出的编辑器中调整提交指令:

    • 把提交C的pick改成drop(丢弃这个移除333的提交)
    • 把提交B的pick改成edit(需要拆分这个提交的内容)
      修改后的内容示例:
    edit b123456 adding 222, 333
    drop c789012 removing 333
    

    保存并关闭编辑器,Git会自动回到提交B的修改应用后的状态。

  3. 拆分提交B的修改:
    执行命令将B的提交内容转为未暂存状态:

    git reset HEAD^
    
  4. 单独提交添加222的变更(即提交D):
    用交互式暂存选择仅包含222的行:

    git add -p test.txt
    

    按照提示输入y确认添加222的变更,然后提交:

    git commit -m "adding 222"
    
  5. 提交添加333的变更(即提交E):

    git add test.txt
    git commit -m "adding 333"
    
  6. 完成rebase流程:

    git rebase --continue
    
  7. 强制推送改写后的历史到远程:

    git push -f origin feat
    

内容的提问来源于stack exchange,提问作者Hao Wu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 18:23:16