网站首页 > 技术文章 正文
Git基础知识(七)--分支开发工作流
分支开发基础知识
长期分支
在master分支上保留完全稳定的代码
- 已发布的代码
- 即将发布的代码
创建develop分支,在该分支上进行开发与测试。
当develop分支稳定后可以合入master分支,等待下一次发布。
渐进稳定分支
大型项目中,通过类似的方式使分支具有不同级别的稳定性。当它们具有一定程度的稳定性后,再把它们合入更高级别的稳定性分支中。使用多个长期分支的方法并非必要,但是当你在一 个非常庞大或者复杂的项目中工作时,就会提供很大的帮助。
特性分支
一个短期的分支,用于实现单一特性或者相关工作。
- 主线分支master
- 开发分支dumbidea
- 问题修复分支iss91
- 问题修复测试分支iss91v2
特性分支
远程分支
上述的分支都是在本地的操作
$ git ls-remote <remote_name> $ git remote show <remote_name>
查看远端分支信息
远程分支更多信息
一般当多人协作的时候,总是会出现先后修改的问题。当别人对改分支进行修改之后,远端的分支就会前进,而你本地不会实时的获取到这个改变。
$ git fetch origin #更新本地数据库,移动origin/master指针指向新的位置
同步远程仓库,更新本地仓库信息
推送
$ git push <remote_name> <branch> #推送branch分支到远端的branch分支 $ git push <remote_name> <branch><remote_branch> #推送branch分支到远端的remote_branch分支
推送分支
推送远端并改名
跟踪分支
从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。跟踪分支是与远程分支有直接关系的本地分支。如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
检出时确定跟踪分支关联关系:
$ git checkout -b [branch] [remotename]/[branch]
检出后修改跟踪分支关联关系:
$ git branch -u [remotename]/[branch]b
修改跟踪分支
查看跟踪分支关系
$ git branch -vv $ git fetch --all; git branch -vv #建议在查看前更新一下本地仓库信息
查看跟踪分支
查看跟踪分支2
拉取
$ git pull = $ git fetch $ git merge
删除远程分支
$ git push [remotename] --delete [branch]
删除分支
常见的分支开发工作流
Gitflow工作流是经典模型,处于核心位置,体现了工作流的经验和精髓。随着项目过程复杂化,你会感受到这个工作流中的深思熟虑和威力!
Forking工作流是分布式协作的(GitHub风格)可以先看看GitHub的Help:Fork A Repo和Using pull requests 。照着操作,给一个GitHub项目贡献你的提交,有操作经验再看指南容易意会。指南中给了自己实现Fork的方法:Fork就是服务端的克隆。在指南的操练中使用的是代码托管服务(如GitHub),可以点一下按钮就让开发者完成仓库的fork操作。
集中式工作流
基本上和SVN一样的开发方式。
虽然机制一样,但是Git有相比SVN的几个优势。 首先,每个开发可以有属于自己的整个工程的本地拷贝。隔离的环境让各个开发者的工作和项目的其他部分修改独立开来 —— 即自由地提交到自己的本地仓库,先完全忽略上游的开发,直到方便的时候再把修改反馈上去。
其次,Git提供了强壮的分支和合并模型。不像SVN,Git的分支设计成可以做为一种用来在仓库之间集成代码和分享修改的『失败安全』的机制。
git-workflow-svn-push-local
git-workflow-svn
功能分支工作流
功能分支工作流以集中式工作流为基础,不同的是为各个新功能分配一个专门的分支来开发。这样可以在把新功能集成到正式项目前,用Pull Requests/Merage Requests的方式讨论变更。
功能分支工作流背后的核心思路是所有的功能开发应该在一个专门的分支,而不是在master分支上。 这个隔离可以方便多个开发者在各自的功能上开发而不会弄乱主干代码。 另外,也保证了master分支的代码一定不会是有问题的,极大有利于集成环境。
功能开发隔离也让pull requests成为可能, pull requests工作流能为每个分支发起一个讨论,在分支合入正式项目之前,给其它开发者有表示赞同的机会。 另外,如果你在功能开发中有问题卡住了,可以开一个pull requests来向同学们征求建议。 这些做法的重点就是,pull requests让团队成员之间互相评论工作变成非常方便!
Code Review是Pull Requests的一个主要的收益,但Pull Requests实际上用作讨论代码的常用手段。 你可以把Pull Requests作为专门给某个分支的讨论。这意味着可以在更早的开发过程中就可以进行Code Review。 比如,一个开发者开发功能需要帮助时,要做的就是发起一个Pull Request,相关的人就会自动收到通知,在相关的提交旁边能看到需要帮助解决的问题。
一旦Pull Request被接受了,发布功能要做的就和集中式工作流就很像了。 首先,确定本地的master分支和上游的master分支是同步的。然后合并功能分支到本地master分支并push已经更新的本地master分支到中央仓库。
git-workflow-feature-branch-1
$ git checkout marys-feature $ git pull # 确认是最新的 $ git pull --rebase origin master # rebase新功能到master分支的顶部 $ git checkout master $ git merge marys-feature # 合并marys-feature分支的修改,因为这个分支之前对齐(rebase)了master,一定是快进合并 $ git push
Gitflow
Gitflow工作流通过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些非常必要的结构。
Gitflow工作流定义了一个围绕项目发布的严格分支模型。虽然比功能分支工作流复杂几分,但提供了用于一个健壮的用于管理大型项目的框架。
Gitflow工作流没有用超出功能分支工作流的概念和命令,而是为不同的分支分配一个很明确的角色,并定义分支之间如何和什么时候进行交互。 除了使用功能分支,在做准备、维护和记录发布也使用各自的分支。 当然你可以用上功能分支工作流所有的好处:Pull Requests、隔离实验性开发和更高效的协作。
Main
主干包含两条分支
- master:存储了正式发布的历史
- develop:功能的集成分支
每个新功能位于一个自己的分支,这样可以push。 但功能分支不是从master分支上拉出新分支,而是使用develop分支作为父分支。当新功能完成时,develop分支。 新功能提交应该从不直接与master分支交互。
main-branches
Supporting branches
- Feature:功能分支
- Release:发布分支
- Hotfix:维护分支
Feature
其中Feature分支可能从develop分支中某一节点创建,最终会合入develop分支,一般为特性分支。并且大部分时候都是在用户本地存在而非远端。
Feature
# 创建一个特性分支 $ git checkout -b myfeature develop # 完成特性并合入开发分支 $ git checkout develop $ git merge --no-ff myfeature $ git branch -d myfeature $ git push origin develop
合并
The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward.
用--no-ff会创建一个新的空提交,但是可以很清晰的看出特性开发的内容与流程,它的收益远大于消耗。
Release
# 从开发分支新建一个release分支 $ git checkout -b release-1.2 develop # 使用shell脚本写入版本信息 $ ./bump-version.sh 1.2 # 提交修改 $ git commit -a -m "Bumped version number to 1.2" # 检出master分支 $ git checkout master # 以非快进分方式将release分支合入master分支 $ git merge --no-ff release-1.2 # 基于当前提交创建标签 $ git tag -a 1.2
将版本信息更新至开发分支
# 检出开发分支 $ git checkout develop # 将release分支合入开发分支 $ git merge --no-ff release-1.2 # 删除release分支 $ git branch -d release-1.2
Hotfix
维护分支或说是热修复(hotfix)分支用于生成快速给产品发布版本(production releases)打补丁,这是唯一可以直接从master分支fork出来的分支。 修复完成,修改应该马上合并回master分支和develop分支(当前的发布分支),master分支应该用新的版本号打好Tag。
hotfix-branches
和特性分支差不多,不在赘述
最终的结果:
gitflow
gitflow
Forking 工作流
Forking工作流和前面讨论的几种工作流有根本的不同。 这种工作流不是使用单个服务端仓库作为『中央』代码基线,而让各个开发者都有一个服务端仓库。 这意味着各个代码贡献者有2个Git仓库而不是1个:一个本地私有的,另一个服务端公开的。
和其它的Git工作流一样,Forking工作流要先有一个公开的正式仓库存储在服务器上。 但一个新的开发者想要在项目上工作时,不是直接从正式仓库克隆,而是fork正式项目在服务器上创建一个拷贝。
git-workflows-forking
要提交本地修改时,push提交到自己公开仓库中 —— 而不是正式仓库中。 然后,给正式仓库发起一个pull request,让项目维护者知道有更新已经准备好可以集成了。 对于贡献的代码,pull request也可以很方便地作为一个讨论的地方。为了把功能集成到正式代码库,维护者pull贡献者的变更到自己的本地仓库中,检查变更以确保不会让项目出错, 合并变更到自己本地的master分支, 然后push master分支到服务器的正式仓库中。 到此,贡献的提交成为了项目的一部分,其它的开发者应该执行pull操作与正式仓库同步自己本地仓库。
使用之前讲过的git remote add管理多个远端,可以方便的更新主仓库的他人的提交。
Pull Request
Pull Request可以和功能分支工作流、Gitflow工作流或Forking工作流一起使用。 但一个Pull Request要求要么分支不同要么仓库不同,所以不能用于集中式工作流。 在不同的工作流中使用Pull Request会有一些不同,但基本的过程是这样的:
- 开发者在本地仓库中新建一个专门的分支开发功能。
- 开发者push分支修改到公开的仓库中。
- 开发者通过代码管理平台发起一个Pull Request。
- 团队的其它成员review code,讨论并修改。
- 项目维护者合并功能到官方仓库中并关闭Pull Request。
pull-request-feature-branch
参考:https://www.atlassian.com/git/tutorials/comparing-workflows
其他根据Gitflow简化的分支开发工作流
GitHub Flow
GitLab Flow
GitLab Flow
GitLab Flow
欢迎关注我的公众号:zx94_11
猜你喜欢
- 2024-10-27 git 入门教程之紧急修复(git checkout . 恢复)
- 2024-10-27 项目版本管理的最佳实践:飞流Flow篇
- 2024-10-27 DevOps(4)之分支模型(ps4如何构建画布)
- 2024-10-27 Git 在团队中的最佳实践——如何正确使用Git Flow
- 2024-10-27 鹅厂程序员干货分享 | 四种工作流,教你如何使用 GitHub
- 2024-10-27 Linux下git和github搭建使用教程(linux搭建git仓库)
- 2024-10-27 git这个小技巧非常实用,值得每个程序员学习
- 2024-10-27 Git实战002:Git快速入门使用详解(git简单教程)
- 2024-10-27 git 多人在同一分支上迭代开发时,如何保证分支提交历史保持线性
- 2024-10-27 Git分支规范(git新建分支)
- 11-26Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 11-26一文搞懂MySQL行锁、表锁、间隙锁详解
- 11-26电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 11-26代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 11-26CMD命令提示符能干嘛?这些功能你都知道吗?
- 11-26性能测试之慢sql分析
- 11-26论渗透信息收集的重要性
- 11-26如何查看电脑连接过的所有WiFi密码
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)