资讯动态

SciPy 贡献者开发工作流实战:从 Fork 仓库到合入主线的完整 Git 流程

发布时间:2026/9/23 11:09:45 来源:尧图企业网站定制
科学计算数据科学高性能计算【免费下载链接】scipySciPy library main repository项目地址https://gitcode.com/gh_mirrors/sc/scipy点击查看免费下载本文是 SciPy 官方《Development workflow》指南位于 doc/source/dev/contributor/development_workflow.rst的深度展开版面向已经完成 SciPy 源码构建、准备向社区提交第一份代码的贡献者。读完本文你将掌握一套完整可复用的 GitHub 协作流程一次性初始化 Git 环境、基于upstream/main创建功能分支、在分支上编辑并规范提交、把分支推送到自己的 Fork 并通过 Pull Request 请求合并同时了解提交前必须逐项核对的工程化检查清单测试、文档、代码风格、基准测试与构建集成并用仓库中的真实源码与测试文件印证每一个环节。开始之前你需要具备的前提本指南默认你已完成以下三步准备原文明确要求已在自己的 GitHub 账号下创建了 SciPy 仓库的Fork副本已在本地机器上clone了该 Fork并从源码构建出了 SciPy尚未开始任何代码修改。如果还没有完成构建请先阅读 doc/source/building/contributor.rst。该页面把构建流程拆成系统级依赖安装与使用spin接口构建 SciPy 本身两步其中推荐的开发流程是conda env create -f environment.yml # 或 python -m venv venv 后按 pyproject.toml 装依赖 conda activate scipy-dev spin build构建完成后spin接口会在仓库内默认build-install目录安装 SciPy随后即可运行spin test、spin ipython等开发命令。原文还提示可以观看官方《SciPy Development Workflow》视频一个修 bug 提 PR的五分钟示例作为阅读本文的辅助材料。一次性初始化三件事让 Git 认识你与官方仓库在开始修改代码之前只需做一次以下三件事原文称之为 three other things you need to do just once。1. 向 Git 介绍你自己git config --global user.email youyourdomain.com git config --global user.name Your Nameuser.email与user.name会写进你每一个提交的作者信息中用于为你的工作署名注意一旦你把分支push到 GitHub这些信息就是公开可见的。如果希望隐藏真实邮箱可参考 GitHub 官方文档 Setting your commit email address in Git 配置隐私邮箱。2. 为官方仓库添加名为upstream的远程引用git remote add upstream https://github.com/scipy/scipy.git这里的关键概念是两个 remote 的分工Remote指向角色origin你自己的 Fork你 push 代码的地方upstream官方 SciPy 仓库你拉取最新版本代码的地方clone Fork 时 Git 已经自动把origin指向你的 Fork而upstream需要手动添加。典型的信息流是从upstream拿到最新代码 → 在本地做修改 → push 到origin→ 通过 Pull Request 请官方把变更从你的 Fork 拉 回主线。这正是 pull request 名称的由来。3. 初始化 Git 子模块git submodule update --initSciPy 依赖若干子模块如 Boost以及仓库中的subprojects/目录下的xsf、highs、cobyqa、biteopt、duccfft、pyprima等外部库该命令会一次性拉取并更新全部子模块。未初始化子模块时spin build很可能因为找不到依赖而失败。总体工作流三个步骤的主干原文用一个高度浓缩的清单概括了整个开发循环为每一组编辑新建一个独立的功能分支feature branch见下文创建功能分支尽情编码见下文编辑工作流完成后普通贡献者把功能分支推到自己的 GitHub 仓库并创建 Pull Request核心开发者Core developers如果不需要进一步审查可以参考仓库维护文档中的说明直接推送到主线。这种一功能一分支的做法能保持工作井然有序也让提交历史尽可能清晰可读。原文还建议如果想系统学习 Git可参考众多在线 Git 教程以及 Linux 与 IPython 社区的 Git 工作流讨论。创建功能分支从正确的基线出发功能分支的生命周期从这里开始。首先拉取upstream的最新提交git fetch upstream然后基于upstream的main分支创建并切换新分支git checkout -b my-new-feature upstream/main也可以先把本地main更新到与上游同步再基于本地main开分支git checkout main git rebase upstream/main git checkout -b my-new-feature这三条命令依次完成切换到本地main→ 把upstream/main的全部最新变更重放到本地main上 → 基于更新后的main创建并切换新分支-b即 create-and-checkout。无论采用哪种方式都务必保证功能分支包含upstream/main的最新变更——这是避免日后提 PR 时出现合并冲突的关键。原文特别强调分支建成后最好先构建并跑一遍测试再继续开发。在已按构建指南配置好的开发环境中conda activate scipy-dev spin test -vspin test会在需要时自动执行构建-v开启详细输出。关于spin test的完整用法如-s指定子模块、-t指定测试文件/测试类/单条测试、-j并行构建、-m full跑全量测试、--透传 pytest 参数等请参考 doc/source/dev/contributor/devpy_test.rst下文也会结合测试用例进一步说明。编辑工作流改代码、看差异、暂存、提交、推送总览原文给出了一个极简的编辑循环# hack hack 改代码 git status # 可选查看变更状态 git diff # 可选查看具体差异 git add modified_file git commit # 把分支推到自己的 GitHub 仓库 git push origin my-new-feature分步详解做修改完成一组完整、可运行、彼此相关的修改后再进行下一步。不建议把半成品混入提交。git status可选查看哪些文件发生了变化。典型输出类似# On branch my-new-feature # Changed but not updated: # (use git add file... to update what will be committed) # (use git checkout -- file... to discard changes in working directory) # # modified: README # # Untracked files: # (use git add file... to include in what will be committed) # # INSTALL no changes added to commit (use git add and/or git commit -a)modified表示已跟踪文件的改动Untracked表示尚未纳入 Git 跟踪的新文件。git diff可选打开一个简单的文本浏览器界面逐行对比当前文件与上一版本的差异确认改动符合预期。git add modified_file把文件放入暂存区staging area。暂存区是下一次提交的内容队列——只添加具有相关且完整改动的文件未完成的改动留给后续提交。这一步也是精细化控制提交粒度的关键。git commit把暂存区提交到本地仓库。此时会打开文本编辑器让你撰写提交信息——务必先阅读下文提交信息规范再动笔。保存并关闭编辑器后提交即完成。对于琐碎提交可用-m直接内联信息例如git commit -am ENH: Some message-a标志会自动暂存所有已修改文件并删除已删除文件能省去多次git add。但原文也警告-a可能把不想要的改动一并带入提交即 tangled working copy 问题使用时要格外小心。git push origin my-new-feature把分支推送到你的 Fork 仓库。让推送更省事--set-upstream按前文步骤操作后Git 默认会把你的 Fork 记为origin。在 Git 1.7 中可以用--set-upstream永久建立本地分支与远程分支的关联git push --set-upstream origin my-new-feature此后每次只需git push注意--set-upstream需要为每一个新建分支各执行一次。分支过期了怎么办如果在你编辑期间upstream又合入了新提交并影响你的工作请按 doc/source/dev/gitwash/useful_git.rst 中rebasing on main一节的指引把这些变更 rebase 到你的分支上而不是用 merge——这能让 PR 的提交历史保持线性整洁。提交信息规范让历史可读、可检索提交信息需要清晰且遵循几条基本规则。原文给了两个示例MAINT/TST: fft: remove xp backend skips, test fftfreq device The first line of the commit message starts with a capitalized acronym (or multiple, options listed below) indicating what type of commit this is. Then a blank line, then more text if needed. References to code names should be enclosed in backticks. If changes are limited to certain submodules or functions, they should be included after the acronym(s) - backticks are not needed here.BUG:sparse.linalg.gmres: add early exit when x0 already solves problem Lines shouldnt be longer than 72 characters. If the commit is related to an issue, indicate that with See gh-3456, Closes gh-3456, or similar, in the extended description. However, if you are pushing many commits to a PR, you should avoid including this in every commit message as it will clutter the linked issue.要点总结首行以大写首字母的缩写开头指明提交类型缩写可组合如MAINT/TST:首行之后空一行再写正文引用代码中的名称函数名、变量等用反引号包裹子模块/函数范围放在缩写之后不需要反引号每一行不超过 72 个字符与 Issue 相关时在扩展描述中写See gh-3456、Closes gh-3456等。但若一个 PR 含大量提交避免在每个提交里都写以免刷屏关联 Issue好的提交信息应说明改动的动机、bug 修复的本质或增强功能的细节让读者不查看代码 diff 也能理解。MAINT: fixed another one就是反例——读者必须去别处找上下文。标准提交类型缩写原文完整清单缩写含义API不兼容的API 变更BENCH基准测试套件benchmark suite的变更BLD与构建 SciPy 相关的变更BUGbug 修复DEP弃用deprecate某个对象或移除已弃用对象DEV开发工具或实用程序DOC文档ENH功能增强MAINT维护性提交重构、错别字等REV回滚之前的提交STY风格修正空白、PEP8TST测试的新增或修改REL与发布 SciPy 相关在提交信息中跳过部分 CI你还可以在提交信息中添加特定标记跳过部分持续集成检查详见 doc/source/dev/contributor/continuous_integration.rst标记效果[skip actions]跳过 GitHub Actions[skip circle]跳过 CircleCI[docs only]只保留 CircleCI 检查与 linter[lint only]只保留 linter[skip ci]跳过全部 CI这些标记应放在独立的新一行可组合使用。例如只改了文档里的.rst文件、想跳过 GitHub Actions 检查时DOC: improve QMCEngine examples. [docs only]需要提醒的是CI 资源是社区共享的有限配额官方建议在 push 前先在本地充分验证最终是否允许跳过部分检查由维护者在合入前酌情决定。发起合并请求从 Pull Request 到代码审查当你觉得工作完成时就可以创建 Pull RequestPR请求合并。GitHub 官方帮助页有完整的提交流程说明。如果改动涉及API 变更或函数的新增/修改原文建议发起一次代码审查code review向 SciPy 论坛发送一封邮件附上 PR 链接并说明改动内容与动机。提交 PR 前的检查清单逐项可验证的工程红线原文为提交 PR 前的自检给出了 11 项硬性要求这里逐项展开并给出对应在仓库中的验证落点许可证确认代码可在 BSD 许可证下分发。SciPy 根目录的 LICENSE.txt 与 LICENSES_bundled.txt 列出了许可证条款更详细的授权考虑参见 doc/source/dev/hacking.rst 中 license considerations 一节。AI 政策确认改动符合 SciPy 的 AI 政策参见 doc/source/dev/conduct/ai_policy.rst。单元测试与覆盖率是否提供覆盖良好的单元测试测试编写指南见 NumPy/SciPy Testing Guidelines运行方式见 doc/source/dev/contributor/devpy_test.rst。本地测试全绿所有单元测试是否在本地通过即上文与下文的spin test用法。docstring 含示例所有公开函数是否都有含示例的 docstring规范见 numpydoc docstring guide。文档渲染正确参见 doc/source/dev/contributor/rendering_documentation.rst。代码风格正确PEP8 合规性说明见 doc/source/dev/contributor/pep8.rst。基准测试是否提供了基准测试benchmark参见 doc/source/dev/contributor/benchmarking.rstairspeed velocity / asv。提交信息格式参见上文提交信息规范。版本标记新功能的 docstring 是否用.. versionadded:: X.Y.Z标记了下一个发布版本号原文以scipy.optimize.differential_evolution的updating、workers、constraints参数文档为例——该函数实现在 scipy/optimize/_differentialevolution.py其 docstring 是查看 versionadded 标记用法的现成范本。教程/模块级描述较大规模的新增内容是否配有 tutorial 或更完整的模块级描述SciPy 教程文件位于 doc/source/tutorial 目录。构建系统集成新增文件是否正确接入meson.build编译代码集成说明见 doc/source/dev/contributor/compiled_code.rst。实战佐证用仓库真实文件走一遍流程以上清单并非抽象口号仓库中处处可见其落地形态。以线性规划求解器为例其测试文件为 scipy/optimize/tests/test_linprog.py。假设你修了一个 linprog 的 bug可以这样逐层验证# 只跑整个 optimize 子模块的测试 spin test -s optimize # 只跑 linprog 测试文件 spin test -t scipy.optimize.tests.test_linprog # 只跑某个测试类 spin test -t scipy.optimize.tests.test_linprog::TestLinprogRSCommon # 只跑单条测试 spin test -t scipy.optimize.tests.test_linprog::test_unknown_solvers_and_options # 类内的单条测试类名 测试名 spin test -t scipy.optimize.tests.test_linprog::TestLinprogRSCommon::test_nontrivial_problem_with_guess-t使用 pytest 的目标语法其余实用选项包括-v/--verbose详细输出、-b引入 array-api 后端、--coverage生成覆盖报告到scipy/build/coverage/index.html、-n跳过自动构建、-j 4用 4 核构建安装 pytest-xdist 后也会并行跑测试、-m full跑含slow标记的全量测试以及--把剩余参数透传给 pytest例如spin test -- -n 4、--durations10显示最慢的 10 个测试。细节均可查阅 doc/source/dev/contributor/devpy_test.rst。如果你改动了编译代码后测试行为异常可以删除scipy/build目录强制spin全量重建。仓库根目录的 conftest.py 还定义了 Hypothesis 的deterministic测试配置含derandomizeTrue保证用例可复现可通过环境变量SCIPY_HYPOTHESIS_PROFILEnondeterministic切换为探索性更强的随机配置SCIPY_XSLOW1则可启用平时连-m full都不跑的超级慢测试这类测试通常需要数分钟。常见问题与进阶指引合并冲突只要功能分支始终基于最新的upstream/main冲突概率就很小真遇到冲突时按前文 rebase 指引解决。如何查看上游分支关系git log upstream/main与git log -p upstream/main..等组合可查看本地分支与上游的差异详见 doc/source/dev/gitwash/useful_git.rst。想更深入了解 Git 本身建议阅读 Pro Git 手册关于git add暂存区、为什么用-a、以及 tangled working copy 问题仓库的 gitwash 文档 doc/source/dev/gitwash/gitwash.rst 也有系统讲解。持续集成全景SciPy 在 GitHub Actions 上运行 Lint、Windows/Linux/macOS 测试、Wheels 构建、文档预览、prerelease 依赖覆盖、gcc-9 最低编译器版本与 Array API 测试等工作流在 CircleCI 上运行文档构建、基准与 refguide 检查具体.yml配置可查看.github/workflows/目录。这些内容以及fail-slow超时策略、wheel 构建触发条件提交信息含[wheel build]、每周定时、手动触发、v开头 tag均记录在 doc/source/dev/contributor/continuous_integration.rst。至此从一次性的 Git 环境初始化到功能分支的创建、编辑、规范提交、推送再到 Pull Request 与合入前的逐项检查你已经拥有了一条完整、可复现的 SciPy 贡献路径。把这份工作流固化下来后续每一次 bug 修复与功能增强都只是这条主干的又一次循环。赞分享科学计算数据科学高性能计算【免费下载链接】scipySciPy library main repository项目地址https://gitcode.com/gh_mirrors/sc/scipy点击查看免费下载相关推荐Meshery 贡献者 Git 工作流实战指南从 Fork 到 Pull Request 的完整流程Meshery 贡献者 Git 工作流实战指南从 Fork 到 Pull Request 的完整流程 本篇指南以 Meshery 开源项目官方仓库中的 doc云原生微服务运维DevOpsMoviePy 贡献指南从 Fork 到合并的完整开发者工作流MoviePy 贡献指南从 Fork 到合并的完整开发者工作流 导读 本文档基于 MoviePy 官方开发者指南 contribution_guideline音视频视频处理音频处理Aptos Core 贡献指南从 Fork 到合并的完整开发者工作流Aptos Core 贡献指南从 Fork 到合并的完整开发者工作流 本指南基于 aptos core 仓库根目录的 CONTRIBUTING.md http区块链Web3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价