作者:林纳斯·托瓦兹 (Linus Torvalds),Linux 的伟大的副产物

Linus 在 1991 年创建了开源的 Linux 之后靠着开发者共同维护。

2002 以前 ,contributors 把源代码文件通过 diff 的方式发给 Linus,Linus 和 维护者 手工方式 merge。

维护者受不了了,Linus 选择了 BitKeeper,并且很喜欢 BitKeeper.

理查德・斯托尔曼(Richard Stallman)自由软件倡导者,精神领袖,GNU计划创造者

并且有人开始对 BitKeeper 逆向,破解,BitKeeper 收回了 Linus 的免费使用权。

Linus 不得不要写一个自己的版本控制系统:

  • 1.速度优势,有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
  • 2.对非线性开发模式的强力支持(允许上千个并行开发的分支)
  • 3.完全分布式
  • 4.简单易用的设计

Linus 不到两周时间, C 写了一个分布式版本控制系统,1300 行左右,之后靠 contributors 去壮大。

身世评价:

亲爹:Linus 

干爹:世界各地 contributors 

外表:Source Tree, TortoiseGit 等等等 

内涵:这里

二. 集中式 与 分布式

集中化的版本控制系统:SVN

单一的集中管理的服务器,保存所有文件的修订版本,协同者通过客户端连到这台服务器,查看提交记录或者进行提交。checkout 的只是某个版本的代码,没有任何版本信息记录。

分布式版本控制系统:Git

客户端并不只提取最新版本的文件快照,而是把代码仓库 完整地镜像 克隆(clone) 提取(fetch) 到本地

  • 1.分布式,去中心化 
  • 2.本地提交 
    • 断网提交 
    • 小步提交,颗粒化,跟踪代码时,更加细腻 
    • 不用 sever,也可以进行版本控制 
  • 3.高速度,所以 commit,checkout 变得飞快 

 

三. Git 结构模型

为什么要理解 Git 结构模型?

  • 我在哪?
  • 我的代码呢?
  • 屏幕上的提示信息到底是让我干嘛?

四个区

两区两库:

  • Workspace:工作区,就是你在电脑里能看到的目录 
  • Index / Stage:暂存区,在暂存区的东西,才能 commit 到 Repository 
  • Repository:本地仓库
  • Remote:远程仓库

六指令:

  • add:增加 
  • commit:提交 
  • push:推送 
  • fetch:拉取 
  • checkout:检出 
  • pull:fetch + merge 

 

四. Git 配置及命令


1.配置 Git

//查看配置
git config --global --list
//编辑配置
git config --global --edit
 
//设置提交人
git config --global user.name "John Doe"
//设置邮件
git config --global user.email johndoe@example.com
//设置编辑器
git config --global core.editor emacs

git有3个配置文件,分别是仓库配置文件、全局配置文件、系统配置文件。

/etc/config 系统配置文件 作用于整个系统的设置

位于git目录的config文件 (也就是 .git/config)  当前项目配置

~/.gitconfig 全局配置文件 配置一些全局都需要用到设置。   作用于当前账号的设置。

如:常用的使用场景 

设置别名
 
//设置lg命令 查看分支图
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

//设置co命令等同于 checkout
git config --global alias.co checkout

//设置分页器,不分页
git config --global core.pager 'less -F -X'

2.有趣的git常用命令学习

LearnGit

 

 

3.对branch的理解

 

4.常见的问题

merge 和 rebase 的取舍

rebase: 保证了提交点的干净有序。 单分之多人开发的情况,建议rebase保证直观性。

merge: 更加详细了记录了开发路线。多分支合并建议merge保留完整路径。

 

rebase的冲突解决,

git rebase --continue


后悔药 reset revert reflog

reset

类似 SVN 的revert,将当前分支提交重置回某个提交点。

git reset [commit]
//--soft --mixed --hard

注意:不要对已经在远程服务器的 commit 进行 reset

revert

对某一次提交做一次反向操作,并且提交创建一个新提交

git revert [commit]

reflog

列出 HEAD 经历过的记录,神器~

git reflog

 

 

五. Git 开发模型–GitFlow

Git Flow 是什么

Git Flow是构建在Git之上的一个组织软件开发活动的模型,是在Git之上构建的一项软件开发最佳实践。Git Flow是一套使用Git进行源代码管理时的一套行为规范和简化部分Git操作的工具。

2010年5月,在一篇名为“一种成功的Git分支模型”的博文中,@nvie介绍了一种在Git之上的软件开发模型。通过利用Git创建和管理分支的能力,为每个分支设定具有特定的含义名称,并将软件生命周期中的各类活动归并到不同的分支上。实现了软件开发过程不同操作的相互隔离。这种软件开发的活动模型被nwie称为“Git Flow”。

一般而言,软件开发模型有常见的瀑布模型、迭代开发模型、以及最近出现的敏捷开发模型等不同的模型。每种模型有各自应用场景。Git Flow重点解决的是由于源代码在开发过程中的各种冲突导致开发活动混乱的问题。因此,Git flow可以很好的于各种现有开发模型相结合使用。

