使用Git命令行修改已提交commit
通过Git提交代码时,需要尽量将每次提交的内容原子化及故事化,即每次commit只包含一个最小化的功能,使多个commit串起开发逻辑,类似commit 提交历史的message串起来关于开发过程的故事线。
但是,在实际的开发中,很难达到这样理想化的结果,经常出现commit后发现又有新的文件要修改,或者多个功能写在了一起并且放在了一条commit中。后期为了维护commit历史需要拆分或修改commit内容,总结来看,包括下面两个场景:
- 对已commit的内容进行修改
- 将原commit的部分文件拆分到新的commit中。
针对这两个场景,我们有各自的方法来处理。
修改commit文件的内容
针对场景1
向最新commit追加新修改
对于已经修改好的文件,首先执行git add
:
git add xxx # xxx为修改对象文件名 或
git add --all # git add所有修改的文件
之后执行下面命令,即可将上面git add
的文件追加到最新的commit中。
git commit --amend
修改过去任意commit的内容
如果不是对最新的commit进行修改,而是需要修改过去某个commit的内容,则需要执行以下步骤。
首先,查看log,执行git log --graph --oneline
找到需要拆分或修改的commit ID。
假如我们想要修改原倒数第二个的commit即344494a
中file4的内容。
git log --graph --oneline
# 得到下面结果
51d62f0 this is the latest commit # 最新commit,包含file1, file2, file3
344494a this is the second-to-last commit # 倒数第二个commit,包含file4
xxxxxxx other commit # 其它更早的commit
# 从344494a即倒数第二个commit开始rebase
git rebase -i HEAD~2
此时代码的状态是344494a
commit后的内容,修改file4后,执行下面命令,即将修改的内容更新进了344494a
。
git add file4
git commit --amend
仍然需要继续进行git rebase --continue
,直到所有的commit都rebase完毕。
拆分commit文件
针对场景2
仍然以上面的几个commit为例。
首先,查看log,找到需要拆分或修改的commit ID。
git log --graph --oneline
# 得到下面结果
51d62f0 this is the latest commit # 最新commit,包含file1, file2, file3
344494a this is the second-to-last commit # 倒数第二个commit,包含file4
xxxxxxx other commit # 其它更早的commit
# 假如我们要修改倒数第二个commit,那么执行下面命令,从倒数第二个commit开始进行rebase修改。
git rebase -i HEAD~2
此时,我们就处在倒数第二个commit下,可以对这里的内容进行任何修改。
如果需要对最新commit进行拆分,比如将部分文件放在一个新的commit中,如:
# 原来的两个commit
51d62f0 this is the latest commit # 待拆分的commit,包含文件file1, file2, file3, 需要将file3放在新的commit中
344494a this is the second-to-last commit # 倒数第二个commit,包含file4
由于此时我们处在倒数第二个commit即344494a
下,最新的commit内容file1,file2,file3还不存在,此时,我们只需要在344494a
的基础上,新建file3,然后执行下面命令,即可新建commit:
git add file3
git commit -m "this is the newly created commit"
git rebase --continue
拆分后的commit内容如下:
# 拆分后的commit
51d62f0 this is the latest commit # 拆分后的原commit,此时仅包含文件file1, file2
bf67971 this is the newly created commit # 新拆分出来的commit,包含文件file3
344494a this is the second-to-last commit # 原倒数第二个commit,包含file4
正常情况下,最新的commit即51d62f0
中已经不再包含file3。如果包含,那么git没有自动处理,那么可以手动将其删除。由于git rebase --continue
后,我们已经处于51d62f0
的rebase过程中,因此手动删除后,再执行git commit --amend
,此时的修改(删除file4)将会更新进51d62f0
中。
之后继续进行最新commit的修改,直到所有commit都修改完成:
git rebase --continue