Git分布式版本管理详解

Git分布式版本管理使用详情

  • Git分布式版本管理使用详情
    • 1. Git的诞生
    • 2. Svn集中式 <-VS-> Git分布式
    • 3. Git分支介绍
    • 4. Git分支之工作流程
      • 1. 最早诞生的工作流程Git flow
        • 功能分支(feature branch):
        • 预发分支(release branch):
        • 补丁分支(hotfix branch):
      • 2. Github flow:
      • 3. Gitlab flow:
    • 5. Git分支之工作技巧
        • 干活之前:
        • Pull Request
        • Protected branch
        • issue
        • merge节点

1. Git的诞生

Linus创建了Linux,Linux的壮大是靠全世界热心的志愿者参与的。世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!
时间到了2002年,Linux系统已经发展了十年,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。
安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错),于是BitMover公司怒了,要收回Linux社区的免费使用权。
Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们。但,这是不可能的。实际情况是这样的:
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git诞生!一个月之内,Linux系统的源码已经由Git管理了!大家可以体会一下,牛是怎么定义的!
Git迅速成为最流行的分布式版本控制系统。尤其是2008年,GitHub网站上线。它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

2. Svn集中式 <-VS-> Git分布式

集中式版本控制系统:版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑。所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器比作一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。

Git分布式版本管理详解_第1张图片

分布式版本控制系统:没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样工作的时候,就不需要联网了,因为版本库就在电脑上。

既然每台电脑上都有一个完整的版本库,那多个人如何协作呢?

比方说你在自己电脑上改了文件A,你的同事在他的电脑上改了文件A。你们俩之间只需要把各自的修改推送给对方,就可以互相看到对方的修改了。

实际使用分布式版本控制系统的时候,很少在两台电脑之间推送版本库的修改。因为可能两台电脑之间不能互相访问,也可能其中一台电脑压根就没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,这个服务器的作用仅仅是用来方便“交换”大家的修改。没有它大家也一样干活,只是交换修改不方便而已。

Git分布式版本管理详解_第2张图片
集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。

分布式版本控制系统的每台电脑里都有完整的版本库,某台电脑坏掉了不要紧,从其他电脑里复制一份就可以。因此,代码安全性要高很多。

Git的优势是拥有极其强大的分支管理,把Svn等远远抛在了身后。

3. Git分支介绍

每次提交代码,Git都会生成支点,它们串成一条时间线,这条时间线就是一个分支。
Git分布式版本管理详解_第3张图片
每次提交,master分支都会向前移动一步。随着你不断提交,master分支的线也越来越长。目前只有一条时间线,在Git里,这个分支叫主分支。
创建新的分支:
例如dev时,Git新建一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上。
Git分布式版本管理详解_第4张图片
重点:HEAD指向的就是当前正在使用的分支!

创建好dev分支开始,对工作区的修改和提交就是针对dev分支了。比如新提交一次后,dev指针往前移动一步,而master指针不变。

Git分布式版本管理详解_第5张图片
假如在dev上的工作完成了,就可以把dev合并到master上。最简单的方法,就是直接把master指向dev的当前提交,就完成了合并。
Git分布式版本管理详解_第6张图片

合并分支完成后,如果dev分支不在使用,可以直接删除dev分支。删除dev分支就是把dev指针给删掉,就剩下了一条master分支。

Git分布式版本管理详解_第7张图片

4. Git分支之工作流程

Git 作为一个源码管理系统,不可避免涉及到多人协作。协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去。“工作流程”在英语里,叫做“workflow”或者“flow”。

三种广泛使用的工作流程:

  • Git flow
  • Github flow
  • Gitlab flow

三种工作流程,有一个共同点,都采用“功能驱动式开发”(Feature-driven development,简称FDD)。
它指的是,需求是开发的起点,先有需求再有功能分支(feature branch)或者补丁分支(hotfix branch)。完成开发后,该分支就合并到主分支,然后被删除。

1. 最早诞生的工作流程Git flow

