分布式是如何实现的:git
好处:github
开发者开始先克隆中央仓库。在本身的项目拷贝中编辑文件和提交修改;但修改是存在本地的,和中央仓库是彻底隔离的。开发者能够把和上游的同步延后到一个方便时间点。框架
要发布修改到正式项目中,开发者要把本地master分支的修改『推』到中央仓库中,推送(push)操做会把全部还不在中央仓库的本地提交都推上去。分布式
中央仓库表明了正式项目,因此提交历史是稳定不变的。若是开发者本地的提交历史和中央仓库有分歧,Git会拒绝push提交。svn
在开发者提交本身功能修改到中央库前,须要先拉取(fetch)在中央库的新增提交,变基(rebase)本身提交到中央库提交历史之上。工具
这样作的意思是在说,『我要把本身的修改加到别人已经完成的修改上。』最终的结果是一个完美的线性历史。学习
若是本地修改和上游提交有冲突,Git会暂停rebase过程,给你手动解决冲突的机会。还有一点,若是解决冲突时遇到麻烦,Git能够很简单停止整个rebase操做,重来一次(或者让别人来帮助解决)。测试
rebase操做过程是把本地提交一次一个地迁移到更新了的中央仓库master分支之上。
这意味着可能要解决在迁移某个提交时出现的合并冲突,而不是解决包含了全部提交的大型合并时所出现的冲突。
这样的方式让你尽量保持每一个提交的聚焦和项目历史的整洁。反过来,简化了哪里引入Bug的分析,若是有必要,回滚修改也能够作到对项目影响最小。
让咱们一块儿逐步分解来看看一个常见的小团队如何用这个工做流来协做的。有两个开发者小明和小红,看他们是如何开发本身的功能并提交到中央仓库上的。
第一步,有人在服务器上建立好中央仓库。
下一步,各个开发者建立整个项目的本地拷贝。
基于你后续会持续和克隆的仓库作交互的假设,克隆仓库时Git会自动添加远程别名origin指回中央仓库。
在小明的本地仓库中,他使用标准的Git过程开发功能:编辑、暂存(Stage)和提交。
若是你不熟悉暂存区(Staging Area),这里说明一下:暂存区的用来准备一个提交,但能够不用把工做目录中全部的修改内容都包含进来。
这样你能够建立一个高度聚焦的提交,即便你本地修改不少内容。
请记住,由于这些命令生成的是本地提交,小明能够按本身需求反复操做屡次,而不用担忧中央仓库上有了什么操做。
对须要多个更简单更原子分块的大功能,这个作法是颇有用的。
与此同时,小红在本身的本地仓库中用相同的编辑、暂存和提交过程开发功能。和小明同样,她也不关心中央仓库有没有新提交;
固然更不关心小明在他的本地仓库中的操做,由于全部本地仓库都是私有的。
一旦小明完成了他的功能开发,会发布他的本地提交到中央仓库中,这样其它团队成员能够看到他的修改。
因为中央仓库自从小明克隆以来尚未被更新过,因此推送(push)操做不会有冲突,成功完成。
一块儿来看看在小明发布修改后,小红push修改会怎么样?
但她的本地历史已经和中央仓库有分岐了,Git拒绝操做并给出下面很长的出错消息:
这避免了小红覆写正式的提交。她要先获取小明的更新到她的本地仓库合并上她的本地修改后,再重试。
小红获取上游的修改到本身的仓库中。
选择要变基(衍合 rebase)的位置,这里选择的是origin/master,即变基到中央仓库最新的master上。
若是小红和小明的功能是不相关的,不大可能在rebase过程当中有冲突。
若是有,Git在合并有冲突的提交处暂停rebase过程,输出下面的信息并带上相关的指令:
本例中,小明上游先提交修改了"sdfghjkl!"-->"sdfghjkl1!",小红后提交了修改"sdfghjkl!"-->"sdfghjkl2!"
小红须要打开冲突的文件:
其中
<<<<< HEAD
上游提交修改
======
本次提交修改
>>>>>>>> *******
须要选择使用什么内容,好比说使用"sdfghjkl2!" ,则删除其余上游提交修改以及标识行
暂存修改,完成提交。
再次右键衍合(变基 rebase)
选择继续衍合,完成衍合(变基 rebase)过程。
变基完成后的结果以下图
若是你忘了变基(rebase)操做,推送(pull)仍然能够完成,切换到“文件状态”格外进行一次合并提交,而后再推送。但每次推送(pull)操做要同步中央仓库中别人修改时,提交历史会以一个多余的『合并提交』结尾。
最好是使用rebase而不是生成一个合并提交。
小红完成和中央仓库的同步后,就能成功发布她的修改了。
说完了单个分支,下面将对功能分支工做流进行深刻讨论
Gitflow工做流经过为功能开发、发布准备和维护分配独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些很是必要的结构。
Gitflow工做流定义了一个围绕项目发布的严格分支模型。虽然比功能分支工做流复杂几分,但提供了用于一个强壮的用于管理大型项目的框架。
Gitflow工做流没有用超出功能分支工做流的概念和命令,而是为不一样的分支分配一个很明确的角色,并定义分支之间如何和何时进行交互。
除了使用功能分支,在作准备、维护和记录发布也使用各自的分支。
固然你能够用上功能分支工做流全部的好处:Pull Requests、隔离实验性开发和更高效的协做。
Gitflow工做流仍然用中央仓库做为全部开发者的交互中心。和其它的工做流同样,开发者在本地工做并push分支到要中央仓库中。
相对使用仅有的一个master分支,Gitflow工做流使用2个分支来记录项目的历史。master分支存储了正式发布的历史,而develop分支做为功能的集成分支。
这样也方便master分支上的全部提交分配一个版本号。
剩下要说明的问题围绕着这2个分支的区别展开。
每一个新功能位于一个本身的分支,这样能够push到中央仓库以备份和协做。
但功能分支不是从master分支上拉出新分支,而是使用develop分支做为父分支。当新功能完成时,合并回develop分支。
新功能提交应该从不直接与master分支交互。
注意,从各类含义和目的上来看,功能分支加上develop分支就是功能分支工做流的用法。但Gitflow工做流没有在这里止步。
一旦develop分支上有了作一次发布(或者说快到了既定的发布日)的足够功能,就从develop分支上fork一个发布分支。
新建的分支用于开始发布循环,因此从这个时间点开始以后新的功能不能再加到这个分支上——
这个分支只应该作Bug修复、文档生成和其它面向发布任务。
一旦对外发布的工做都完成了,发布分支合并到master分支并分配一个版本号打好Tag。
另外,这些重新建发布分支以来的作的修改要合并回develop分支。
使用一个用于发布准备的专门分支,使得一个团队能够在完善当前的发布版本的同时,另外一个团队能够继续开发下个版本的功能。
这也打造定义良好的开发阶段(好比,能够很轻松地说,『这周咱们要作准备发布版本4.0』,而且在仓库的目录结构中能够实际看到)。
维护分支或说是热修复(hotfix)分支用于生成快速给产品发布版本(production releases)打补丁,这是惟一能够直接从master分支fork出来的分支。
修复完成,修改应该立刻合并回master分支和develop分支(当前的发布分支),master分支应该用新的版本号打好Tag。
为Bug修复使用专门分支,让团队能够处理掉问题而不用打断其它工做或是等待下一个发布循环。
你能够把维护分支想成是一个直接在master分支上处理的临时发布。
下面的示例演示本工做流如何用于管理单个发布循环。假设你已经建立了一个中央仓库。
第一步为master分支配套一个develop分支。简单来作能够本地建立一个空的develop分支,push到服务器上
之后这个分支将会包含了项目的所有历史,而master分支将只包含了部分历史。其它开发者这时应该克隆中央仓库,建好develop分支的跟踪分支
如今每一个开发都有了这些历史分支的本地拷贝。
这个示例中,小红和小明开始各自的功能开发。他们须要为各自的功能建立相应的分支。新分支不是基于master分支,而是应该基于develop分支:
后面的功能都在这里,将再也不重复贴图。
他们用老套路添加提交到各自功能分支上:编辑、暂存、提交
添加了提交后,小红以为她的功能OK了。她能够直接合并到她本地的develop分支后push到中央仓库:
获取,更新develop分支状态(切换到develop分支,拉取),点击git工做流,完成功能,推送。
在合并功能前确保develop分支是最新的。注意,功能决不该该直接合并到master分支。
冲突解决方法和集中式工做流同样。
这个时候小明正在实现他的功能,小红开始准备她的第一个项目正式发布。
像功能开发同样,她用一个新的分支来作发布准备。
这个分支是清理发布、执行全部测试、更新文档和其它为下个发布作准备操做的地方,像是一个专门用于改善发布的功能分支。
只要小红建立这个分支并push到中央仓库,这个发布就是功能冻结的。任何不在develop分支中的新功能都推到下个发布循环中。
一旦准备好了对外发布,小红合并修改到master分支和develop分支上,删除发布分支。合并回develop分支很重要,由于在发布分支中已经提交的更新须要在后面的新功能中也要是可用的。
发布分支是做为功能开发(develop分支)和对外发布(master分支)间的缓冲。只要有合并到master分支,就应该打好Tag以方便跟踪。
对外发布后,小红回去和小明一块儿作下个发布的新功能开发,直到有最终用户开了一个Ticket抱怨当前版本的一个Bug。
为了处理Bug,小红(或小明)从master分支上拉出了一个维护分支,提交修改以解决问题,而后直接合并回master分支。
就像发布分支,维护分支中新加这些重要修改须要包含到develop分支中,因此小红要执行一个合并操做。而后就能够安全地删除这个分支了。
到了这里,希望你对集中式工做流、功能分支工做流和Gitflow工做流已经感受很温馨了。
你应该也牢固的掌握了本地仓库的潜能,push/pull模式和Git的分支和合并模型。
记住,这里演示的工做流只是可能用法的例子,而不是在实际工做中使用Git不可违逆的条例。
因此不要畏惧按本身须要对工做流的用法作取舍。不变的目标就是让Git为你所用。
获取是从中央仓库检查分支是否有更新。若是有更新,则获得更新的详细信息,如提交信息,变动差别等等。
拉取是将中央仓库与本地仓库进行同步,将差别同步到本地。
丢弃是指将修改的部分丢弃,即恢复到修改前的状态。
移除是指删除这个文件,若是以前没有提交过这个文件,移除后将没法找回该文件。
忽略是指再也不对该文件进行差别检查和提交。忽略会在.ignore文件中增长一项,同步到中央仓库,这样,全部环境都将忽略该文件。若是该文件已经在提交历史中,该文件不会被删除。
建立高度聚焦的提交,方便查看检索,提交信息格式:功能名称--新增/修复--描述