理解Git的工作流程

2014-02-19  来源:本站原创  分类:管理  人气:0 

如果你不理解Git的设计动机,那你就会处处碰壁。知道足够多的命令和参数后,你就会强行让Git按你想的来工作,而不是按Git自己的方式来。这就像把螺丝刀当锤子用;也能把活干完,但肯定干的差极了,花费很长时间,还会弄坏螺丝刀。

想想常见的Git工作流程是怎么失效的吧。

从Master创建一个分支,写代码,然后把这个分支合并回Master。

多数时候这样做的效果会如你所愿,因为从你创建分支到合并回去之间,Master一般都会有些变动。然后,有一天当你想把一个功能(feature)分支合并进Master的时候,而Master并没有像以往那样有变动,问题来了:这时Git不会进行合并commit,而是将Master指向功能分支上的最新commit。(看图

不幸的是,你的功能分支有用来备份代码的commit(作者称之为checkpoint commit),这些经常进行的commit对应的代码可能处于不稳定状态!而这些commit现在没法和Master上那些稳定的commit区分开来了。当你想回滚的时候,很容易发生灾难性后果。

于是你就记住了:“当合并功能分支的时候,加上 -no-ff 选项强制进行一次全新的commit。”嗯,这么做好像解决问题了,那么继续。

然后一天你在线上环境中发现了一个严重bug,这时你需要追溯下这个bug是什么时候引入的。你运行了bisect命令,但却总是追溯到一些不稳定的commit。因此你不得不放弃,改用人肉检查。

最后你将bug范围缩小到一个文件。你运行blame命令查看这个文件在过去48小时里的变动。然后blame告诉你这个文件已经好几周没有被修改过了——你知道根本不可能没有变动。哦,原来是因为blame计算变动是从第一次commit算起,而不是merge的时候。你在几周前的一次commit中改动了这个文件,但这个变动今天才被merge回来。

用no-ff来救急,bisect又临时失效,blame的运作机制又那么模糊,所有这些现象都说明一件事儿,那就是你正在把螺丝刀当锤子用。

理解Git的工作流程

反思版本控制

版本控制的存在是因为两个原因。

首先,版本控制是用来辅助写代码的。因为你要和同事同步代码,并经常备份自己的代码。当然了,把文件压缩后发邮件也行,不过工程大了大概就不好办了。

其次,就是辅助配置管理工作。其中就包括并行开发的管理,比如一边给线上版本修复bug,一边开发下一个版本。配置管理也可以帮助弄清楚变动发生的具体时间,在追溯bug中是一个很好的工具。

一般说来,这两个原因是冲突的。

在开发一个功能的时候,你应该经常做备份性的commit。然而,这些commit经常会让软件没法编译。

理想情况是,你的版本更新历史中的每一次变化都是明确且稳定的,不会有备份性commit带来的噪声,也不会有超过一万行代码变动的超大commit。一个清晰的版本历史让回滚和选择性merge都变得相当容易,而且也方便以后的检查和分析。然而,要维护这样一个干净的历史版本库,也许意味着总是要等到代码完善之后才能提交变动。

那么,经常性的commit和干净的历史,你选择哪一个?

如果你是在刚起步的创业公司中,干净的历史没有太大帮助。你可以放心地把所有东西都往Master中提交,感觉不错的时候随时发布。

如果团队规模变大或是用户规模扩大了,你就需要些工具和技巧来做约束,包括自动化测试,代码检查,以及干净的版本历史。

功能分支貌似是一个不错的折中选择,能够基本的并行开发问题。当你写代码时候,可以不用怎么在意集成的问题,但它总有烦到你的时候。

当你的项目规模足够大的时候,简单的branch/commit/merge工作流程就出问题了。缝缝补补已经不行了。这时你需要一个干净的版本历史库。

Git之所以是革命性的,就是因为它能同时给你这两方面的好处。你可以在原型开发过程中经常备份变动,而搞定后只需要交付一个干净的版本历史。

工作流程

考虑两种分支:公共的和私有的。

公共分支是项目的权威性历史库。在公共分支中,每一个commit都应该确保简洁、原子性,并且有完善的提交信息。此分支应该尽可能线性,且不能更改。公共分支包括Master和发行版的分支。

私有分支是供你自己使用的,就像解决问题时的草稿纸。

安全起见,把私有分支只保存在本地。如果你确实需要push到服务器的话(比如要同步你在家和办公室的电脑),最好告诉同事这是私有的,不要基于这个分支展开工作。

绝不要直接用merge命令把私有分支合并到公共分支中。要先用reset、rebase、squash merges、commit amending等工具把你的分支清理一下。

把你自己看做一个作者,每一次的commit视为书中的一章。作者不会出版最初的草稿,就像Michael Crichton说的,“伟大的书都不是写出来——而是改出来的”。

如果你没接触过Git,那么修改历史对你来说好像是种禁忌。你习惯于认为提交过的所有东西都应该像刻在石头上一样不能抹去。但如果按这种逻辑,我们在文本处理软件器中也不应该使用“撤销”功能了。

实用主义者们直到变化变为噪音的时候才关注变化。对于配置管理来说,我们关注宏观的变化。日常commit(checkpoint commits)只是备份于云端的用于“撤销”的缓冲。

如果你保持公共历史版本库的简洁,那么所谓的fast-forward merge就不仅安全而且可取了,它能保证版本变更历史的线性和易于追溯。

关于 -no-ff 仅剩的争论就只剩“文档证明”了。人们可能会先merge再commit,以此代表最新的线上部署版本。不过,这是反模式的。用tag吧。

规则和例子

根据改变的多少、持续工作时间的长短,以及分支分叉了多远,我使用三种基本的方法。

1)短期工作