项目存在二个长期分支:
- 主分支(master
- 开发分支(develop
master用于存放对外发布的版本,任何时候在这个分支拿到的,都是稳定的分布版;develop用于日常开发,存放最新的开发版。

项目存在三种短期分支:

  • 功能分支(feature branch)
  • 预发分支(release branch)
  • 补丁分支(hotfix branch)

这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有masterdevelop

功能分支(feature branch):

它是为了开发某种特定功能,从develop分支上面分出来的。开发完成后,要再并入develop分支。它的命名,可以采用feature-*的形式。
Git分布式版本管理详解_第8张图片

预发分支(release branch):

它是指发布正式版本之前(即合并到master分支之前),需要有一个预发布的版本进行测试。预发布分支是从develop分支上面分出来的,预发布结束以后,必须合并进develop和master分支。它的命名,可以采用release-*的形式。

补丁分支(hotfix branch):

软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。修补bug分支是从master分支上面分出来的。修补结束以后,再合并进masterdevelop分支。它的命名,可以采用fixbug-*的形式。

Git分布式版本管理详解_第9张图片
Git flow总结:
优点是清晰可控,缺点是相对复杂,需要同时维护两个长期分支。大多数工具都将master当作默认分支,可是开发是在develop分支进行的,这导致经常要切换分支,非常烦人。
更大问题在于,这个模式是基于“版本发布”的,目标是一段时间以后产出一个新版本。但是很多网站项目是“持续发布”,代码一有变动,就部署一次。这时master分支和develop分支的差别不大,没必要维护两个长期分支。

2. Github flow:

它是Git flow的简化版,专门配合“持续发布”。它是 Github.com 使用的工作流程。

它只有一个长期分支master,因此用起来非常简单。操作步骤:
1、根据需求,从master拉出新分支,不区分功能分支或补丁分支。
2、新分支开发完成,有需要讨论的时候,就向master发起一个Pull Request(简称PR)。
3、PR既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。
4、PR被接受时,合并进master,重新部署。把新拉出来的那个分支删除。
Git分布式版本管理详解_第10张图片

Githubdevelopflow总结:
优点就是简单,对于“持续发布”的产品是最合适的流程。
它的问题在于假设要成立。master分支的更新与产品的发布是一致的。保证master分支的最新代码就是当前线上的代码。
有些时候并非如此,代码合并进入master分支,并不代表它就能立刻发布。例如,苹果商店的APP提交审核以后,等一段时间才能上架。如果还有新的代码提交,master分支就会与刚发布的版本不一致。另一个例子是有些公司有发布窗口时间,只有指定时间才能发布新的版本,这也会导致线上版本落后于master分支。

3. Gitlab flow:

它是 Git flow 与 Github flow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是 Gitlab.com使用的工作流程。

它的最大原则叫做“上游优先”(upsteam first),即只存在一个主分支master,它是所有其他分支的“上游”。只有上游分支采纳的代码变化,才能应用到其他分支。

Gitlab flow 分成两种情况,适应不同的开发流程。
1、持续发布:
它建议在master分支以外,建立不同的环境分支。“开发环境”的分支是master,“预发环境”的分支是pre-production,“生产环境”的分支是production。
开发分支是预发分支的“上游”,预发分支是生产分支的“上游”。代码的变化,必须由“上游”向“下游”发展。例如,生产环境出现bug,新建一个功能分支修正bug,先把它合并到master,确认没有问题。再cherry-pick到pre-production,确认没有问题。才能进入production。
只有紧急情况,才允许跳过上游,直接合并到下游分支。
Git分布式版本管理详解_第11张图片
2、版本发布:
它对于“版本发布”的项目,建议的做法是每一个稳定版本,都要从master分支拉出一个分支,比如2-3-stable、2-4-stable等等。
以后,只有修补bug,才允许将代码合并到这些分支,并且此时要更新小版本号。
Git分布式版本管理详解_第12张图片

Gitlab flow总结:
优点是很多公司都使用这种工作流程。

5. Git分支之工作技巧

干活之前:

首先,每次开发新功能,都应该新建一个单独的分支。

Pull Request

功能分支合并进master分支,必须通过Pull Request(Gitlab.com里面叫做 Merge Request)。
Pull Request本质是一种对话机制,可以在提交的时候@相关人员或团队,引起他们的注意。及时的查看提交的内容。

Protected branch

master分支应该受到保护,不是每个人都可以修改这个分支,以及拥有审批 Pull Request 的权力。
Github.com 和 Gitlab.com 都提供“保护分支”(Protected branch)这个功能。

issue

GitHub.com 的issue 功能就如同TODO list。想要在下一步完成的工作,如feature添加、bug修改等,都写成一个个的issue。放在上面,可以作为提醒,可以统一管理。

开发完成后,在提交说明里面,可以选择性的与某个issue关联。比如在message中添加#n,就可以与第n个issue进行关联。

commit message title, #1

只要commit message里面有下面这些动词 + 编号,就会关闭对应的issue。

- close  #n
- closes  #n
- closed  #n
- fix  #n
- fixes  #n
- fixed  #n
- resolve  #n
- resolves  #n
- resolved  #n
`commit message title, fix #n`

merge节点

Git有两种合并:一种是“直进式合并”(fast forward),不生成单独的合并节点;另一种是“非直进式合并”(none fast-forword),会生成单独节点。
前者不利于保持commit信息的清晰,也不利于以后的回滚。建议总是采用后者(即使用–no-ff参数)。只要发生合并,就要有一个单独的合并节点。

你可能感兴趣的:(Git)