理解Git的工作流程(转)

  英文原文:Understanding the Git Workflow

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

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

  多数时候这样做的效果会如你所愿,因为从你创建分支到合并回去之间,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的运作机制又那么模糊,所有这些现象都说明一件事儿,那就是你正在把螺丝刀当锤子用。

  反思版本控制

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

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

  其次,就是辅助配置管理工作。其中就包括并行开发的管理,比如一边给线上版本修复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说的,“伟大的书都不是写出来——而是改出来的”(“Great books aren’t written – they’re rewritten.”)。

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

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

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

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

  规则和例子

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

  1)短期工作

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

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

git checkout -b private_feature_branch
touch file1.txt
git add file1.txt
git commit -am "WIP" 

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

git checkout master
git merge --squash private_feature_branch
git commit -v 

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

  2)较大的工作

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

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

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

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

  在我的功能分支上:

git rebase --interactive master 

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

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

pick ccd6e62 Work on back button
pick 1c83feb Bug fixes
pick f9d0c33 Start work on toolbar 

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

pick ccd6e62 Work on back button
squash 1c83feb Bug fixes
pick f9d0c33 Start work on toolbar 

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

  舍弃分支

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

git checkout master
git checkout -b cleaned_up_branch
git merge --squash private_feature_branch
git reset 

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

  总结

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

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

  推荐的工作流程是:

  1. 基于公共分支创建一个私有分支。
  2. 经常向这个私有分支commit代码。
  3. 一旦你的代码完善了,就清理掉私有分支的历史。
  4. 将干净的私有分支merge到公共分支中。

  (作者:Benjamin Sandofsky,译者:张重骐)

http://kb.cnblogs.com/page/152176/

 

时间: 2024-09-21 06:29:21

理解Git的工作流程(转)的相关文章

Git 教程之工作流程详解_相关技巧

Git 工作流程 本章节我们将为大家介绍 Git 的工作流程. 一般工作流程如下: 1.克隆 Git 资源作为工作目录. 2.在克隆的资源上添加或修改文件. 3.如果其他人修改了,你可以更新资源. 4.在提交前查看修改. 5.提交修改. 6.在修改完成后,如果发现错误,可以撤回提交并再次修改并提交. 下图展示了 Git 的工作流程:

分享用户研究工作流程:用户理解方法和经验

文章描述:如何了解我们的用户:无线终端用户理解工作方法分享. 一. 前言 来到腾讯以后,做过iPhone阅读器.iPad阅读器.iPad音乐播放器的用户理解,目前正在做iPhone QZone的用户理解工作.做得次数多了,方法在不断改进,也积累了一些经验,与大家一起分享,希望帮助我们更了解用户. 首先介绍一下目前北分wsd(无线研发部用户体验组)用户研究工作流程:我们的用研需求来自项目组和用研组需求池,为控制节奏和质量,对承接项目组需求的工作流程进行严格把控,我们针对项目组需求,制定了用研工作流

《深入理解Elasticsearch(原书第2版)》一1.2.3 Elasticsearch的工作流程

1.2.3 Elasticsearch的工作流程 本节我们将探索一些关键的Elasticsearch特性,如启动.故障检测.数据索引和查询等.1. 启动过程当Elasticsearch节点启动时,它使用发现(discovery)模块来发现同一个集群中的其他节点(这里的关键是配置文件中的集群名称)并与它们连接.默认情况下,Elasticsearch节点会向网络中发送广播请求,以找到拥有相同集群名称的其他节点.读者可以通过下图的描述来了解相关的处理. 集群中有一个节点被选为主(master)节点.该

【代码管理】GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git分支 标签 过滤 Git版本工作流

找到一篇很详细的Git教程,真的很不错,推荐!!! GitHub操作总结 : 总结看不明白就看下面的详细讲解. . 作者 :万境绝尘  . GitHub操作流程 : 第一次提交 :   方案一 : 本地创建项目根目录, 然后与远程GitHub关联, 之后的操作一样; -- 初始化git仓库 :git init ; -- 提交改变到缓存 :git commit -m 'description' ; -- 本地git仓库关联GitHub仓库 : git remote add origin git@g

从策划到设计的工作流程:明晰、 高效、欢乐

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

交互设计师的工作流程及不同阶段的职责

  交互设计师的工作,并不仅仅是输出设计方案,我们需要参与前期的需求讨论.后期开发.测试验收等等产品设计与实现的多个环节.本篇将介绍我目前参与交互设计的工作流程以及各个阶段的工作职责. 一.需求分析阶段 这个阶段,对于不同时期的产品讨论.分析的方面侧重点不同. 1.新产品 对于从无到有的心产品,需要了解: 产品的定位是什么? 用户群体是谁?他们有哪些特征?我们的产品需要解决用户的什么痛点?如果有竞品,我们与他们的优势在哪里.差异又在哪里? 这个阶段非常重要,但是也是最难讨论清楚的,即使是产品经理

UI设计的整个工作流程是怎样的?

  题外话 我认为设计师在工作中需要清楚了解设计的目的,尤其是你做的不是大众化产品,不能以个人认知.很强的主题性(如游戏)或"潮流"风格来确定目标时.比如设计小米手机的老人模式,老人需要什么样的颜色?增加样式是会产生干扰还是更好的体验感?按钮要多大才合适?在这种产品的UI设计时,设计师需要从头参与,而且到了设计环节时,设计师基本上已经心里有数了. 正式开始 我倾向于说"交互设计的整个流程".在我这里,UI是指"界面",在视觉设计开始之前,界面的的

《Photoshop Lightroom5经典教程》—第1课1.4节Lightroom工作流程

1.4 Lightroom工作流程 Photoshop Lightroom5经典教程 使用Lightroom模块化的界面使照片管理工作流程的每个阶段都变得更轻松,包括从照片获取到完成导出. 导入:Lightroom工作流程从图库模块开始,在图库模块中,可以从硬盘.存储设备或其他应用中获取照片:从相机中下载照片:从视频中提取帧,甚至可以绕开相机的存储卡而直接将照片存到Lightroom中. 分组:可以在"导入"对话框中设置选项来应用一个基本的组织操作到目录中,再通过给照片批量添加关键字标

《Adobe Premiere Pro视频编辑指南(第2版)》——第1章 Adobe的工作流程 认识Adobe Premiere Pro

第1章 Adobe的工作流程 现如今,视频编辑人员的工作任务变得越来越广泛了,我们所给的任务中只有少数是剪切项目的.通常,还会被要求调整音频.处理黑镜头画面或者为合成图形设置动画.由于工作任务种类的不断扩展,我们需要拥有或者使用大量的编辑软件.当今,大多数视频编辑人员必须至少理解和掌握多款软件的使用,例如:要基本了解Adobe Photoshop用于处理图像.Adobe Illustrator用于处理标识和艺术品,而且还要知道使用Adobe After Effects进行合成的基本流程. 我们编