python/cherry-picker
GitHub: python/cherry-picker
一个自动化Git工具,用于将主分支更改移植到维护分支。
Stars: 62 | Forks: 48
# cherry_picker
[](https://pypi.org/project/cherry-picker)
[](https://pypi.org/project/cherry-picker)
[](https://github.com/python/cherry-picker/actions/workflows/main.yml)
用法(从克隆的 CPython 目录执行):
```
Usage: cherry_picker [OPTIONS] [COMMIT_SHA1] [BRANCHES]...
cherry-pick COMMIT_SHA1 into target BRANCHES.
Options:
--version Show the version and exit.
--dry-run Prints out the commands, but not executed.
--pr-remote REMOTE git remote to use for PR branches
--upstream-remote REMOTE git remote to use for upstream branches
--abort Abort current cherry-pick and clean up branch
--continue Continue cherry-pick, push, and clean up branch
--status Get the status of cherry-pick
--push / --no-push Changes won't be pushed to remote
--auto-pr / --no-auto-pr If auto PR is enabled, cherry-picker will
automatically open a PR through API if GH_AUTH
env var is set, or automatically open the PR
creation page in the web browser otherwise.
--config-path CONFIG-PATH Path to config file, .cherry_picker.toml from
project root by default. You can prepend a colon-
separated Git 'commitish' reference.
-h, --help Show this message and exit.
```
## 关于
`cherry_picker` 可配置为移植其他具有与 CPython 类似工作流程的项目。更多详情请参阅下方配置文件选项。
维护分支名称应包含某种形式的版本号(`X.Y`)。
例如:`3.12`、`stable-3.12`、`1.5`、`1.5-lts` 均为支持的分支名称。
它会将分支名称添加到提交信息前,例如 `[3.12]`,然后打开拉取请求页面。
使用 [pytest](https://docs.pytest.org/) 编写测试。
## 设置信息
```
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ python -m pip install cherry_picker
```
验证 `upstream` 远程仓库已设置为 CPython 仓库:
```
$ git remote -v
...
upstream https://github.com/python/cpython (fetch)
upstream https://github.com/python/cpython (push)
```
如果需要,创建 `upstream` 远程仓库:
```
$ git remote add upstream https://github.com/python/cpython.git
```
默认情况下,用于向主仓库提交拉取请求的 PR 分支会推送到 `origin`。如果此默认设置不正确,则需要使用 `--pr-remote` 选项指定正确的远程仓库(例如,使用名为 `pr` 的远程仓库则为 `--pr-remote pr`)。
## Cherry-picking 操作 🍒⛏️
(请先完成设置!参见上一节。)
从克隆的 CPython 目录执行:
```
(venv) $ cherry_picker [--pr-remote REMOTE] [--upstream-remote REMOTE] [--dry-run] [--config-path CONFIG-PATH] [--abort/--continue] [--status] [--push/--no-push] [--auto-pr/--no-auto-pr]
```
### 提交 sha1
用于 cherry-pick 的提交 sha1 是合并到 `main` 分支的 squash 提交。在合并的拉取请求页面底部,找到类似以下内容的事件:
```
merged commit into python:main ago.
```
通过链接访问 ``,即可获得完整的提交哈希值。在 `cherry_picker.py` 中使用完整的提交哈希。
### 选项
```
--dry-run Dry Run Mode. Prints out the commands, but not executed.
--pr-remote REMOTE Specify the git remote to push into. Default is 'origin'.
--upstream-remote REMOTE Specify the git remote to use for upstream branches.
Default is 'upstream' or 'origin' if the former doesn't exist.
--status Do `git status` in cpython directory.
```
附加选项:
```
--abort Abort current cherry-pick and clean up branch
--continue Continue cherry-pick, push, and clean up branch
--no-push Changes won't be pushed to remote
--no-auto-pr PR creation page won't be automatically opened in the web browser or
if GH_AUTH is set, the PR won't be automatically opened through API.
--config-path Path to config file
(`.cherry_picker.toml` from project root by default)
```
配置文件示例:
```
team = "aio-libs"
repo = "aiohttp"
check_sha = "f382b5ffc445e45a110734f5396728da7914aeb6"
fix_commit_msg = false
default_branch = "devel"
require_version_in_branch_name = false
draft_pr = false
```
可用的配置选项:
```
team github organization or individual nick,
e.g "aio-libs" for https://github.com/aio-libs/aiohttp
("python" by default)
repo github project name,
e.g "aiohttp" for https://github.com/aio-libs/aiohttp
("cpython" by default)
check_sha A long hash for any commit from the repo,
e.g. a sha1 hash from the very first initial commit
("7f777ed95a19224294949e1b4ce56bbffcb1fe9f" by default)
fix_commit_msg Replace # with GH- in cherry-picked commit message.
It is the default behavior for CPython because of external
Roundup bug tracker (https://bugs.python.org) behavior:
#xxxx should point on issue xxxx but GH-xxxx points
on pull-request xxxx.
For projects using GitHub Issues, this option can be disabled.
default_branch Project's default branch name,
e.g "devel" for https://github.com/ansible/ansible
("main" by default)
require_version_in_branch_name Allow backporting to branches whose names don't contain
something that resembles a version number
(i.e. at least two dot-separated numbers).
draft_pr Create PR as draft
(false by default)
```
为其他项目自定义此工具:
1. 在项目根目录(`.git` 文件夹旁)创建名为 `.cherry_picker.toml` 的文件。
2. 按照上述说明添加 `team`、`repo`、`fix_commit_msg`、`check_sha` 和 `default_branch` 配置值。
3. 使用 `git add .cherry_picker.toml` / `git commit` 将配置文件加入 Git 管理。
4. 将 `cherry_picker` 添加到开发依赖项,或通过 `pip install cherry_picker` 安装。
5. 现在一切就绪,使用 `cherry_picker ` 将 `` 中的更改移植到维护分支。
分支名称应至少包含主版本号和次版本号,并可添加前缀或后缀。
从分支名称中提取版本时,仅匹配第一个版本样式的子字符串。
### 演示
- 安装:https://asciinema.org/a/125254
- 移植:https://asciinema.org/a/125256
### 示例
例如,要将 `6de2b7817f-some-commit-sha1-d064` 移植到 `3.12` 和 `3.11` 分支,请从克隆的 CPython 目录运行以下命令:
```
(venv) $ cherry_picker 6de2b7817f-some-commit-sha1-d064 3.12 3.11
```
此操作将执行以下步骤:
```
(venv) $ git fetch upstream
(venv) $ git checkout -b backport-6de2b78-3.12 upstream/3.12
(venv) $ git cherry-pick -x 6de2b7817f-some-commit-sha1-d064
(venv) $ git push origin backport-6de2b78-3.12
(venv) $ git checkout main
(venv) $ git branch -D backport-6de2b78-3.12
(venv) $ git checkout -b backport-6de2b78-3.11 upstream/3.11
(venv) $ git cherry-pick -x 6de2b7817f-some-commit-sha1-d064
(venv) $ git push origin backport-6de2b78-3.11
(venv) $ git checkout main
(venv) $ git branch -D backport-6de2b78-3.11
```
如果出现合并冲突或错误,将显示以下消息:
```
Failed to cherry-pick 554626ada769abf82a5dabe6966afa4265acb6a6 into 2.7 :frowning_face:
... Stopping here.
To continue and resolve the conflict:
$ cherry_picker --status # to find out which files need attention
# Fix the conflict
$ cherry_picker --status # should now say 'all conflict fixed'
$ cherry_picker --continue
To abort the cherry-pick and cleanup:
$ cherry_picker --abort
```
使用 `--dry-run` 选项将使脚本打印出所有将要执行的步骤,而不实际执行任何操作。例如:
```
$ cherry_picker --dry-run --pr-remote pr 1e32a1be4a1705e34011770026cb64ada2d340b5 3.12 3.11
Dry run requested, listing expected command sequence
fetching upstream ...
dry_run: git fetch origin
Now backporting '1e32a1be4a1705e34011770026cb64ada2d340b5' into '3.12'
dry_run: git checkout -b backport-1e32a1b-3.12 origin/3.12
dry_run: git cherry-pick -x 1e32a1be4a1705e34011770026cb64ada2d340b5
dry_run: git push pr backport-1e32a1b-3.12
dry_run: Create new PR: https://github.com/python/cpython/compare/3.12...ncoghlan:backport-1e32a1b-3.12?expand=1
dry_run: git checkout main
dry_run: git branch -D backport-1e32a1b-3.12
Now backporting '1e32a1be4a1705e34011770026cb64ada2d340b5' into '3.11'
dry_run: git checkout -b backport-1e32a1b-3.11 origin/3.11
dry_run: git cherry-pick -x 1e32a1be4a1705e34011770026cb64ada2d340b5
dry_run: git push pr backport-1e32a1b-3.11
dry_run: Create new PR: https://github.com/python/cpython/compare/3.11...ncoghlan:backport-1e32a1b-3.11?expand=1
dry_run: git checkout main
dry_run: git branch -D backport-1e32a1b-3.11
```
### `--pr-remote` 选项
此选项将通过非 `origin` 的远程仓库(例如 `pr`)生成拉取请求。
### `--upstream-remote` 选项
此选项将从非 `upstream`/`origin` 的远程仓库(例如 `python`)生成分支。
### `--status` 选项
此选项将对 CPython 目录执行 `git status`。
### `--abort` 选项
取消当前 cherry-pick 操作并清理 cherry-pick 分支。
### `--continue` 选项
继续当前 cherry-pick 操作,提交更改,将当前分支推送到 `origin`,打开 PR 页面,并清理分支。
### `--no-push` 选项
更改不会推送到远程仓库。这允许您进行测试和额外修改。一旦您对本地更改满意,可使用 `--continue` 完成移植,或使用 `--abort` 取消并清理分支。您还可以通过以下方式移植额外的提交:
```
$ git cherry-pick -x
```
### `--no-auto-pr` 选项
不会自动在网页浏览器中打开 PR 创建页面,或者如果设置了 GH_AUTH 环境变量,则不会通过 API 自动创建 PR。
如果您的终端无法打开合适的网页浏览器,或者您在使用 cherry-picker 时连接的 Git 托管平台不是 GitHub,此选项会很有用。
### `--config-path` 选项
允许使用自定义路径覆盖默认的配置文件路径(`<项目根目录>/.cherry_picker.toml`)。这使得 cherry_picker 能够移植 CPython 以外的项目。
## 创建拉取请求
当 cherry-pick 成功应用后,此脚本将打开一个浏览器标签页,指向拉取请求创建页面。
拉取请求页面的 URL 类似于以下形式:
```
https://github.com/python/cpython/compare/3.12...:backport-6de2b78-3.12?expand=1
```
点击 `Create Pull Request` 按钮。
随后,Bedevere 将从针对 `main` 分支的原始拉取请求中移除 `needs backport to ...` 标签。
## 运行测试
```
$ # Install pytest
$ pip install -U pytest
$ # Run tests
$ pytest
```
测试要求您本地 Git 版本为 2.28.0 或更高。
## 发布到 PyPI
- 请参阅 [发布清单](https://github.com/python/cherry-picker/blob/main/RELEASING.md)。
## 本地安装
在存在 `pyproject.toml` 的目录中:
```
$ pip install
```
## 更新日志
请参阅 [更新日志](https://github.com/python/cherry-picker/blob/main/CHANGELOG.md)。
标签:cherry-pick, CPython, Git, PR管理, PyPI, Python, SOC Prime, 代码移植, 代码管理, 分支操作, 安全可观测性, 实用程序, 开发工具, 开发流程, 开源, 数据管道, 无后门, 版本同步, 版本控制, 维护分支, 网络安全研究, 网络调试, 脚本, 自动化, 软件工程, 逆向工具