Break a previous commit into multiple commits
Break a previous commit into multiple commits
技术背景
在使用Git进行版本控制时,有时会遇到一个提交包含了多个不同功能或修改的情况。为了让提交历史更加清晰、易于维护和审查,需要将一个之前的提交拆分成多个独立的提交。
实现步骤
准备工作
开始操作前,确保工作目录是干净的,即git status
应显示没有待修改、删除或添加的文件。
拆分最近的提交
如果要拆分最近的提交,可按以下步骤操作:
- 使用
git reset HEAD~
撤销最近的提交,将修改放回工作区。 - 按正常方式分别提交各个部分,生成所需数量的提交。
拆分较早的提交
这需要进行变基(rebasing)操作,即重写历史。指定正确的提交有以下几种选择:
- 若要拆分的提交是倒数第3个,则使用
git rebase -i HEAD~3
。 - 若提交在提交树中较深,不想手动数,可以使用
git rebase -i 123abcd~
,其中123abcd
是要拆分的提交的SHA1值。 - 若要对整个当前分支进行变基,可使用
git rebase -i
。 - 若在不同的分支(如功能分支)上,并想将其合并到
master
分支,可使用git rebase -i master
。
当进入变基编辑界面后,找到要拆分的提交,将行首的pick
替换为edit
(简写为e
),保存并退出。变基会在要编辑的提交之后停止,然后执行git reset HEAD~
,再按正常方式分别提交各个部分,最后执行git rebase --continue
完成变基。
保留提交作者信息
如果要保留提交的作者信息和日期,可参考相关链接。
拆分单个文件中的更改
拆分文件到不同提交时,若要拆分单个文件中的更改,有两种选择:
- 使用
git reset HEAD~
后,通过git add -p
逐个选择要包含在每个提交中的补丁。 - 编辑工作副本,移除不需要的更改,提交中间状态,然后恢复完整提交进行下一轮操作。
使用TortoiseGit拆分提交
在Windows上的最新版TortoiseGit中,可按以下步骤操作:
- 打开变基对话框并进行配置。
- 右键单击要拆分的提交,选择
Edit
。 - 点击
Start
开始变基。 - 到达要拆分的提交时,勾选
Edit/Split
按钮,直接点击Amend
,打开提交对话框。 - 取消选择要单独提交的文件。
- 编辑提交消息,然后点击
commit
。 - 重复上述步骤,直到没有文件需要提交。
在IDE中拆分提交(以IntelliJ IDEA等为例)
- 在版本控制日志窗口中,选择要拆分的提交,右键单击并选择
Interactively Rebase from Here
。 - 将需要拆分的提交标记为
edit
,点击Start Rebasing
。 - 当看到黄色标签表示HEAD已设置到该提交时,右键单击该提交,选择
Undo Commit
。 - 此时这些提交会回到暂存区,可分别提交它们。所有更改提交完成后,旧的提交将变为无效。
不使用交互式变基拆分提交
可按以下步骤操作:
1 |
|
之后就可以像平常一样分别提交这些更改。
使用脚本拆分提交
可将以下脚本内容复制到名为git-split
的文件中,放到$PATH
包含的文件夹中,并使其可执行,然后使用git split
运行该脚本:
1 |
|
使用Sublime Merge拆分提交
- 在提交列表中选择要修改的提交,右键单击并选择
Edit Commit > Edit Commit Contents
。 - 此时处于HEAD状态,提交内容在暂存区。
- 取消暂存要分离的文件、块或行,只保留第一个提交的内容。
- 提供提交消息,然后按
Commit
。 - 根据需要暂存/提交,直到将提交拆分为所需的样子。
- 当没有未提交的更改时,按
Continue Rebase
。
核心代码
拆分较早提交的示例代码
1 |
|
不使用交互式变基拆分提交的示例代码
1 |
|
最佳实践
- 在进行拆分提交操作前,建议先备份分支,以免操作失误导致历史记录丢失。
- 拆分提交后,若分支已推送到远程仓库,需要使用
git push --force
强制推送,但要注意强制推送可能会影响其他协作者的工作。 - 拆分提交时,尽量让每个提交的内容具有原子性,即每个提交只包含一个逻辑上独立的更改。
常见问题
变基过程中出现冲突怎么办?
当变基过程中出现冲突时,需要手动解决冲突。解决冲突后,使用git add
将解决后的文件添加到暂存区,然后使用git rebase --continue
继续变基。
拆分提交后提交历史变得混乱怎么办?
可以使用git log
查看提交历史,确认是否符合预期。如果提交历史仍然混乱,可以考虑重新进行拆分操作或使用git reflog
恢复到之前的状态。
Break a previous commit into multiple commits
https://119291.xyz/posts/break-a-previous-commit-into-multiple-commits/