GitLab flow工作流程 一、分支约定 临时分支:在开发完成会被删除
功能分支: feature - 用于新功能的开发,以“feature-版本号-需求工单号” 命名,,若涉及前后端开发,可以加上后缀-FE或-BE加以区分,FE:前端,BE:后端。如: feature-5.6.0-QYRD-3172-BE,对应工单号为:https://oa.richinfo.cn:5443/browse/QYRD-3172
修复分支:fix - 用户bug的修复,以“fix-版本号-问题工单号”命名,如:fix-5.0.0-QYRD-2216,对应工单号为:https://oa.richinfo.cn:5443/browse/QYRD-2216
固定分支:
开发分支: master - 用于发布到开发环境,上游分支为 feature 和 fix,该分支为受保护分支。
测试分支: test - 用于发布到测试环境(标准版的测试环境),上游分支为master,该分支为受保护分支。——等同于SIT
生产分支: prod - 用于发布到生产环境(标准版的打包环境),上游分支为 test,该分支为受保护分支。——等同于UAT
二、开发与自测试:
从master拉取feature分支进行编码开发(多个开发人员拉取多个feature同时进行并行开发 , 互不影响);
feature分支开发完成后, 在feature分支变基合并(git rebase master)master的代码 (合并前先更新本地master),进行本地测试;
测试没问题后,在GitLab上发起 New Merge Request,Assignee给* *代码评审员(前端:彭宝文、陈英华,后端:黄健秋、唐伟、于亚林,如果需要某一位开发人员关注,你可以在描述字段中@该名开发人员)**;
代码评审员进行Code Review后,批准merge(若拒绝,需提供有关必要修复的评论),合并有冲突,通知开发人员解决冲突,开发人员解决完冲突后推送到远程feature分支,如果New Merge Request被关闭,再次打开(如果合并请求未关闭,它将自动更新,直到最后一次提交为止),注释合并的请求或以其他方式报告已实施的修复;
代码评审员合并代码,开发人员部署到开发环境。
示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 shell> git checkout -b feature-5.6.0-QYRD-3172-BE origin/master # 在当前分支开发完成后: shell> git add -A # 将暂存区里的改动给提交到本地的版本库: shell> git commit -m ' feat(setting): 增加发邮件默认编辑格式的设置。 closes issue #https://oa.richinfo.cn:5443/browse/QYRD-3172 ' # 将master代码合并到当前分支: shell> git checkout master #先切换到master shell> git pull #更新本地仓master的代码到最新 shell> git checkout feature-5.6.0-QYRD-3172-BE #切换分支到需要rebase的分支 shell> git rebase master #执行变基。 # 若合并有冲突: shell> git status #查看本地工作区、暂存区中文件的修改状态 shell> git add -A #手动解决冲突后,添加修改的文件到暂存区 shell> git rebase --continue #继续变基操作 shell> git rebase -i HEAD~3 #合并之前的提交记录,~3表示最后提交的三次commit,git rebase -i <commitHash> #合并某个commitHash之后的所有提交 shell> git push origin feature-5.6.0-QYRD-3172-BE -f #推送本地分支代码到远程仓库 # 在 https://192.168.8.7/enterprise/xx_STD/-/merge_requests 页面发起 New Merge Request,具体操作参考: Merge_Request_Workflow.md
三、基线测试及Bug修复:
代码评审员将master分支代码合并到test;
提交基线测试,配置管理员(CM)赖玉兰 通过jenkins将test代码自动化构建和部署到测试环境,提测;
提测过程发现BUG,从master拉取fix分支进行修复,修复完成后,按Merge Request流程合并到master分支;(参考:Merge_Request_Workflow.md)
master部署到开发环境,研发自测试没问题后,开发人员从master分支增量合并(cherry-pick)到test,再走第2步提交基线测试。
四、生产发布:
test测试没问题后,代码管理员将test分支代码覆盖至为prod分支,打上tag,封版发布。
tag版本号建议采用语义化版本规范(2.0.0),参考:https://semver.org/lang/zh-CN/
五、历史版本的Bug修复
从历史版本的tag创建一个fix修复分支进行开发;
fix分支开发完成后,打包部署到历史版本的测试环境;
测试没问题后,打上新的tag,将tag推送到远程。
示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 shell> git checkout -b fix-5.0.0-QYRD-2216 V5.0.0 # 在当前分支修复完bug后: shell> git add -A # 将暂存区里的改动给提交到本地的版本库: shell> git commit -m ' fix(admin): 修复写邮件,勾选“转发禁止修改”,发送提示:系统错误。 close issue #https://oa.richinfo.cn:5443/browse/QYRD-2216 ' # 基于fix-5.0.0-QYRD-2216打包部署到历史版本的测试环境,测试没问题后: shell> git push origin fix-5.0.0-QYRD-2216 # 将本地code推送到远程分支仓库。 # ##########代码评审员操作############# shell> git checkout fix-5.0.0-QYRD-2216 shell> git tag -a V5.0.1 -m "version 5.0.1 released" #打新的tag shell> git push origin V5.0.1 #将当前tag分支推送到远程仓库 # ##########代码评审员操作############# # 将master代码合并到当前分支: shell> git checkout master #先切换到master shell> git pull #更新本地仓master的代码到最新 shell> git checkout fix-5.0.0-QYRD-2216 #切换分支到需要rebase的分支 shell> git rebase master #执行变基。 # 若合并有冲突: shell> git status #查看本地工作区、暂存区中文件的修改状态 shell> git add -A #手动解决冲突后,添加修改的文件到暂存区 shell> git rebase --continue #继续变基操作 shell> git push -f #推送本地分支代码到远程仓库 # 在 https://192.168.8.7/enterprise/xx_STD/-/merge_requests 页面发起 New Merge Request,具体操作参考: Merge_Request_Workflow.md # 合并完成后,部署master的代码到开发环境 # ##########代码评审员操作############# # 开发环境测试没问题后,代码评审员将修复后的代码从master增量(cherry-pick)合并到prod: shell> git log --author ' pengbaowen' --graph --oneline --decorate=short --date-order -10 #查看自己最近10次的提交记录,复制要增量合并的记录哈希值,此处为:231766b2 shell> git checkout prod #切换至prod分支 shell> git pull #更新本地仓prod的代码到最新 shell> git cherry-pick 231766b2 #将指定的提交commitHash(多个用空格隔开),应用于当前分支,这会在当前分支产生一个新的提交,当然它们的哈希值会不一样。 shell> git push origin prod #推送到远程仓库,部署到最新版本的测试环境测试 # ##########代码评审员操作#############
六、Merge Request的好处:
利于多人协同开发;
强化了代码记录的可读性, 去除杂乱无用的提交记录;
便于 Code review 的执行;
重要分支设置为受保护,杜绝了有些问题代码被提交了,但项目经理不知道的情况;
每个任务都有一个对应的分支,互相隔离,所有的代码改动有据可查;
开发人员不用在分支间切换和合并,更专注于开发。
七、Code Review的一般原则:
代码评审是任何开发过程中不可或缺的一部分 - 将其打印出来并放在墙上以便记住。可参考 《你的代码评审需要来一次清单革命 》!
代码评审是在小段的逻辑完整的代码片段上执行的,例如功能,任务,错误修复,改进等;
只有通过审核的代码才能发送到测试部门;
该项目的所有开发人员都会进行代码评审,无论他们的级别如何;
项目的所有开发人员都应该通过代码评审,无论他们的级别如何(初级开发人员也应该审查经验丰富的中高级专家的代码)。
八、注意事项:
始终要遵循”上游优先”(upsteam first)原则,即:master ->prod;
控制提交粒度,不要一次性提交包括多个问题的代码,一个问题的相关代码作为一次提交;
养成时不时pull远程master分支(git rebase master)的好习惯,把同事最新的提交合并到自己分支,提前解决冲突。这样下去就可以避免你在一个无用的代码上进行长期的开发,回头来看这些代码不是新的代码,甚至是会面临很多冲突需要解决,而这个时候你可能还需要对冲突的部分代码进行测试回归,这就很麻烦了。
rebase原则:只对尚未推送的本地修改执行变基操作清理历史,从不对已推送远程的提交执行变基操作。为防止产生不可预料的事情,已经推送到服务器的分支直接经过merge合并,不使用rebase;使用 git rebase 的黄金法则就是:分支的开发者尽量是一个人,重写提交历史不会影响别人。
九、一些有用的操作示例: 查看提交日志: 1 2 3 4 5 6 7 8 9 10 11 12 13 $ git log $ git log --author 'pengbaowen' $ git log --name-status $ git log --name-only $ git log --stat $ git whatchanged $ git whatchanged --stat $ git show $ git show <commit-hash-id> $ git log -- <filename> $ git log -p <filename> $ git log -p -2 $ git log --author 'pengbaowen' --graph --oneline --decorate=short --date-order
查看修改(比较修改之间的差异): 1 2 3 4 5 6 7 $ git diff $ git diff --cached [<path>...] $ git diff HEAD [<path>...] $ git diff commit-id [<path>...] $ git diff --cached [<commit-id>] [<path>...] $ git diff [<commit-id>] [<commit-id>]
删除本地所有fix-相关的分支: 1 $ git branch | grep 'fix-' | xargs git branch -D
查看本地分支和追踪情况: 1 $ git remote show origin
本地同步删除远程已被删除的分支: 1 $ git remote prune origin
git revert回滚代码示例: 1 2 3 4 5 6 shell> git revert -n 817e1f # 若冲突,则修改冲突的文件,然后: shell> git add <冲突的文件> shell> git revert --continue shell> git commit -m 'refactor:回退误提交的Q4代码' shell> git push origin master
其他git revert相关示例: 实例一: git revert 多个提交,比如revert c15a7ae 到 3a2055 之间的提交(包含它俩)
1 2 shell> git revert -n c15a7ae^..3a2055 shell> git commit -m "revert c15a7ae to 3a2055"
实例二: 撤销 HEAD 指针之前的第3个提交,并且生成一个新的提交。这里补充解释一下,HEAD 是指当前的提交指针,除了 HEAD,再往前找3个,所以下面的英文里面说是第4个。
实例三: 撤销从 master 之前第5个提交到之前第3个提交的变化(这么看来,前面是开区间,第6个没有被包含;后面是闭区间,包含了第3个),但是这个操作不会提交一个commit,只是修改 work tree 和 index,如果没有冲突,则直接在 index 里面了。
1 shell> git revert -n master~5..master~2
不同项目仓库之间的cherry-pick代码(增量合并代码): 下面以xx_STD库prod分支的代码cherry-pick到xx_BOC库(当前库)为例:
基于xx_BOC库的master分支创建新分支:
1 2 3 shell> git checkout master shell> git pull shell> git checkout -b fix-5.8.0-XXX
将xx_STD库加为远程仓库:
1 2 shell> git remote add xx_STD git@192.168.8.7:enterprise/xx_STD.git shell> git remote -v
或者直接修改xx_boc/.git/config文件,增加以下内容:
1 2 3 [remote "xx_STD"] url = git@192.168.8.7:enterprise/xx_STD.git fetch = +refs/heads/*:refs/remotes/xx_STD/*
把远程 xx_STD库的分支信息同步到本地:
1 2 shell> git fetch xx_STD shell> git log xx_STD/prod
把远程xx_STD库的代码提交(commitHash)cherry-pick到xx_BOC库的当前分支(fix-5.8.0-XXX):
1 shell> git cherry-pick 166c5561d1915f76cc343514f9c42ca761788791
将xx_BOC库当前分支(xx_STD库prod分支的BUG修复代码已增量合并到xx_BOC库分支)推送到远程:
1 shell> git push origin fix-5.8.0-XXX
基于fix-5.8.0-XXX创建合并到xx_BOC库master分支的合并请求。
十、Git缩写命令配置: 编辑git配置文件:
1 shell> git config --global -e
加入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [alias] st = status co = checkout br = branch mg = merge ci = commit md = commit --amend dt = difftool mt = mergetool unstage = reset HEAD last = log -1 HEAD cf = config latest = for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) [%(committername)]' line = log --oneline lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit ls = log --pretty=format:\"%C(yellow)%h %C(blue)%ad %C(red)%d %C(reset)%s %C(green)[%cn]\" --decorate --date=short hist = log --pretty=format:\"%C(yellow)%h %C(red)%d %C(reset)%s %C(green)[%an] %C(blue)%ad\" --topo-order --graph --date=short type = cat-file -t dump = cat-file -p
或者直接命令行添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 shell> git config --global alias.st status shell> git config --global alias.co checkout shell> git config --global alias.br branch shell> git config --global alias.mg merge shell> git config --global alias.ci commit shell> git config --global alias.md 'commit --amend' shell> git config --global alias.dt difftool shell> git config --global alias.mt mergetool shell> git config --global alias.unstage 'reset HEAD' shell> git config --global alias.last 'log -1 HEAD' shell> git config --global alias.cf config shell> git config --global alias.latest "for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) [%(committername)]'" shell> git config --global alias.line 'log --oneline' shell> git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" shell> git config --global alias.ls "log --pretty=format:\"%C(yellow)%h %C(blue)%ad %C(red)%d %C(reset)%s %C(green)[%cn]\" --decorate --date=short" shell> git config --global alias.hist "log --pretty=format:\"%C(yellow)%h %C(red)%d %C(reset)%s %C(green)[%an] %C(blue)%ad\" --topo-order --graph --date=short" shell> git config --global alias.type "cat-file -t" shell> git config --global alias.dump "cat-file -p"
十一、参考链接: PRO GIT BOOK 2nd Edition:
https://git-scm.com/book/zh/v2
.gitignore:
https://github.com/github/gitignore
Git Commit Message:
Angular规范:https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits
Conventional Commits 规范:https://www.conventionalcommits.org/zh-hans/v1.0.0-beta.4/
How to Write a Git Commit Message: https://chris.beams.io/posts/git-commit/
Commit message 编写指南:https://www.oschina.net/news/69705/git-commit-message-and-changelog-guide
workflows and branching models and strategies:
A Successful Git branching model: http://nvie.com/posts/a-successful-git-branching-model/
Introduction to GitLab Flow:https://docs.gitlab.com/ee/topics/gitlab_flow.html
GitLab的权限管理及Merge Request:https://blog.csdn.net/justyman/article/details/90142327
创建和接受合并请求 Merge Requests: https://blog.csdn.net/weixin_43606948/article/details/85489257
__END__