绝大多数时间,我做清理时只用squash merge命令。

假设我创建了一个功能分支,并且在接下来一个小时里进行了一系列的checkpoint commit。


1

2

3

4

git checkout -b private_feature_branch

touch file1.txt

git add file1.txt

git commit -am "WIP"

完成开发后,我不是直接执行git merge命令,而是这样:


1

2

3

git checkout master

git merge --squash private_feature_branch

git commit -v

然后我会花一分钟时间写个详细的commit日志。

2)较大的工作

有时候一个功能可以延续好几天,伴有大量的小的commit。

我认为这些改变应该被分解为一些更小粒度的变更,所以squash作为工具来说就有点儿太糙了。(根据经验我一般会问,“这样能让阅读代码更容易吗?”)

如果我的checkpoint commits之后有合理的更新,我可以使用rebase的交互模式。

交互模式很强大。你可以用它来编辑、分解、重新排序、合并以前的commit。

在我的功能分支上:


1

git rebase --interactive master

然后会打开一个编辑器,里边是commit列表。每一行上依次是,要执行的操作、commit的SHA1值、当前commit的注释。并且提供了包含所有可用命令列表的图例。

默认情况下,每个commit的操作都是“pick”,即不会修改commit。


1

2

3

pick ccd6e62 Work on back button

pick 1c83feb Bug fixes

pick f9d0c33 Start work on toolbar

我把第二行修改为“squash”,这样第二个commit就会合并到第一个上去。


1

2

3

pick ccd6e62 Work on back button

squash 1c83feb Bug fixes

pick f9d0c33 Start work on toolbar

保存并退出,会弹出一个新的编辑器窗口,让我为本次合并commit做注释。就这样。

舍弃分支

也许我的功能分支已经存在了很久很久,我不得不将好几个分支合并进这个功能分支中,以便当我写代码时这个分支是足够新的的。版本历史让人费解。最简单的办法是创建一个新的分支。


1

2

3

4

git checkout master

git checkout -b cleaned_up_branch

git merge --squash private_feature_branch

git reset

现在,我就有了一个包含我所有修改且不含之前分支历史的工作目录。这样我就可以手动添加和commit我的变更了。

总结

如果你在与Git的默认设置背道而驰,先问问为什么。

将公共分支历史看做不可变的、原子性的、容易追溯的。将私有分支历史看做一次性的、可编辑的。

推荐的工作流程是:


1

2

3

4

基于公共分支创建一个私有分支。

经常向这个私有分支commit代码。

一旦你的代码完善了,就清理掉下私有分支的历史。

