最近在开发过程中遇到一个关于 git 的问题,个人认为比较经典,因此把问题和解决方案总结出来进行分享。
背景
公司 git 分支类型分为以下三类:
- release(预发分支):用于合并开发分支后,打 tag 发布上线
- text-web(测试分支):用于合并其他成员的新需求开发或者 bug 修复分支,然后进行测试环境构建
- dev/feat(开发分支):用于新需求/bug 开发
我通过新建分支 dev-illustrate 进行新需求开发,在开发过程中将开发分支合并到了 text-100 测试分支用于测试环境重新构建来验证功能。我在此处出现的错误是:我本地先切换测试分支 text-100 进行拉取,然后切换回开发分支 dev-illustrate ,合并了 text-100 测试分支,然后没有冲突后切换回 text-100 分支,然后将 dev-illustrate 分支再合并到 text-100 分支。
问题原因
前面所讲,测试分支的用途是开发者将开发分支合并到测试分支,然后通过测试环境重新构建,测试功能开发的笑果。那么测试分支会存在其他开发者已开发好的功能/正在开发的功能(目前不进行上线)的代码,如果我们将测试分支合并到了本地开发分支,后续测试环境验证无误后,要将开发分支合并到 预发分支,等待上线通知,此时发布的预发分支中会包含其他开发者已开发好的功能/正在开发的功能,但是这些功能是不进行上线的。
解决方案
- 将本地代码进行备份,然后新创建一个开发分支,同时当前开发分支重置到原开发分支 测试分支合并到开发分支 前的commit版本,然后对照原开发分支的历史修改记录和备份文件修改新开发分支的文件。
- 将测试分支重置到测试分支合并到原开发分支前的commit版本,然后将新创建的开发分支合并到回退后的测试分支,测试环境进行测试,没问题后等待上线通知。(注:此时其他开发者本地的测试分支需要重置到远程的正确状态)
过程回顾
前置条件:text-100(测试分支),dev-illustrate(开发分支),release(预发分支)
// 克隆仓库地址,新建分支别切换指定分支
git clone url地址
cd 文件夹名称
git checkout release
git checkout -b dev-illustarte
// 开发功能1(commit1)
git add .
git commit -m "开发功能1"
git push --set-upstream origin dev-illustarte
git checkout text-100
git pull
git merge dev-illustarte
// 如果有冲突,解决冲突后输入指令
// git add .
// git merge --continue
// 开发功能2(commit2)
git add .
git commit -m "开发功能2"
git push
git checkout text-100
git pull
git merge dev-illustarte
// 开发功能3(commit3)
git add .
git commit -m "开发功能3"
git push
git checkout text-100
git pull
git checkout dev-illustarte
git merge text-100 // 此时将测试分支代码合并到了本地开发分支,有冲突要解决冲突
git checkout text-100
git merge dev-illustarte // 此时将合并后的本地分支(包含了其他开发者开发的功能)合并到测试分支
git checkout dev-illustrate
// 开发功能3(commit4)
git add .
git commit -m "开发功能4"
git push
git checkout text-100
git pull
git checkout dev-illustarte
git merge text-100
git checkout text-100
git merge dev-illustarte
git checkout dev-illustrate
...
// 功能开发完成
解决方案
// 第一步:将本地文件做备份,重置测试分支
// 测试分支重置到“测试分支合并到本地开发分支”之前的commit版本(需要在text-100分支的提交记录中查找)
git checkout text-100
git reset --hard <commit_hash>
// 这里注意其他开发者本地的 测试分支text-100 仍然是有之前的历史记录
// 重置为当前的最新版本
git fetch origin
git reset --hard origin/text-100
// 第二步:新建分支并切换到 dev-illustarte 分支的指定commit版本(测试分支合并到本地开发分支,即commit2)
git checkout -b 新分支名称
git reset --hard commit值
// 第三步:根据dev-illustarte的提交历史结合备份文件,对新开发分支代码进行修改,然后合并到 text-100测试分支,在测试环境进行测试,没有问题后合并到 release 分支,等待上线通知
多人开发测试分支合并小技巧
// 多人合作开发开发一个项目,往往有一个测试分支用于测试环境的构建,验证开发者功能。对于每个开发者来说,每次功能/bug完成后都要合并到测试分支,我们的做法一般是:
// 假设测试分支为 feature-test
git checkout feature-test // 本地代码提交后,切换测试分支
git pull // 更新测试分支,拉取最新提交代码
git merge '本地需求开发分支' // 然后将本地开发分支合并到测试分支
// 有冲突要解决冲突,然后继续完成合并
git add .
git merge --continue
// 然后进行构建,测试环境验证
// 这个过程会存在的情况是:
//切换测试分支,然后更新远端测试分支。A开发者第一次向远端测试分支合并了修改,我们将修改更新到本地;然后开发者A又修改了之前的代码,并进行了提交。此时我们在本地更新远端测试分支的时候会存在冲突:开发A修改了代码,要确认使用传入还是当前。我们就需要问A开发如何选择来解决冲突。
// 为了避免这个麻烦的操作,我们本地代码开发完后,合并测试分支时先删除本地测试分支,然后再切换测试分支(此时测试分支是最新的,就不会遇到前面讲的问题),然后就是常规操作,分支合并
git branch -D feature-test
git checkout feature-test
git merge ...
...