如何使用Git提高研发团队工作效率?
为什么使用Git
随着互联网时代的来临与发展,尤其分布式开发的大力引入,对于开发工程师来说,代码管理变成了头等难题。10多个人或者更多的成员的研发团队如何管理同一份代码,异地办公如何跟同事有效的维护同一份代码?下面直接介绍Git,就不对Git和其他的版本管理工具进行比较了。
Git属于分布式的版本控制系统,它具有以下特点:
- Git中每个克隆(clone)的版本库都是平等的。你可以从任何一个版本库的克隆来创建属于你自己的版本库,同时你的版本库也可以作为源提供给他人,只要你愿意。
- Git的每一次提取操作,实际上都是一次对代码仓库的完整备份。
- 提交完全在本地完成,无须别人给你授权,你的版本库你作主,并且提交总是会成功。
- 甚至基于旧版本的改动也可以成功提交,提交会基于旧的版本创建一个新的分支。
- Git的提交不会被打断,直到你的工作完全满意了,PUSH给他人或者他人PULL你的版本库,合并会发生在PULL和PUSH过程中,不能自动解决的冲突会提示您手工完成。
- 冲突解决:在需要的时候才进行合并和冲突解决。
- Git版本库统一放在服务器中
- 可以为 Git 版本库进行授权:谁能创建版本库,谁能向版本库PUSH,谁能够读取(克隆)版本库,即权限配置
- 团队的成员先将服务器的版本库克隆到本地;并经常的从服务器的版本库拉(PULL)最新的更新;
- 团队的成员将自己的改动推(PUSH)到服务器的版本库中,当其他人和版本库同步(PULL)时,会自动获取改变
- 你完全可以在脱离Git服务器所在网络的情况下,如移动办公/出差时,照常使用代码库
- 你只需要在能够接入Git服务器所在网络时,PULL和PUSH即可完成和服务器同步以及提交
选择适合团队的工作流
分布式工作流程:
同传统的集中式版本控制系统(CVCS)不同,Git 的分布式特性使得开发者间的协作变得更加灵活多样。在集中式系统中,每个开发者就像是连接在集线器上的节点,彼此的工作方式大体相像。而在 Git 中,每个开发者同时扮演着节点和集线器的角色——也就是说,每个开发者既可以将自己的代码贡献到其他的仓库中,同时也能维护自己的公开仓库,让其他人可以在其基础上工作并贡献代码。由此,Git 的分布式协作可以为你的项目和团队衍生出种种不同的工作流程,接下来的章节会介绍几种利用了 Git 的这种灵活性的常见应用方式。我们将讨论每种方式的优点以及可能的缺点;你可以选择使用其中的某一种,或者将它们的特性混合搭配使用。
Git 提供的有以下三种工作流程:
- 集中式工作流
- 集成管理者工作流
- 司令官与副官工作流
目前我们团队使用的是最简单的方式,集中式工作流程,随着研发团队的壮大可能会选择使用第二种,下面我们分别介绍下三种工作流
1.集中式工作流
集中式系统中通常使用的是单点协作模型——集中式工作流。一个中心集线器,或者说仓库,可以接受代码,所有人将自己的工作与之同步。若干个开发者则作为节点——也就是中心仓库的消费者——并且与其进行同步。
这意味着如果两个开发者从中心仓库克隆代码下来,同时作了一些修改,那么只有第一个开发者可以顺利地把数据推送回共享服务器。第二个开发者在推送修改之前,必须先将第一个人的工作合并进来,这样才不会覆盖第一个人的修改。这和 Subversion (或任何 CVCS)中的概念一样,而且这个模式也可以很好地运用到 Git 中。如果在公司或者团队中,你已经习惯了使用这种集中式工作流程,完全可以继续采用这种简单的模式。只需要搭建好一个中心仓库,并给开发团队中的每个人推送数据的权限,就可以开展工作了。Git 不会让用户覆盖彼此的修改。例如 John 和 Jessica 同时开始工作。 John完成了他的修改并推送到服务器。接着 Jessica 尝试提交她自己的修改,却遭到服务器拒绝。她被告知她的修改正通过非快进式(non-fast-forward)的方式推送,只有将数据抓取下来并且合并后方能推送。这种模式的工作流程的使用非常广泛,因为大多数人对其很熟悉也很习惯。当然这并不局限于小团队。利用 Git 的分支模型,通过同时在多个分支上工作的方式,即使是上百人的开发团队也可以很好地在单个项目上协作。
2.集成管理者工作流
Git 允许多个远程仓库存在,使得这样一种工作流成为可能:每个开发者拥有自己仓库的写权限和其他所有人仓库的读权限。这种情形下通常会有个代表``官方''项目的权威的仓库。要为这个项目做贡献,你需要从该项目克隆出一个自己的公开仓库,然后将自己的修改推送上去。接着你可以请求官方仓库的维护者拉取更新合并到主项目。维护者可以将你的仓库作为远程仓库添加进来,在本地测试你的变更,将其合并入他们的分支并推送回官方仓库。这一流程的工作方式如下所示:
- 项目维护者推送到主仓库。
- 贡献者克隆此仓库,做出修改。
- 贡献者将数据推送到自己的公开仓库。
- 贡献者给维护者发送邮件,请求拉取自己的更新。
- 维护者在自己本地的仓库中,将贡献者的仓库加为远程仓库并合并修改。
- 维护者将合并后的修改推送到主仓库。
这是 GitHub 和 GitLab 等集线器式(hub-based)工具最常用的工作流程。人们可以容易地将某个项目派生成为自己的公开仓库,向这个仓库推送自己的修改,并为每个人所见。这么做最主要的优点之一是你可以持续地工作,而主仓库的维护者可以随时拉取你的修改。贡献者不必等待维护者处理完提交的更新——每一方都可以按照自己节奏工作。
3.司令官与副官工作流
这其实是多仓库工作流程的变种。一般拥有数百位协作开发者的超大型项目才会用到这样的工作方式,例如著名的 Linux 内核项目。被称为副官(lieutenant)的各个集成管理者分别负责集成项目中的特定部分。所有这些副官头上还有一位称为司令官(dictator)的总集成管理者负责统筹。司令官维护的仓库作为参考仓库,为所有协作者提供他们需要拉取的项目代码。整个流程看起来是这样的
- 普通开发者在自己的特性分支上工作,并根据master分支进行变基。这里是司令官的master分支。
- 副官将普通开发者的特性分支合并到自己的master分支中。
- 司令官将所有副官的master分支并入自己的master分支中。
- 司令官将集成后的master分支推送到参考仓库中,以便所有其他开发者以此为基础进行变基。
这种工作流程并不常用,只有当项目极为庞杂,或者需要多级别管理时,才会体现出优势。利用这种方式,项目总负责人(即司令官)可以把大量分散的集成工作委托给不同的小组负责人分别处理,然后在不同时刻将大块的代码子集统筹起来,用于之后的整合。
介绍了上面三种工作流,想必你一定有想法使用哪一种了,选择一个适合自己团队的工作流,只要是严格按照这种规则执行的话,相信你的研发团队对于代码的管理一定不会再混乱了,这也会大大提升团队的工作效率。
管理 Git 分支
几乎所有的版本控制系统都以某种形式支持分支。使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。
有人把 Git 的分支模型称为它的``必杀技特性'',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。理解和精通这一特性,你便会意识到 Git 是如此的强大而又独特,并且从此真正改变你的开发方式。
Git 创建分支
Git 是怎么创建新分支的呢?很简单,它只是为你创建了一个可以移动的新的指针。比如,创建一个 testing 分支,你需要使用 git branch 命令:
$ git branch testing
这会在当前所在的提交对象上创建一个指针
那么,Git 又是怎么知道当前在哪一个分支上呢?也很简单,它有一个名为 HEAD 的特殊指针。请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD 概念完全不同。在 Git 中,它是一个指针,指向当前所在的本地分支。在本例中,你仍然在 master 分支上。因为 git branch 命令仅仅创建一个新分支,并不会自动切换到新分支中去。
你可以简单地使用 git log 命令查看各个分支当前所指的对象。提供这一功能的参数是 --decorate 。
$ git log --oneline --decoratef30ab (HEAD, master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project
正上,当前 master 和 testing 分支均指向校验和以 f30ab 开头的提交对象。
分支切换
要切换到一个已存在的分支,你需要使用 git checkout 命令。我们现在切换到新创建的 testing 分支去:
$ git checkout testing
这样HEAD就指向testing分支了。
那么,这样的实现方式会给我们带来什么好处呢?现在不妨再提交一次:
$ vim test.rb
$ git commit -a -m 'made a change'
如上图所示,你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。这就有意思了,现在我们切换回 master 分支看看:
$ git checkout master
这条命令做了两件事。一是使 HEAD 指回master分支,二是将工作目录恢复成master分支所指向的快照内容。也就是说,你现在做修改的话,项目将始于一个较旧的版本。本质上来讲,这就是忽略testing分支所做的修改,以便于向另一个方向进行开发。
现在我们稍微再做些修改并 commit :
$ vim test.rb
$ git commit -a -m 'made other changes'
现在,这个项目的提交历史已经产生了分叉。因为刚才你创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。上述两次改动针对的是不同分支:你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。而所有这些工作,你需要的命令只有 branch 、 checkout 和 commit 。
Git 合并分支
接下来咱们举个稍微复杂点的例子,三个分支的分别处理不同的事情,最后合并到一块
首先,我们假设你正在你的项目上工作,并且已经有一些提交, 如下图:
现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:
$ git checkout -b iss53
Switched to a new branch "iss53"
它是下面两条命令的简写:
$ git branch iss53
$ git checkout iss53
你继续在 #53 问题上工作,并且做了一些提交。在此过程中, iss53 分支在不断的向前推进,因为你已经检出到该分支(也就是说,你的 HEAD 指针指向了 iss53 分支)
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
当你在 iss53 这个分支上正在顺畅的工作,这时候有个特别紧急的问题需要你来修复,那么为了不影响 iss53 的正常工作,你需要做的是重新切换到 master 分支上来,在 master 分支的基础上再创建一个新的分支 hotfix ,然后在 hotfix 分支解决紧急的问题。
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
这个时候 hotfix 分支上的问题彻底解决了,你需要合并到 master 分支,并且部署上线, 那么你只需要在 master 分支使用 git merge 命令就可以了
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的时候,你应该注意到了"快进( fast-forward )"这个词。由于当前 master 分支所指向的提交是你当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。换句话说,当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进( fast-forward )”。现在,最新的修改已经在master分支所指向的提交快照中了。
关于这个紧急问题的解决方案发布之后,你准备回到被打断之前时的工作中。然而,你应该先删除 hotfix 分支,因为你已经不再需要它了, master 分支已经指向了同一个位置。你可以使用带 -d 选项的 git branch 命令来删除分支:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
现在你可以切换回你正在工作的分支继续你的工作,也就是针对 iss53 分支
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
这个时候 #53 问题解决后你就可以把代码合并到master了,操作跟刚才的 htofix 分支处理方式一样
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.index.html | 1 +
1 file changed, 1 insertion(+)
但是这和你之前合并hotfix分支的时候看起来有一点不一样。在这种情况下,你的开发历史从一个更早的地方开始分叉开来( diverged )。因为, master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4和C5)以及这两个分支的工作祖先(C2),做一个简单的三方合并。
和之间将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。
这个时候如何不需要 iss53 分支的话,你也可以删除 iss53 分支了
远程分支
以 github 为例,目前很多开源项目以及公司的研发项目代码一般都托管在 github ,那么就出现了远程仓库,远程分支等这些概念。
下面我们从 github 远程仓库 clone 下来一份代码
如果你在本地的master分支做了一些工作,然而在同一时间,其他人推送提交到 git@github.com:glj1102/git_test.git 并更新了它的master分支,那么你的提交历史将向不同的方向前进。也许,只要你不与 origin 服务器连接,你的origin/master指针就不会移动。
如果要同步你的工作,运行 git pull 命令。这个命令是抓取远程分支数据到本地分支,并且更新本地数据库,移动origin/master指针指向新的、更新后的位置。同时你也可以执行 git push 命令把你本地修改的数据提交到远程分支。
实时跟踪和监控团队代码操作记录
我们使用的是 Worktile + github 来管理团队的,平时团队沟通,任务分配都是通过Worktile来做的,那么 Worktile 与github如何关联的呢?
Worktile绑定github代码仓储
在Worktile的 后台管理 > 服务管理 中找到 github ,点击添加
下一步会让你选择Worktile的一个 聊天群组 ,之后github的提交记录就会发送到这个群组中:
添加服务之后需要进行一些配置,配置方式有两种,一种是 授权模式 ,选择仓储,选择事件, 另一种是 普通模式 ,这种模式Worktile会生成一个 Webhook 链接,拿到这个链接可以直接在github仓储中进行Webhook配置:
具体的配置Worktile后台github服务设置中有教程。
Worktile接收github发送的操作记录
根据不配置时选择的事件不同,github会发送不同的记录消息
总结
通过上面对Git的介绍,对于团队管理者来说,如何使用Git来有效的管理团队代码应该会有最基本的概念,那接下来就需要你真正的花时间来实践了。那么对于Git的命令集网上有很多例子的,下面我这里介绍两本Git的基本入门教程
Git 简易指南 http://www.bootcss.com/p/git-guide/
Git 图解 http://marklodato.github.io/visual-git-guide/index-zh-cn.html
Worktile官网:www.worktile.com
本文作者:龚林杰
文章首发于「Worktile官方博客」,转载请注明来源。
如何使用Git提高研发团队工作效率?的更多相关文章
- 提高IT团队工作效率的建议
过分强调个人主义,不科学分工,内部成员的冲突等,都将导致IT团队没有凝聚力,直接影响团队合作项目的完成.如何提高团队工作效率,相信很多IT经理人都想过这类问题.日前,国外科技网站CIO撰文就如何提高I ...
- 【年度开源、工具合集】牛津计划,DMTK,Graph Engine…提高你的工作效率!
本篇合集包括以下三个部分的内容: 1.微软亚洲研究院过去一年的所有开源合集,如分布式机器学习工具包DMTK等. 2.利用微软研究院的技术提高工作效率的工具合集,如让没有机器学习背景的开发人员也能开发出 ...
- 使用 Productivity Power Tools 2013来帮助你提高 VS2013的工作效率
Visual Studio Gallery中发布了Productivity Power Tools 2013 的更新.在此版本中,此版本解决了客户报告的大量错误和问题,并介绍了一项称为语法行压缩的新功 ...
- 这些linux技巧大大提高你的工作效率
前言 linux中的一些小技巧可以大大提高你的工作效率,本文就细数那些提高效率或者简单却有效的linux技巧. 命令编辑及光标移动 这里有很多快捷键可以帮我们修正自己的命令.接下来使用光标二字代替光标 ...
- 超好用的Redis管理及监控工具,使用后可大大提高你的工作效率!
Redis做为现在web应用开发的黄金搭担组合,大量的被应用,广泛用于存储session信息,权限信息,交易作业等热数据.做为一名有10年以上JAVA开发经验的程序员,工作中项目也是广泛使用了Redi ...
- 使用 Productivity Power Tools 高级扩展 来帮助你提高 VS2012 的工作效率
Productivity Power Tools 高级工具是帮助开发者提高工作效率的, 用于 Visual Studio 2012 专业版(及以上) 的一组免费扩展. 本文大多数内容译自MSDN:ht ...
- AECC2018同时中英文切换多开使用,加倍提高你的工作效率
最近相信不少人已经更新了AECC2018,升级之后第一件重要的事当然是中英文的切换了,要不然工作中很麻烦.对于一直习惯用中文的人来说,在用模板过程中会出现各种表达式报错极其不方便,而对于习惯英文操作朋 ...
- [GIt] 团队工作效率分析工具gitstats
copy : http://www.cnblogs.com/ToDoToTry/p/4311637.html 如果你是团队领导,关心团队的开发效率和工作激情:如果你是开源软件开发者,维护者某个repo ...
- 团队工作效率分析工具gitstats
如果你是团队领导,关心团队的开发效率和工作激情:如果你是开源软件开发者,维护者某个repo:又或者,你关心某个开源软件的开发进度,那么你可以试一试gitstats. gitstats 是一个git仓库 ...
随机推荐
- Go资源
go语言实现的设计模式 http://tmrts.com/go-patterns/ https://design-patterns.readthedocs.io/zh_CN/latest/index. ...
- 数据分析 大数据之路 五 pandas 报表
pandas: 在内存中或对象,会有一套基于对象属性的方法, 可以视为 pandas 是一个存储一维表,二维表,三维表的工具, 主要以二维表为主 一维的表, (系列(Series)) 二维的表, ...
- 我的 FPGA 学习历程(01)—— FPGA 基础知识和 Quartus 的安装
高级的嵌入式市场主要分为以下三类:ARM.DSP 和 FPGA. 其中 ARM 是行业内的佼佼者,目前几乎所有的安卓智能手机都使用 ARM 授权的 CPU架构:而 DSP(数字信号处理器) 早年就被大 ...
- 实现logstash6.4.3 同步mysql数据到Elasticsearch6.4.3
本文旨在实践把mysql已有的数据同步到elasticsearch中,使用的版本是6.4.3,对于其它6.x版本理应是一样的处理方式. 本文目录: 1.初始化Elasticsearch 6.4.3 1 ...
- vbs脚本实现qq定时发消息(初级)
vbs脚本实现QQ消息定时发送 目标 批处理又称为批处理脚本,强大的强大功能可以高效得实现很多功能,例如批量更改文件格式,批量进行文件读写,今天我们的目标是用vbs脚本编写可以发送qq消息的脚本,并利 ...
- 图解Raft之日志复制
日志复制可以说是Raft集群的核心之一,保证了Raft数据的一致性,下面通过几张图片介绍Raft集群中日志复制的逻辑与流程: 在一个Raft集群中只有Leader节点能够接受客户端的请求,由Leade ...
- 使用IDEA时跳转到.class的解决办法
项目背景:jdk1.8 软件环境:IDEA 问题: 1. 两个不同的项目,在A项目中写了一个实体类.B项目中引用.在B项目中CTRL+鼠标左键点击进入,正常情况下是进入了源码文件,也就是.JAVA文件 ...
- 使用Jacksum对文件夹和文件生成checksum
Jacksum 是一个java开源工具, 用来 给单个文件生成checksum, 也可以给整个文件中所有文件生成checksum,生产的checksum 可以是MD系列,也可sha. 你可以参考 官 ...
- 你不知道的JS之 this 和对象原型(一)this 是什么
原文:你不知道的js系列 JavaScript 的 this 机制并没有那么复杂 为什么会有 this? 在如何使用 this 之前,我们要搞清楚一个问题,为什么要使用 this. 下面的代码尝试去 ...
- MVC Web.Config 配置错误
配置一个MVC项目的 SessionState,查阅了大量的资料,发现都是直接在web.config中直接加入类似的语句就可以了 <sessionState timeout="60&q ...