背景
最近项目开发中,在master分支拉一个dev分支,开发完毕之后,需要把dev的新增代码合并到测试分支,由于历史和项目原因,只能把dev分支的新增代码“复制”到测试分支。发布gray和master同理。
其实如果是单人开发还好,直接吧commit1-commit4通过cherry-pick到对应的分支就可以了。
但是实际工作中,往往有多种情况,导致cherry-pick的时候,需要很多冲突需要解决,当需求时间比较长,甚至有上百次commit,每次cherry-pick的时候,头皮发麻。
设想
要是能有一种方法,能把示例中的commit1-commit4合并成一次提交,然后再进行cherry-pick,这样即使有冲突,也只需要解决一次就OK了。
说到这里,很多人想到的肯定是使用git rebase。
实际上,如果cherry-pick有冲突的情况,git rebase照样会有各种冲突,而且很多人甚至不了解怎么使用git rebase。
这样做无非就是脱裤子放屁。
操作方法
这里不卖关子了,我这里说的方法,就是使用git reset。
具体操作为:
git reset --soft commit0
git commit -m 'commit message'
这样操作之后,commit1-commit4的所有修改就变成一次提交。这时候再去进行cherry-pick。
解释一下:
commit0指的是,commit1的前一次提交的commit id,因为我们需要把commit1-commit4的修改合并为一次。--soft参数指的是,回退到commit0的位置,但是从commit0(不包含)以后的提交和修改,全部在git的暂存区,看起来好像是我从master拉了一个新分支,然后把commit1-commit4的修改内容全部一次性做完,然后进行了一次git add .。git commit之后,commit1-commit4的修改就变成一次提交了。- 这时候再进行
cherry-pick。
注意点
- 请从
dev分支重新拉一个新分支进行该操作,搞砸了容易补救。 cherry-pick到其他分支的时候,也从相应的分支拉一个新分支操作,完毕之后,使用新分支去merge。commit1-commit4的修改去都需要发布,如果某次提交不需要,则不适用。- 这样操作之后,
commit1-commit4的提交信息将会丢失,如果比较在意或者有相关要求,则不适用。
规范操作流程
# 目标:当前在dev分支,需要cherry-pick到master分支
# 从dev分支拉一个新分支,方便后续有问题容易补救
git checkout -b dev-new
# 回退到第一次提交前,并保留记录
git reset --soft commit0
# 提交
git commit -m 'commit all'
# 切换到master分支
git checkout master
# 从master拉一个新分支,方便后续有问题容易补救
git checkout -b master-new
# 给dev-new的最近一次提交(包含所有修改)cherry-pick到master-new分支
git cherry-pick dev-new
# 切回到master分支
git checkout master
# 把修改merge到master分支/或者进行CR、打tag、merge操作
git merge master-new
总结
有其他更好方法,欢迎讨论。