基于git的代码版本管理规范及流程
代码库分类
根据代码库分布的位置及作用,分为以下几类:
- 主库:位于服务端,所有开发的代码最终都要合到主库。
- 个人代码库(服务端):从主库fork出来,位于服务端。每个人自已开发的代码,由本地的git库push到每个人自己的个人代码库(服务端),再由个人代码库(服务端)合入主加。
- 个人工作库:位于每个开发人员的开发机器,从个人代码库(服务端)clone到本地。每个开发人员开发的代码,先commit到个人工作库,再由个人工作库push到个人代码库(服务端)。
人员角色分类
这里说的角色,都是人员在主库上的角色。基于简化的原则,人员分为三类:
- Owner:拥有主库的所有权限。
- Committer:具有将开发人员的合并需求(MR)合入主库的权限。基于安全考虑,我们设置为只能通过MR的方式将代码合入主库,而不能直接push到主库。
- Developer:只能从自己的个人代码库(服务端)提交合并代码的请求(MR),是否能够合入,由Committer进行审核。
基本流程
在主库已经存在的情况下,日常操作流程如下:
- 开发人员从主库fork出自己的个人代码库。
- 开发人员将自己的个人代码库clone到本地,即个人工作库。
- 开发人员在开发了新代码后(包括新增和修改),先将代码commit到自己的个人工作库,再由个人工作库push到个人代码库。
- 开发人员提交从个人工作库到主库的MR,Committer审核后,决定是否将MR合入主库。
- 每个开发人员从主库pull最新代码到个人工作库。
分支管理
- 主库缺省的master分支,是用来向生产环境发布的,所有合入的代码,原则上都必须是稳定的。
- 主库除了master分支外,至少还要有一个活动分支,命名建议为:br_工程名_active,平时日常的开发都基于活动分支开发。即从个人工作库提交MR到主库时,指向的是主库的活动分支。活动分支测试稳定后,将主库的活动分支通过MR的形式,合并到主库的master分支,同时打上tag。
- 如果软件运行过程中发现必须立即修改的bug,则从主库的master分支中,拉出一个bugfix分支。为修复这个bug的所有开发,都基于bugfix分支。待bugfix分支开发完成,并测试稳定后,将bugfix分支以MR的方合入主库的master分支。然后删除bugfix分支,视情况决定是否打tag。
常见问题
使用git在本地创建一个项目的过程:
$ makdir G:\python ##创建一个项目文件夹 $ cd G:\python ##打开文件夹 $ git init ##初始化本地git仓库 $ git commit -m \'first commit\' ##提交更新并添加备注“first commit”以上为本地仓库创建提交流程
登录码云,创建一个项目python,添加README文件,复制链接
$ git remote add origin https://git.oschina.net/xxxxxx/python.git ##连接远程github项目 $ git push -u origin master ##将本地项目更新到github项目上去容易出现的问题及常用命令:
git status ##查看git状态 git pull origin master ##pull远程仓库 git remote ##查看远程仓库及其分支 git rm origin ##删除本地仓库问题1:执行git remote add xxxx报错fatal: remote origin already exists.
解决办法:git remote rm origin删除远程仓库的origin,然后再add添加远程仓库
问题2:执行git push origin master报错fatal: I don\'t handle protocol \'git@https\'
解决办法:那是因为你用了git@github...的add方式添加了远程仓库,请通过问题1删除远程仓库再重新添加
问题3:执行git push origin master报错error: failed to push some refs to...
解决办法:大部分是由于github中的README.md文件不在本地代码目录中导致的, 先通过git pull --rebase origin master进行合并,再通过git push -u origin master上传
问题4:执行git pull origin master报错fatal: refusing to merge unrelated histories
解决办法:这是一个常见问题,要把两个不同的项目合并,需要添加一个强制命令:git pull origin master --allow-unrelated-histories
问题5:如何添加一个.gitignore,或者如何添加一个目录(文件)到ignore中
解决办法:一、还未添加git的项目:在项目目录下新建一个.gitignore文件(Windows无法新建命名为.gitignore,可以命名为.gitignore.,但是我更推荐使用sublime等工具来创建命名即可),在.gitignore中添加你需要过滤的文件即可。添加完成后git init即可;二、已经进行了git操作的项目,需要通过命令把相应的过滤文件缓存进行清空,清空后将代码push,同步端直接pull即可:
git rm --cached -r [目录名]
git commit -m \'clean ignore files\'问题6:" refusing to update checked out branch: refs/heads/master, By default, updating the current branch in a non-bare repository is denied, because it will make the index and work tree inconsistent……"
解决办法:这个错误是我在搭建裸仓库时碰到的,主要原因是git初始默认receive.denyCurrentBrach是拒绝接收push的,我们要向中心仓库push就需要设置它允许接收,在中心仓库输入:
git config receive.denyCurrentBranch ignore关于这个bare仓库可以多谈几句,通过bare建立的.git仓库是没有工作区的,所以又称为裸仓库,通常用它作为中心仓库。
问题7:Git add或commit出现:“ fatal: Pathspec \'xxx\' is in submodule \'yyy\' 异常”解决办法:碰到这个问题是开发某小哥自己在yyy文件夹里搞了一个git仓库,然后另一个小伙直接放到项目中了,结果两个git仓库相互作用,导致项目的git仓库无法添加xxx到项目中,OK,总之这是两个仓库,通常我们到GitHub去clone别人的代码也会碰到这类问题,需要做的很简单,删掉yyy下面的git仓库,并把当前项目git的cache中的yyy清空掉:
git rm -rf --cached yyy git add . git commit -m \'add something\' git push origin master
一些经验分享:注意平时在多人操作同一个git仓库时候尽量用不同的分支,在合并代码的时候使用一个主分支即可,此外,如果你忘记了代码的更新状态,在push操作之前尽量先pull。
活动分支合入主分支时发生冲突
产生原因
平时基于活动分支开发,如果这个过程中为了修复bug而拉了一个bugfix分支,当bugfix分支开发完成并合入master分支后,如果bugfix分支和活动分支修改了相同的文件,则在活动分支合入master分支时就会产生冲突。
解决方法
- 从个人代码库(服务端)clone一个库到本地,即专门用于合并的个人工作库。(也可以用之前的个人工作库,但初学都容易混淆,建议单独clone一个。)
- 从主库的活动分支上pull最新的代码到本地。
- 从主库的master分支上pull最新的代码到本地。
- 此时会产生冲突,手工修复冲突,然后先commit到本地的个人工作库,再push到个人代码库(服务端)。
- 提交从个人工作库(服务端)到主库的MR(此时不会再有冲突),然后由Committer审核后将MR合入主库。