# Git 的使用工作流

Git 最大的优点同时也是它的最大的缺点:极具灵活性。这种灵活抬高了初学者的学习门槛。为此,有经验的程序员和大型机构结合软件开发的流程为 git 总结-提炼出了固定的使用方式,这中特定的使用顺序和方法被称为 工作流

Atlassian 公司推荐一种基于 git rebase 命令的 Git 工作流,这种工作流与 github 工作流的却别在于,『处理代码冲突』的工作从项目管理者转交到了代码提交者手里,项目提交者必须要保证自己的新代码与 master 分支合并后必须是无误的(至少是不耽误 master 分支原有代码运行的),再发起 pull request 。

# 1. 核心规则

这种基于 git rebase 的工作流核心准则只有 2 条:

  • 让你的本地的 master 和远程仓库的 master『在一起』;

    git-flow-1

    如何让它俩在一起?

    1. 切换到 master 分支

    2. 执行 git pull

  • 让你的工作分支始终保证是『基于你的本地最新 master』的。

    git-flow-2

    如何让工作分支基于最新的 master ?

    1. 切换到工作分支

    2. 执行 git rebase

总而言之,上述两个规则总结起来就是一句话:

时刻保证你当前的工作分支是『基于』最新的 master 远程分支。

# 2. 工作流程

这种工作流的整体流程如下:

[1]. git clone 下载中央仓库的项目。

[2]. 创建属于自己的分支。如何创建见后续。

[3]. 等待项目经理安排任务。接受到项目经理安排的任务:实现某某功能,或修改某某 bug 。

while (true) {

    [4]. 是否满足核心准则一:本地 master 是否是最新的?
    if (不是) {
        a. 更新(本地)master 分支。如何更新见后续。
    }

    [5]. 是否满足核心准则二:本地 xxx 是否是『基于』最新的 master ?
    if (不是) {
        a. 本地 xxx 分支变基。如何变基见后续。
    }

    [6]. 判断是否完成了任务?
    if (是) {
        a. 更新(远程)xxx 分支。如何更新见后续。
        b. 发起和并请求(pull request),并口头通知项目经理,希望他合并。
        c. break,跳出循环
    } 
    else if (否) {
        a. 写 5 分钟代码,努力完成项目经理安排的任务。 
    }

}

[7]. 回到上面第 [3] 步,再次等待项目经理安排新任务,开始新的工作周期。
  • 如何创建自己的分支:

    1. 保证是在 master 分支上

    2. 通过 git branch 命令创建分支,分支名自定义。

    3. 创建成功后,此时你是在你自己 xxx 分支上的。

  • 如何更新(远程)xxx 分支:

    1. 保证是在本地 xxx 分支上;

    2. 通过 git add 命令提交修改(至暂存区)

    3. 通过 git commit 命令提交修改(至本地仓库)

    4. 可选操作:通过 git rebase 命令(的第二个功效)压缩多个提交,优化提交记录。

    5. 通过 git push 命令推送(上传)本地 xxx 分支代码。

  • 如何更新(本地)master 分支:

    1. 此时你大概率是在本地 master 分支之外,例如,是在 xxx 分支上;

    2. 执行 git stash 命令暂存工作空间中的修改;

    3. 执行 git checkout 切换到 master 分支;

    4. 执行 git pull 命令拉取(下载)远程 master 分支;

    5. 执行 git checkout 切换回你来时的分支,例如,xxx 分支;

    6. 执行 git pop 取出曾经暂存的工作空间中的修改。

# 3. 正常的“不正常场景”

由于大家都是在向同一个中央仓库提交代码,因此,可能本来是 “正常” 的场景在你看来会无缘无故变成 “不正常” 的情况。

如果不是因为你的操作导致的,这些 “不正常” 的情况都是 “正常的不正常” ,是工作中的必然环节:

  • 正常的不正常场景一:本地 master 和中央仓库 master 不在一起

    atlassian-flow-1.png

    出现这种情况是因为你的同事的提交导致了中央仓库的版本的演进,而你的本地版本库还没有更新,所以就出现了上述情况。

    对于这种情况,要解决很简单,对你的 master 分支执行 git pull 来更新你的本地仓库就行了:

    atlassian-flow-2.gif

  • 不正常场景二:本地开发分支不是基于最新的 master

    atlassian-flow-3.png

    出现这种情况和上一个场景有一定关系。本来你的开发分支是基于最新的 master ,但是由于中央仓库的 master 更新以后,你“当初的” 最新 master ,已经不再是 “最新” 了,因此就出现了上述情况。

    对于这种情况,要解决也很简单,对你的开发分支执行 git rebase 变基就行了:

    atlassian-flow-4.gif

# 4. 不正常的“不正常场景”

  • 本地 master 要领先于中央仓库 master

    atlassian-flow-5.png

  • 开发分支不是基于最新的 master 就提交

    atlassian-flow-6.gif