当前位置: 首页 > Linux

Git工作流程详解

时间:2023-04-07 01:33:25 Linux

作为一名工程师,Git是日常开发中必不可少的工具。下面详细介绍几种常用的基于Git的工作流模型,以方便团队协作的规范化和效率提升。集中式工作流程用过SVN的人应该都知道,SVN采用的是集中式管理流程。如果你刚从SVN切换到Git,你可以尝试使用集中式工作流。这样,你几乎可以在不改变之前工作方式的情况下,完成一个平滑的过渡。而且在使用过程中也可以看出Git相对于SVN的优势:首先,每个成员都可以在本地拥有一个完整的项目代码仓库,而不仅仅是工作区的副本,任何人都可以在本地执行add和commit,而不用考虑是否有变化远程仓库,需要的时候提交。其次,Git的工作区、暂存区、引用更新等设计,可以让开发者更自由地切换当前工作,不会造成代码丢失。工作细节工作流集中化的方式是在远程端新建一个仓库(远程端可以是服务器端也可以是本地任意目录),默认是master分支作为唯一的中央仓库。大家克隆这个仓库作为本地仓库,在本地仓库开发。本地提交与远程仓库无关,需要的时候推送到主仓库的master分支即可。这样远端就是唯一确定的中央仓库,大家一定要参考这个仓库。因此,在提交之前,你必须先fetch最新的提交,并在这些提交之上进行自己的修改(通常我们使用rebase来完成)。如果您的本地更改与远程存储库中的更改发生冲突,Git将暂停变基并让您解决冲突。我们可以很方便的使用gitstatus、gitadd等命令来完成冲突的合并。另外,如果我们无法解决冲突,我们也可以使用gitrebase--abort轻松退出rebase过程。这样一来,每天的工作方式就变成了,从中央仓库拉取最新的代码,然后开始一天的工作。开发完成后拉取中央仓库的更新,合并代码,然后提交到中央仓库,结束一天的工作。这样做的好处是不需要改变原来(使用SVN)的工作方式。当然,缺点也很明显。你不知道中央仓库的代码是否稳定,或者说你的代码和中央仓库的代码合并后,你不能确定它是否稳定。带来的问题是开发进度和回滚不太方便控制。例子我们有两个程序员A和B,他们同时在开发一个项目,使用的是Git的集中式工作流。1、创建远程中央仓库这里我们有两种方式:借助已经搭建好的平台GitHub/GitLab等,直接点击createrepo即可。在远端创建一个裸仓库(这里只是为了区分本地仓库,实际上是使用其他人可以连接到的任何机器,包括其他本地目录)创建一个裸仓库。创建裸仓库和我们平时创建本地仓库的区别可以参考我的另一篇文章Git本地仓库和裸仓库。这里以第二种方式为例:#--bare参数必须有gitinit--bare/the/repo/path.git2。大家把中央仓库克隆到本地作为本地仓库gitclone/the/repo/path。Git注意仓库地址一定要正确,有权限才能clone成功。3.程序员A在自己的本地仓库开发并发布功能。一般情况下,我们通过gitstatus查看当前状态,通过gitadd、gitcommit等命令完成本地仓库的提交。当然,这次提交只影响本地仓库,对中央仓库没有影响,所以我们不需要关心其他人的提交,也不需要担心我们当前的提交是否影响了其他人。当A认为自己开发的功能已经完成时,会执行gitpushoriginmaster等操作,将自己本地仓库中所有中央仓库不存在的提交推送到远程中央仓库。4.程序员B在自己的本地仓库开发功能。B克隆中央仓库后,做与A相同的操作。他在本地仓库开发项目,在本地仓库提交。他不需要知道中央仓库发生了什么变化。5、程序员B发布自己开发的功能。程序员B在确认自己开发的功能已经完成后,想通过gitpushoriginmaster等操作将自己的代码发布到中央仓库,但是中央仓库提示他的修改已经和中央仓库fork了,而他需要先进行gitpull等操作,将A在中央仓库的提交和B本地的提交合并,才可以让他合并到中央仓库。因此,他执行gitpull--rebaseoriginmaster将中央存储库中的更改合并到他的本地存储库中。使用--rebase参数的意思是,执行fetch后,B的所有commit都会被移到master的最前面。当然这里如果不使用--rebase参数也是可以成功的,但是会生成merge提交。在某些情况下,使用--ff参数也可以避免生成合并提交。此处使用--rebase只是一个建议。如果A和B修改的文件不相关,一般情况下会直接完成merge。如果发生冲突,Git会暂停rebase进程并列出当前冲突的文件。您可以简单地使用gitstatus和gitaddMerge等命令,在合并后使用gitrebase--continue继续rebase过程。或者使用gitrebase--abort中止变基过程。B合并完成后,可以执行gitpushoriginmaster将自己开发的功能发布到中央仓库。至此基本的集中式工作流方式已经介绍完毕,但是这里很容易看出问题所在。除了上面提到的,还有效率低下的问题。如果很多人继续提交,那将是非常有影响力的。提交新特征(多人连续提交)。更简单的提高效率的方法是切换到特性分支工作流。特征分支工作流基于特征的分支工作流可以隔离各个特征,避免影响中央仓库的主代码。工作细则,顾名思义,就是根据每个特性开一个新的分支。每个分支都应包含一个描述性名称。无论是一个人开发还是多人协作,该特性的所有开发工作都在这个分支上进行。执行。该功能开发完成后会合并到主分支,然后删除分支,上线代码。在这种情况下,最大的优势是可以并行进行所有功能开发。它不需要像集中式工作流方法那样。每个人的改动都可能导致其他人的代码被合并,所有的功能都混在一起,从测试和回滚上会变得非常繁琐。还有一个好处就是可以把feature分支推送到中央仓库,也方便独立测试。这里需要注意的是,将feature分支合并到主分支的时机应该是feature开发完成,测试通过的时候,以免污染主代码。分支隔离之后,我们发现我们目前只处理了开发模式,并没有涵盖一个完整的产品生命周期,开发、发布、维护等流程,所以我们有一个Gitflow工作流。Gitflow工作流基于Gitflow的工作流方法。这种工作流方式主要管理新功能的开发、发布和维护模式。根据不同的工作类型定义分支,分为特性分支、修复分支和发布分支,开发分支和主分支。masterbranch:中央仓库建立后默认的master分支(当然其他分支也可以,但必须保护该分支)。主分支随时保持代码稳定,版本标签清晰。后续的代码回滚等操作都会从主分支进行。开发分支:中央仓库建立后,从master分支切下来,此时与master分支一致。在后续的演进中,开发分支随时保持代码是最新的,但不一定是真正上线运行的代码。gitcheckout-bdevelopfeaturebranch:应该是从develop分支切出来的。开发完成后,会合并到开发分支。如果满足发布标准,发布分支将从开发分支中切出。切出的分支仅针对本版本中的代码修复,不会增加新功能,且该分支已锁定。修复分支用于及时修复上线主分支的代码。修复完成后会合并到主分支,再合并到开发分支。固定分支只能从master分支中分叉出来。release分支,一般命名为release-xxx,这个分支只能从开发分支切下来,最后合并到主分支,标有版本号,应该也合并到开发分支,如果有其他修复在中间。fork工作流程fork分支流程不同于上述所有工作流程。它的上游有一个独特的仓库,大家fork这个仓库,在自己的远端和自己的本地维护一个仓库,开发完成后推入自己的远程仓库,结合GitHub/GitLab提交Pull,等请求进入审核阶段,通过后合并到唯一的上游仓库。这种方式比较适合GitHub上的大型开源项目,但是对于小团队的内部项目可能就不适合了。而且fork工作流会占用更多的资源(毕竟每个人都维护一个远程仓库)。而且大家也看不到别人的动态,只有提交了PullRequest,才知道大家发生了什么。综上所述,我个人比较推荐Gitflow的开发流程。这样一来,一切都是可控的,每个分支都有自己独立的功能。目的很明确。同时在做代码回滚之类的操作时也可以直接去掉。另外,在这种工作流方式下,团队中的每个人都可以很容易地知道其他人在做什么,做了什么改变,可能更适合团队协作。当然,并不是所有的工作流程都能完全应用。你可以吸收一些规范,融入到你的日常工作中,规范和规范代码仓库的协作流程,这也是一切自动化的基础。你可以通过公众号MoeLove联系我