将干净的私有分支merge到公共分支中。​

本文由张重骐(@candyhorse)投稿于伯乐在线,

相关文章
  • 理解Git的工作流程 2014-02-19

    如果你不理解Git的设计动机,那你就会处处碰壁.知道足够多的命令和参数后,你就会强行让Git按你想的来工作,而不是按Git自己的方式来.这就像把螺丝刀当锤子用:也能把活干完,但肯定干的差极了,花费很长时间,还会弄坏螺丝刀. 想想常见的Git工作流程是怎么失效的吧. 从Master创建一个分支,写代码,然后把这个分支合并回Master. 多数时候这样做的效果会如你所愿,因为从你创建分支到合并回去之间,Master一般都会有些变动.然后,有一天当你想把一个功能(feature)分支合并进Master

  • 理解Git的工作流程[转] 2012-07-27

    转自http://blog.jobbole.com/24379/ 如果你不理解Git的设计动机,那你就会处处碰壁.知道足够多的命令和参数后,你就会强行让Git按你想的来工作,而不是按Git自己的方式来.这就像把螺丝刀当锤子用:也能把活干完,但肯定干的差极了,花费很长时间,还会弄坏螺丝刀. 想想常见的Git工作流程是怎么失效的吧. 从Master创建一个分支,写代码,然后把这个分支合并回Master. 多数时候这样做的效果会如你所愿,因为从你创建分支到合并回去之间,Master一般都会有些变动.然

  • Git 分布式工作流程 2014-04-17

    本文介绍使用 Git 参与项目开发的各种流程和模式,比如 Github 上大名鼎鼎的 fork+pull 模式. 本文是<Pro Git>阅读笔记整理,疏漏之处,还请阅读原作. 1. 概述 1.1 集中式工作流程 一个存放代码仓库的中心服务器,接受所有开发者提交的代码,而后提交者,必须先下载合并服务器上的数据,解决冲突之后才能推送数据到共享服务器上. SVN和GIT都可以使用该工作流,优点是简单高效,只需给每个人推送数据的权限,就可以开展工作了. 1.2 集成管理员工作流程 这是 GitHub

  • Martin Fowler讲述重构的工作流程 2014-04-25

    <重构:改善既有代码的设计>一书的作者Martin Fowler最近在其个人网站上发表了一篇文章,探讨了如何通过各种工作流程来将代码重构融入到我们日常的编程工作当中. 在文章中他还介绍了如何使用各种不同的工作流程,并且建议"为了最有效地进行代码重构,我们需要结合使用所有的重构工作流程,这样才能使不同的流程无缝地融入到开发工作当中". Fowler将重构定义为"--一项用于对既有代码的主体结构进行调整的专门技术,可以在不影响其外部行为的情况下修改其内部结构"

  • 从策划到设计的工作流程 2014-12-13

    欢迎大家来到 XDC ! 这次我们探讨的主题是: MOVE it! PM&UE动起来 --"从策划到设计的工作流程" 标题听起来有点挫,其实我要表达的意思是让PM&UE之间更多互动,让大家在一个完善流程中工作地更 明晰.高效.欢乐! 先看目录: part1 一个故事引出PM&UE合作的?寰?/li> Part2 当前流程的问题与解决原则 Part3 工作流程节点提纲 PART1 一个故事引出PM&UE合作的?寰?/strong> 开始讨论流程

  • ccflow工作流程引擎投递规则的新增两个成员 2012-06-04

    关键字:工作流程管理系统, 工作流程引擎,投递规则 ,ccflow 就是下一步工作人员的接受人范围处理规则. 如何设置下一步的接受人范围,是我们研究的难题, 到目前位置,ccflow 为您提供了如下几种模式. 说明: 1, 下列设置类型,都设置当前节点作用于下一步节点. 2, 每一种类型,都有路径自动记忆功能,所说自动记忆功能是当节点第一次向下一个节点投递时,它把要投递的人记录下来. 如果你执行了分配系统就把分配的人员,做为接受人员计算. 可以设置的投递的类型: 按岗位: 设置方法: 在下一个节

  • ping的工作流程 2013-08-21

    虽然网上有很多人写过关于ping的工作流程,但我还是写下自己的理解. 1.ping的作用 ping命令最常用的作用是用来监测网络之间是否能通.现在对于我们来说,想去判断自己的宽带是否能正常使用,一般都是采用"ping www.baidu.com"(国外估计是"ping www.google.com",为什么国内不同样采用这种方式,你们都懂得...) 2.ping的工作流程 一般而言分为两种情况来进行说明: a.同一段网络之间进行通信.现有PCA IP地址为:192.

  • Glusterfs简介以及其工作流程的简单分析 2013-11-16

    1. Glusterfs简介 GlusterFS是Scale-Out存储解决方案Gluster的核心,它是一个开源的分布式文件系统,具有强大的横向扩展能力,通过扩展能够支持数PB存储容量和处理数千客户端.GlusterFS借助TCP/IP或InfiniBand RDMA网络将物理分布的存储资源聚集在一起,使用单一全局命名空间来管理数据.GlusterFS基于可堆叠的用户空间设计,可为各种不同的数据负载提供优异的性能. 2. Glusterfs特点 2.1 扩展性和高性能 GlusterFS利用双

  • Open vSwitch(OvS)源代码分析之工作流程(收发数据包) 2014-10-31

    前面已经把分析Open vSwitch源代码的基础写得非常清楚了,虽然访问的人比较少,也因此让我看到了一个现象:第一篇,<Open vSwitch(OvS)源代码分析之简介>(http://www.sdnlab.com/2788)其实就是介绍了下有关于云计算现状和Open vSwitch的各个组成模块,还有笼统的介绍了下其工作流程,个人感觉对于学习Open vSwitch源代码来说没有多大含金量.云计算现状是根据公司发展得到的个人体会,对学习Open vSwitch源代码其实没什么帮助:Ope

  • 驰骋工作流程引擎 ccflow 2009-06-05

    ccflow 网站 : http://ccflow.org/ 驰骋工作流程引擎,工作流程管理系统:简称ccflow. 是来解决政府机关.企事业单位管理经营活动中的业务作业过程中规范化.合理化的软件管理系统.它以多样的终端(计算机.手机.短信.PDA),把单位的内 外部的各个部门.人员有机的联系起来.它有效的解决了各个环节中的时间.人力.财物等资源的损耗. 工作流程引擎是一门横向的科学,应用非常广泛.只要有管理活动的地方,就有管理流程,有管理流程,就有ccflow生存的条件. 工作流程引擎,它与任

  • 揭秘Apple Store内部员工的工作流程 2014-05-29

    图为 Apple Store 店员的 iPod touch 上确定客户位置的平面图 |via Brian X. Chen/The New York Times 上周五,也就是「黑色星期五」那天,<纽约时报>的编辑布莱恩(Brian X. Chen)进了帕洛阿尔托的一家苹果零售店,店员迭戈•阿吉雷(Diego Aguirre)向他介绍了 Apple Store 内部员工的一些工作流程. 在苹果零售店中,员工最重要的工具就是挂在胸前的 iPod touch,那就是战士的枪,画家的笔.iPod to

  • 制作网站设计工作流程的建议 2014-10-22

    许多公司和个人需要网页设计师的帮助为自己的建设网站.当然,他们也希望它看起来尽可能专业.他们依靠的网页设计师,使他们的在线业务的成功,并确保网页设计师他们可以给客户想要的 . 双方都知道的设计工作流程,它也是重要的是,以避免某些误解.这也将帮助客户和设计师同意在项目进度.记住,客户应该知道设计过程中,使他们不会对任何疑虑.向客户解释一切,使他们了解的过程.这将大大有助于在与他们有一个良好的工作关系.在这篇文章中,我们会给你制作自 己的网页设计工作流程的指导 . 1咨询 第一件事就是将您的客户谈论

  • 搞笑漫画:Siri 的"真实"工作流程 2015-01-16

    专门画搞笑科技漫画的团队 The Joy of tech 又出新作,这次说的是 Siri 背后的"工作流程",各种科幻电影中的超智能计算机都出现在了这幅作品中,突出的中心思想就是人类最终会被 Siri 所统治.果迷网将该漫画翻译成了中文版本.欢迎传播-. P.S. 点击图片可以查看中英文对照版

  • 理解git常用命令原理 2013-12-30

    git不同于类似SVN这种版本管理系统,虽然熟悉常用的操作就可以满足大部分需求,但为了在遇到麻烦时不至于靠蛮力去尝试,了解git的原理还是很有必要. 文件 通过git管理的文件版本信息全部存放在根目录.git下,稍微看下: $ ls .git COMMIT_EDITMSG HEAD branches description index logs packed-refs FETCH_HEAD ORIG_HEAD config hooks info objects refs git除了提供给我们平时

  • 谈 Git 的开发流程 2014-04-15

    很高兴受邀参加『FED Party 10』GIT的develop与master 论坛成为与谈人.其中「协同开发时,master 与 dev branch 如何规划?」这个问题是我主要讲述的部份,分享了团队用 Git 的开发流程经验. 2010 年的 GitFlow 是一个很好的开始,它提供了一个很清楚的开发流程,几乎可说是目前用 Git 的「标准开发流程」.不过流程的目的是为了帮助软体开发和释出,而不同团队有著不同的需求,也就不可能有 "One size fits all " 的解法.

  • 看板工作流程是否敏捷呢? 2014-09-16

    Karl Scotland讨论研究了看板系统中的工作流程和阶段跟敏捷思想中跨功能协作团队是否互相违背,他指出在看板中的阶段看似瀑布思想中的阶段,接下来的讨论澄清了看板中的阶段不一定是"手递手"方式的工作传递,而且还有其他的见解. Karl先剖析了貌似瀑布开发过程的看板系统: 分析 -> 构建 -> 测试 -> 发布 之后他分析了一般 Scrum 工作板,如下: 未开始 -> 开发中 -> 完成 Karl 然后找寻不同方法让这工作板透露更多关于工作流程的情况

  • 分析Nutch的工作流程 2009-05-31

    Nutch的大致工作流程可以通过上一篇文章有了一定的了解了.在上一篇文章 中,主要是针对一幅Nutch工作流程图片来了解Nutch的工作流程,十分感性,并没有涉及到任何关于Nutch的包和类.这里通过在网上下载的一个 <Nutch入门学习>的PDF文档中介绍的内容,来详细组织一下,加深了解,为深入研究Nutch的源代码奠定良好的基础. 这里通过几个标题来叙述. Nutch爬虫工作策略 Nutch爬虫的工作策略一般则可以分为累积式抓取(cumulative crawling)和增量式抓取(inc

  • 工作流程引擎-工作流管理软件的概念 2009-06-11

    工作流引擎概念: 用来定义业务流程规则并在定义的规则下驱动业务流程正常运行的程序. 工作流引擎= 流程定义工具 + 流程运行程序 工作流引擎包含模块: 流程定义工具=流程定义工具+外部接口定义工具+报表定义工具+考核定义工具 流程运行程序=流程处理程序+工作预警+报表系统+考核定义工具 工作流管理软件的概念: 由工作流引擎定义出来的系统,称为工作流程管理信息系统. 工作流管理信息系统包含如下三个模块. 1,流程操作模块. 2,预警与考核模块. 3,报表模块. 以上是 ccflow 观点. 关于B

  • 适用于驰骋工作流程管理系统 判断是否允许请假的函数sql 2010-11-27

    ---------------------------------- -- 适用于驰骋工作流程管理系统 判断是否允许请假的函数sql -- http://hi.baidu.com/ccflow ---------------------------------- set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER FUNCTION [dbo].[CheckIsCandiaoxiu] ( @Rec VARCHAR(128), @Days int

  • 递归在算法在工作流程引擎中的应用 2011-03-26

    递归在算法在工作流程引擎中的应用 递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象.递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写程序能使程序变得简洁和清晰.. 递归在工作流程引擎中有广泛的应用,以以下事例来说明: 应用一:退回到指定的节点,要把当前节电与退回节点之间的节点数据清空. /// <summary> /// 递ÌY归¨¦删¦?除y两¢?个?节¨²点Ì?之?间?的Ì?数ºy据Y /// &l