Git 和 Git 分支模型
本文基于使用私有部署的 GitLab 来作为代码仓库,来讲述我们在使用 Git 作为版本控制工具方面的实践。
配置 SSH KEY
为了可以免密拉取和提交代码,需要配置 SSH key。
- 查看是否已有 SSH key 存在
打开终端,输入 ls -al ~/.ssh
ls -al ~/.ssh # Lists the files in your .ssh directory, if they exist
如果存在,跳到 3 步,否则,跳到第 2 步
- 生成 SSH Key
打开终端,复制以下命令,记得替换邮箱地址
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
一路回车即可,不要设置密码
- 复制 SSH Key 到 GitLab
运行以下命令,复制 SSH Key 到剪贴板
pbcopy < ~/.ssh/id_rsa.pub # Copies the contents of the id_rsa.pub file to your clipboard
打开 GitLab -> Profile Settings -> SSH Keys 右键粘贴或者 Command + V,把刚刚拷贝的 SSH Key 添加到 Key 文本域里面,注意不要有新行或空格,随意起一个 title,点击 Add key 按钮确认添加。
- 测试 SSH 连接
通过以下命令测试 SSH 连接,记得将 gitlab.com 替换成私有部署的 GitLab 域名。
ssh -T git@gitlab.com
如果连接成功,会看到下面这样的信息
Welcome to GitLab, @listen!
掌握 Git 基本知识
常用命令:
# 从远程主机克隆仓库到本地 git clone [url] # 新建一个分支,并切换到该分支 git checkout -b feature/login # 显示本地仓库状态 git status # 添加当前目录的所有文件到暂存区 git add . # 提交暂存区到仓库区 git commit -m [message] # 修改上一次提交 git commit --amend -m [message] # 用 rebase 模式合并代码 git pull --rebase origin master:feature/login # 删除在远端已经不存在的分支,以及同步远端 tag git fetch origin --tags --prune --force # 解决冲突后,继续 rebase git rebase --continue # 上传本地指定分支到远程仓库,并建立追踪关系 git push -u origin feature/login # 强行推送当前分支到远程仓库对应分支,即使有冲突 git push --force # 停止追踪指定文件,但该文件会保留在工作区 git rm --cached [file] # 改名文件,并且将这个改名放入暂存区 git mv [file-original] [file-renamed]
请务必理解 merge 和 rebase 的区别open in new window
如果遇到意外,可使用 git reflog
和 git reset --hard
来救命。
推荐使用 Sourcetreeopen in new window 可视化管理 Git 仓库,专注于编码。
brew install --cask sroucetree
提交规范
一个 Commit 只应该做一件事情,或者添加、删除功能,或者处理 BUG,或者修改构建配置等等。
一条 Commit 消息,由标题和正文两部分组成,通常只有标题,而没有正文。
标题应当简洁明了地陈述清楚,在什么领域,为了什么,做了什么事情。标题尽量简短,不要超过 30 个汉字。标题必须以动词开头。譬如:
# 添加验证码登录 # 添加 vivo 推送 # 处理因为苹果 logo 未能通过审核的问题 # 修改 eslint 配置,以禁止行内样式 # 移除个人中心无用的方法 # 调整主页样式
如果有需要,可以空一行,书写正文,解释为什么要这么做,如果是修复 Jira 上的 BUG,把 BUG 的链接放在这里。譬如
# 处理切换用户,数据没有同步的问题 # https://jira.xxxxxx.com/browse/DA-248
禁止像如下那样编写 commit 信息
修复 DA-248
DA-248 代表什么问题,你倒是说清楚呀。
理解 Git 分支管理模型
根据我们团队的规模,产品迭代频率,我们使用的分支管理模型主要基于 GitHub Flow
:
master 分支是我们的持续集成分支,是个受保护的分支,不允许直接 push 代码。
也就是说,以下命令将会失效
git push origin master
日常开发流程
- 创建分支
当有新的需求时,从 master 拉一个 feature 分支进行开发。
分支或以功能命名或以开发者命名,如 feature/login
# 创建新的 feature 分支 git checkout -b feature/login
- 持续集成
不断地将自己的代码合并(merge)到 master,是持续集成,不断地将 feature 分支 rebase 到 master 也是持续集成。
借助 sourcetree 等可视化工具,可以方便地感知 master 分支是否有新的代码合并。如果 master 已有新的代码,那么需要将 feature 分支 rebase 到 master。
git pull --rebase origin master:feature/login
如果有冲突,解决,继续 rebase
git rebase --continue
- 持续交付
在 rebase 到 master 或提交(commit)新的代码后,需要及时推送(push)到远程仓库。代码推送到远程仓库后,会触发 CI,进行必要的代码检查和单元测试,以及构建。
git push -u origin
可以在 GitLab 上手动触发相应的 CI/CD 流程,打包给 QA 进行测试,根据反馈,持续完善功能。
- 请求合并
即使功能尚未开发完成或通过 QA 测试,也可以创建 Merge Request,进行代码评审,根据评审意见,持续完善代码。代码评审通常和第三步交替进行。
创建 Merge Request 后,只要代码还没有被批准合并,都可以持续提交代码,甚至强制提交(尤其是在 rebase 之后)。
git push --force
feature 分支在通过 CI,通过评审,以及通过测试后,会被批准合并到 master。
feature 分支合并到 master 后,会被自动删除。可使用以下命令清理本地仓库,以免堆积过多无用分支。
git fetch origin --tags --prune
release
需要发版时,由项目 owner 基于 master 创建 release 分支,并打上 tag 作为版本号,发布新的版本。
如果线上版本有 BUG,通常基于 master 拉一个 bugfix 分支进行修复,代码通过 Merge Request 合并到 master 后,由项目 owner 根据情况 merge 或 cherry-pick 到对应的 release 分支,在该 release 分支打上新的 tag 并发布新的版本。