learn-git

git-workflow

工作流

Git 作为一个源码管理系统,不可避免涉及到多人协作。

协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去。”工作流程”在英语里,叫做”workflow”或者”flow”,原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡。

所以制定一套规范有效的git工作流来规范我们的分支管理和工作流程是极其必要的,并且越早越好。

git-flow

下面是三种广泛使用的工作流程:

Git 使用规范流程

Git 使用规范流程 团队开发中,遵循一个合理、清晰的Git使用流程,是非常重要的。

否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护。

参考流程:

整体上,团队小,采用简单的形式,快;团队大,采用严谨的形式,稳。

具体操作步骤如下:

  1. 新建分支

    首先,每次开发新功能/修复 bug,都应该新建一个单独的分支,详细可以参考分支管理策略

     # 获取主干最新代码
     $ git checkout master
     $ git pull
    
     # 开发新功能 新建 feature/myfeature 分支(基于 dev)
     # 修复bug 新建 hotfix/xxx 分支(基于 master)
     $ git checkout -b hotfix/xxx master
     $ git checkout -b feature/xxx develop
    
  2. 提交分支commit

    分支修改后,就可以提交commit了。

     # 分支修改后,就可以提交commit了
     $ git add .
     $ git status
    
     # verbose参数,会列出 diff 的结果
     $ git commit --verbose
    

    git add 命令的all参数,表示保存所有变化(包括新建、修改和删除)。从Git 2.0开始,all是 git add 的默认参数,所以也可以用 git add . 代替。

    git status 命令,用来查看发生变动的文件。

    git commit 命令的verbose参数,会列出 diff 的结果。

  3. 撰写提交信息

    提交commit时,必须给出完整扼要的提交信息,下面是一个范本。

     第一行是不超过50个字的提要,然后空一行
    
     * 罗列出改动原因,
     * 主要变动,
     * 以及需要注意的问题
    
     最后,提供对应的网址(比如Bug ticket)。
    
  4. 与主干同步

    分支的开发过程中,要经常与主干保持同步。

     # TODO:
     # 分支的开发过程中,要经常与主干保持同步
     $ git fetch origin
     # 或
     $ git rebase origin/master
    
  5. 合并commit

    这里分两种派别

    • 一为 merge 模式,简单
    • 二为 rebase 模式,干净

    merge 模式

    使用 git merge xxx --no-ff 保证版本演进的清晰。

    rebase 模式

    严格遵守:Golden Rule of Rebasing 永远不要在public 分支上使用git rebase!

    分支开发完成后,很可能有一堆commit,但是合并到主干的时候,往往希望只有一个(或最多两三个)commit,这样不仅清晰,也容易管理。

    那么,怎样才能将多个commit合并呢?这就要用到 git rebase 命令。

     $ git rebase -i origin/master
    
     # rebase命令的i参数表示互动(interactive),这时git会打开一个互动界面,进行下一步操作。
     - pick:正常选中
     - reword:选中,并且修改提交信息;
     - edit:选中,rebase时会暂停,允许你修改这个commit
     - squash:选中,会将当前commit与上一个commit合并
     - fixup:与squash相同,但不会保存当前commit的提交信息
     - exec:执行其他shell命令
    

    origin master vs origin/master

    • origin master 代表着两个概念,前面的 origin 代表远程名,后面的 master 代表远程分支名
    • origin/master 只代表一个概念,即远程分支名,是从远程拉取代码后在本地建立的一份拷贝(因此也有人把它叫作本地分支)。
    • git rebase origin/master 所以做 rebase master 分支,使用的是这个命令

    操作

     # https://stackoverflow.com/questions/45920951/when-use-rebase-master-or-origin-master
     # 假设当前分支 feature/abc
     # 方案 1: 基于本地 master 做 rebase
     git checkout master
     git pull origin master
     git checkout - # 或 git checkout feature/abc
     git rebase master
    
     # 方案 2: 基于远程 origin/master 做 rebase
     git fetch
     # 我们常用的就是这个,让当前 feature 开发分支保持基于最新的 master 开发
     # 之后再提交 MR 到 master 进行合并
     git rebase origin/master
    
     # 方案 3: 汇总
     git pull origin master --rebase
    
     # 方案 4: 如果你更懒,你可以在拉动时默认设置 rebase。
     git config --global pull.rebase true
     git pull origin/master
    

    说明

    • 执行 git fetch origin master 时,它的意思是从名为 origin 的远程上拉取名为 master 的分支到本地分支 origin/master 中。既然是拉取代码,当然需要同时指定远程名与分支名,所以分开写。
    • 执行 git merge origin/master 时,它的意思是合并名为 origin/master 的分支到当前所在分支。既然是分支的合并,当然就与远程名没有直接的关系,所以没有出现远程名。需要指定的是被合并的分支。
    • 执行 git push origin master 时,它的意思是推送本地的 master 分支到远程 origin,涉及到远程以及分支,当然也得分开写了。
    • 还可以一次性拉取多个分支的代码:git fetch origin master stable oldstable
    • 也还可以一次性合并多个分支的代码:git merge origin/master hotfix-2275 hotfix-2276 hotfix-2290
     git pull=git fetch + git merge
     git pull --rebase=git fetch+git rebase
    
  6. 推送到远程仓库

    合并commit后,就可以推送当前分支到远程仓库了。

     $ git push
     # 不要使用 --force
    

    使用 rebase 以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送(即加 –force 参数 参见这里)。

  7. 发出Pull Request

    提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。

     # 提交到远程仓库以后,就可以发出 Pull Request 到发布分支release,
     # 然后请求别人进行代码review,确认可以合并到release
     $ git push
    
  8. 发布上线,并增加tag标签标记版本。

     git tag v1.x.x
     git push --tags
    

git-flow 备忘清单

我们可以使用 git-flow 进行有效的分支实践

# mac
$ brew install git-flow-avh
    | init
git | feature| -| start   -| name
    | release|  | finish   |
    | hotfix |  | publish  |
                | pull     |

因为项目开发一般要加分支保护,所以使用此工具有问题(直接操作了 master 受保护分支,无法 push),所以此工具可以使用于非团队的私人项目开发

团队开发,仍然采用类似此流程,但通过 PR 形式合并入开发分支或生产分支,而且控制上更灵活。

参考: