Workflow based on git-flow
发布一个版本:
参考 git simple guide。
git diff
的有效性实践中,所有非手工编写文件都尽量不进入版本控制系统: * 二进制文件 * 程序生成的文件
**/__pycache__/
for Python project辅助工具:gitignore.io
常见处理方法:
Commit message 的作用:
让每一行代码讲述历史。最重要的产品文档。
让 git log
, git diff
和 git blame
充分发挥作用。
<type>(<scope>): <subject>
<body>
<footer>
What kind of action is performed in this commit?
常用标签:
What’s the object of the action?
改动的目标是什么?
What action is performed in this commit?
对本次提交的一句话说明,句尾不加句号
Why and how of <subject>
?
feat(backend): 实现了用户购物车基本功能
通过将购买服务加入购物车中,方便用户使用优惠券等提升购物体验
Fix #233
在 hook 文件 pre-commit 中定义,常用来进行本地代码的格式检查、单元测试等。 示例代码:
#!/usr/bin/env python
import sys
from subprocess import call
def runsh(cmd: str):
ret = call(cmd, shell=True)
if ret != 0:
sys.exit(f'Encounter error when running "{cmd}", return value: {ret}')
print('Linting codes ...')
# runsh('flake8 .')
runsh('flake8 --ignore=F401,E501 .')
print('Pass!')
由 hook 文件 prepare-commit-msg 实现,例如:
#!/usr/bin/env python
import sys
template = """
# This is a custom Template
# <type>(<scope>): <subject>
# <blank line>
# <body>
# <blank line>
# <footer>
# See [Git Commit Message Guidance]() for details
# Example:
# feat(backend): 实现了用户购物车基本功能
# 通过将购买服务加入购物车中,方便用户使用优惠券等提升购物体验
# Fix #233
"""
with open(sys.argv[1], 'w') as f:
f.write(template)
由 hook 文件 commit-msg 实现,对提交的信息进行格式检查,例如:
#!/usr/bin/env python
import sys
import re
with open(sys.argv[1], 'r') as f:
lines = f.read().splitlines()
valid_lines = [line for line in lines if (not line.startswith('#'))
and len(line) > 0]
assert len(valid_lines) >= 2, '有效行数小于2'
subject_format = (r'((feat)|(fix)|(docs)|(style)|(refactor)|(perf)|(test))'
r'\(\S+\):\s.*\S')
assert re.fullmatch(subject_format, lines[0]), '标题格式不符合要求'
assert len(lines[1]) == 0, '标题行下面没有空行'
assert len(lines[2].strip()) > 5, 'body 长度不足 5 个字符'
在指定的运行环境(gitlab runner)中执行 CI/CD 动作,一般由 build, test, deploy 三步组成。 常用的运行环境是 Docker,通过 image
关键字指定,例如 image: python:3.8.9
。
编写 .gitlab-ci.yml 文件,自动运行
优点:功能强大,可以对触发条件做精细控制,是代码库的一部分,方便管理
缺点:绑定 gitlab 平台
stages 间顺序执行,stage 内各个 job 并行执行。 前面 stage 中所有 job 运行完成后,开始下一个 stage。示例:
stages:
- build
- test
- deploy
image: python:3.8.9
job1:
stage: build
script:
- pip install -r requirements.txt
- echo "step 2"
job2:
stage: test
script:
- echo "run test 1"
- echo "run test 2"
job3:
stage: deploy
script:
- echo "run job 1"
- echo "run job 2"
顶层标签是 stages
or workflow
or image
.
workflow
一般包含 rules
实现对执行场景的精确控制,例如:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- if: '$CI_PIPELINE_SOURCE == "push"'
when: never
- when: always
与 local hook 一样保存在 .git/hooks 文件夹中,包括:
优点:任何 git 仓库都可用
缺点:需要有服务器文件系统读写权限,不是代码库的一部分,需要单独维护
需要单独编写 web 服务执行相关动作,比其他方式略重。
git add
git commit
git push
git pull --rebase
git push
每个特征使用一个分支,将特征分支 push 到 central repo。
开发过程中的 commit push 到 remote repo 对应的 feature branch 上。
开发完成后发起 PR 请求 merge 到 master 上,相关开发者接到通知,可以评论代码, 也可以 clone 此 branch 修改代码。
与 feature branches 模式的区别:特征分支基于 develop 分支而非 master 分支: 从 develop 创建,合并回 develop。
当 develop 满足发布版本的特征后,创建 release 分支,此分支只接收发布相关的 commit, 例如 bug fix,文档完善等。发布到 master 分支,并合并回 develop 分支。
优点:发布版本和特征开发并行。
brew install git-flow # on Mac
apt install git-flow # on Linux
全局级别:clone hook repo,设置 git hook 全局路径(可选);
项目级别:初始化 git flow 项目,设置项目环境:
$ cd ~/Documents
$ git clone git@123.56.15.24:datascience/git-template.git
$ git config --global core.hooksPath '~/Documents/git-template/hooks'
$ python -m venv .env
$ . .env/bin/activate
$ pip install Django pytest-django ipython ptpython pipdeptree flake8 pep8-naming yapf pynvim # config Python virtualenv
$ django-admin startproject messenger
$ cd messenger
$ pipdeptree -f > requirements.txt
$ git flow init -d
# or use interactive mode:
$ git flow init
Initialized empty Git repository in /home/leo/Documents/messenger/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]
How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [/home/leo/Documents/messenger/.git/hooks]
# on develop branch
# here run `git config core.hooksPath ~/Documents/git-template/hooks` to set template for only this repo
$ git flow feature start naive-func
# on feature/naive-func branch
这时自动进入 feature 分支。
去中心化,每个开发者都有两个 repo:本地的私有库和远端的公开库,多见于开源项目。 与其他协作方式相比,不需要开发者有中心库写权限,maintainer 负责审核所有开发者的 PR, 并写入到中心库中。
开发者的第一个动作不是 clone,而是 fork。