在开始研究Git Flow的具体内容前,下面这张图可以看到模型的全貌(引自nvie的博文):

Git Flow模型全图

Git Flow中的分支

Git Flow模型中定义了主分支和辅助分支两类分支。其中主分支用于组织与软件开发、部署相关的活动;辅助分支组织为了解决特定的问题而进行的各种开发活动。

主分支

主分支是所有开发活动的核心分支。所有的开发活动产生的输出物最终都会反映到主分支的代码中。主分支分为master分支和development分支。

主分支之间的互操作

master分支

master分支上存放的应该是随时可供在生产环境中部署的代码(Production Ready state)。当开发活动告一段落,产生了一份新的可供部署的代码时,master分支上的代码会被更新。同时,每一次更新,最好添加对应的版本号标签(TAG)。

develop分支

develop分支是保存当前最新开发成果的分支。通常这个分支上的代码也是可进行每日夜间发布的代码(Nightly build)。因此这个分支有时也可以被称作“integration branch”。

当develop分支上的代码已实现了软件需求说明书中所有的功能,通过了所有的测试后,并且代码已经足够稳定时,就可以将所有的开发成果合并回master分支了。对于master分支上的新提交的代码建议都打上一个新的版本号标签(TAG),供后续代码跟踪使用。

因此,每次将develop分支上的代码合并回master分支时,我们都可以认为一个新的可供在生产环境中部署的版本就产生了。通常而言,“仅在发布新的可供部署的代码时才更新master分支上的代码”是推荐所有人都遵守的行为准则。基于此,理论上说,每当有代码提交到master分支时,我们可以使用Git Hook触发软件自动测试以及生产环境代码的自动更新工作。这些自动化操作将有利于减少新代码发布之后的一些事务性工作。

辅助分支

辅助分支是用于组织解决特定问题的各种软件开发活动的分支。辅助分支主要用于组织软件新功能的并行开发、简化新功能开发代码的跟踪、辅助完成版本发布工作以及对生产代码的缺陷进行紧急修复工作。这些分支与主分支不同,通常只会在有限的时间范围内存在。

辅助分支包括:

  • 用于开发新功能时所使用的feature分支;
  • 用于辅助版本发布的release分支;
  • 用于修正生产代码中的缺陷的hotfix分支。

以上这些分支都有固定的使用目的和分支操作限制。从单纯技术的角度说,这些分支与Git其他分支并没有什么区别,但通过命名,我们定义了使用这些分支的方法。

feature分支

使用规范:

  • 可以从develop分支发起feature分支
  • 代码必须合并回develop分支
  • feature分支的命名可以使用除masterdeveloprelease-*hotfix-*之外的任何名称

feature分支(有时也可以被叫做“topic分支”)通常是在开发一项新的软件功能的时候使用,这个分支上的代码变更最终合并回develop分支或者干脆被抛弃掉(例如实验性且效果不好的代码变更)。

一般而言,feature分支代码可以保存在开发者自己的代码库中而不强制提交到主代码库里。

Feature分支

release分支

使用规范:

  • 可以从develop分支派生
  • 必须合并回develop分支和master分支
  • 分支命名惯例:release-*

release分支是为发布新的产品版本而设计的。在这个分支上的代码允许做小的缺陷修正、准备发布版本所需的各项说明信息(版本号、发布时间、编译时间等等)。通过在release分支上进行这些工作可以让develop分支空闲出来以接受新的feature分支上的代码提交,进入新的软件开发迭代周期。

当develop分支上的代码已经包含了所有即将发布的版本中所计划包含的软件功能,并且已通过所有测试时,我们就可以考虑准备创建release分支了。而所有在当前即将发布的版本之外的业务需求一定要确保不能混到release分支之内(避免由此引入一些不可控的系统缺陷)。

成功的派生了release分支,并被赋予版本号之后,develop分支就可以为“下一个版本”服务了。所谓的“下一个版本”是在当前即将发布的版本之后发布的版本。版本号的命名可以依据项目定义的版本号命名规则进行。

hotfix分支

使用规范:

  • 可以从master分支派生
  • 必须合并回master分支和develop分支
  • 分支命名惯例:hotfix-*

除了是计划外创建的以外,hotfix分支与release分支十分相似:都可以产生一个新的可供在生产环境部署的软件版本。

当生产环境中的软件遇到了异常情况或者发现了严重到必须立即修复的软件缺陷的时候,就需要从master分支上指定的TAG版本派生hotfix分支来组织代码的紧急修复工作。

这样做的显而易见的好处是不会打断正在进行的develop分支的开发工作,能够让团队中负责新功能开发的人与负责代码紧急修复的人并行的开展工作。

Hotfix分支

更进一步

Git Flow开发模型从源代码管理角度对通常意义上的软件开发活动进行了约束。应该说,为我们的软件开发提供了一个可供参考的管理模型。Git Flow开发模型让nvie的开发代码仓库保持整洁,让小组各个成员之间的开发相互隔离,能够有效避免处于开发状态中的代码相互影响而导致的效率低下和混乱。