Git 作为一个源码管理系统,不可避免涉及到多人协作。
协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去。”工作流程”在英语里,叫做”workflow”或者”flow”,原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡。
所以制定一套规范有效的git工作流来规范我们的分支管理和工作流程是极其必要的,并且越早越好。
下面是三种广泛使用的工作流程:
Git 使用规范流程 团队开发中,遵循一个合理、清晰的Git使用流程,是非常重要的。
否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护。
参考流程:
整体上,团队小,采用简单的形式,快;团队大,采用严谨的形式,稳。
具体操作步骤如下:
新建分支
首先,每次开发新功能/修复 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
提交分支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 的结果。
撰写提交信息
提交commit时,必须给出完整扼要的提交信息,下面是一个范本。
第一行是不超过50个字的提要,然后空一行
* 罗列出改动原因,
* 主要变动,
* 以及需要注意的问题
最后,提供对应的网址(比如Bug ticket)。
与主干同步
分支的开发过程中,要经常与主干保持同步。
# TODO:
# 分支的开发过程中,要经常与主干保持同步
$ git fetch origin
# 或
$ git rebase origin/master
合并commit
这里分两种派别
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
推送到远程仓库
合并commit后,就可以推送当前分支到远程仓库了。
$ git push
# 不要使用 --force
使用 rebase
以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送(即加 –force 参数 参见这里)。
发出Pull Request
提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。
# 提交到远程仓库以后,就可以发出 Pull Request 到发布分支release,
# 然后请求别人进行代码review,确认可以合并到release
$ git push
发布上线,并增加tag标签标记版本。
git tag v1.x.x
git push --tags
我们可以使用 git-flow 进行有效的分支实践
# mac
$ brew install git-flow-avh
| init
git | feature| -| start -| name
| release| | finish |
| hotfix | | publish |
| pull |
因为项目开发一般要加分支保护,所以使用此工具有问题(直接操作了 master 受保护分支,无法 push),所以此工具可以使用于非团队的私人项目开发
团队开发,仍然采用类似此流程,但通过 PR 形式合并入开发分支或生产分支,而且控制上更灵活。
参考: