ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

准备参与开源项目:GitHub 贡献代码的基本流程

准备参与开源项目:GitHub 贡献代码的基本流程 准备参与开源项目GitHub 贡献代码的基本流程前言最近打算参与一些开源项目。一方面想接触真实项目的开发和协作方式另一方面也想积累一些能够放进简历、经得住追问的实践经历。但准备动手时我发现自己虽然经常浏览 GitHub对实际协作流程却很陌生Git 和 GitHub 有什么区别Fork 和 Clone 为什么都像是在复制项目Commit 以后代码是不是已经上传了Pull Request 又是在“拉”谁的代码于是花时间把相关概念和操作过了一遍。参与开源并不是直接修改别人的仓库大部分情况下会经历下面这些步骤找到合适的 Issue ↓ 阅读贡献规范并与维护者确认 ↓ Fork 原仓库到自己的 GitHub 账号 ↓ Clone 自己的 Fork 到本地 ↓ 创建独立分支并修改代码 ↓ 测试、Commit、Push ↓ 向原仓库提交 Pull Request ↓ 根据 Code Review 继续修改 ↓ 维护者合并代码下面记录这次查资料和练习过程中弄清楚的内容也顺便整理一下如何把自己的项目发布到 GitHub。Git 和 GitHub 不是一回事以前我很容易把 Git 和 GitHub 混在一起。实际上它们分别解决不同问题Git 是安装在本地的版本管理工具负责记录文件修改和版本历史。GitHub 是托管 Git 仓库的协作平台提供 Issue、Pull Request、Code Review、Actions 等功能。即使没有 GitHub也可以只用 Git 在本地管理代码。GitHub 则让多人可以围绕同一个 Git 仓库协作。一次修改从电脑走到开源项目大致经过四个位置工作区中的文件 ↓ git add 暂存区 ↓ git commit 本地 Git 仓库 ↓ git push GitHub 远程分支 ↓ Pull Request 请求合并到目标分支我之前最容易混淆的是commit只是在本地保存一个版本只有执行push后提交才会上传到 GitHub。Pull Request 也不是上传代码而是在代码已经上传之后请求项目维护者审查并合并这些提交。GitHub 中几个最容易混淆的概念Repository项目仓库Repository 通常简称 Repo里面不仅有当前代码还包括分支、提交记录和完整修改历史。Clone把远程仓库下载到本地gitclone https://github.com/username/project.gitClone 发生在 GitHub 和本地电脑之间。执行后我会得到一个可以使用 Git 管理的本地项目目录。Fork在自己的 GitHub 账号下复制仓库Fork 发生在 GitHub 平台上。给陌生开源项目贡献时我通常没有权限直接向官方仓库上传代码因此需要先把官方仓库 Fork 到自己的账号下。官方仓库github.com/original-owner/project ↓ Fork 我的仓库github.com/my-name/project我现在会这样区分 Fork 和 CloneFork从别人的 GitHub 仓库复制到我的 GitHub 账号。Clone从 GitHub 下载到我的电脑。Branch独立的开发路线分支让我可以在不影响main的情况下修改代码gitswitch-cfix/login-validation开源贡献通常要求一个 Issue 对应一个分支。这样修改范围清晰后续也容易审查和撤销。Commit一次有说明的版本快照gitaddsrc/login.py tests/test_login.pygitcommit-mfix(auth): validate empty username好的 Commit 应该只完成一个明确目的并且通过提交信息说明改了什么。Pull Request请求合并修改Pull Request 通常简称 PR。它表达的是我在自己的分支完成了这些修改请维护者检查并考虑把它们合并到目标分支。维护者可以在 PR 中查看代码差异、提出修改意见、运行自动化测试最后决定是否合并。Issue先讨论问题再开始写代码Issue 可以用来报告 Bug、提出功能需求、讨论设计或者发布待办任务。对开源贡献者来说Issue 不只是任务列表也是和维护者确认修改范围的地方。如何发布自己的开源项目发布自己的项目相对简单因为仓库属于自己不需要先 Fork。第一步准备基本文件一个适合公开的项目至少应该考虑包含my-project/ ├── README.md ├── LICENSE ├── .gitignore ├── requirements.txt 或 pyproject.toml ├── src/ └── tests/其中README.md说明项目解决什么问题、如何安装和运行。LICENSE明确别人是否可以使用、修改和分发代码。.gitignore排除虚拟环境、缓存、构建产物和本地配置。依赖文件让别人可以复现开发环境。测试用来证明核心功能能够正常运行。开源之前必须检查是否包含敏感信息。下面这些内容不能上传.env API Key 密码和数据库凭据 SSH 私钥 访问令牌 .venv/ __pycache__/如果密钥曾经被提交即使后来删除文件它仍可能留在 Git 历史里。正确处理方式是立即撤销旧密钥、生成新密钥再清理提交历史而不是只删除当前文件。第二步选择开源许可证公开仓库不等于自动授权别人随意使用代码。常见许可证包括MIT限制较少允许使用、修改、分发和商用。Apache-2.0同样比较宽松并包含明确的专利授权条款。GPL-3.0通常要求分发衍生作品时继续使用兼容的开源许可证。具体选择应该根据项目目标判断不能随便复制一个许可证后就不再关注其义务。第三步初始化本地 Git 仓库cdmy-projectgitinitgitadd.gitcommit-mfeat: initial project release第一次使用 Git 时还需要配置提交者身份gitconfig--globaluser.namemy-github-namegitconfig--globaluser.emailmy-emailexample.com如果不想在提交记录中公开私人邮箱可以使用 GitHub 提供的隐私邮箱。第四步在 GitHub 创建远程仓库并上传在 GitHub 创建一个空仓库后将本地仓库与它关联gitremoteaddorigin https://github.com/my-name/my-project.gitgitbranch-Mmaingitpush-uorigin main这里的origin是远程仓库的本地别名。-u会让本地main跟踪远程分支后续通常直接执行git push即可。以后更新项目的基本循环就是gitstatusgitdiffgitaddpath/to/filegitcommit-mfix: correct input validationgitpush将仓库设置成 Public 只是把代码公开。如果希望别人方便地使用和参与后续还可以逐渐补充CONTRIBUTING.md、Issue 模板、行为准则、CI、版本号和 Release。如何给别人的开源项目贡献代码第一步寻找合适的 Issue第一次贡献可以重点寻找这些标签good first issue help wanted documentation tests bug不过不能只看标签还要检查Issue 是否仍然开放。是否已经有 Assignee。评论中是否有人声明正在处理。是否已经存在关联 PR。需求和验收条件是否明确。自己能否在合理时间内复现问题并运行相关测试。对初学者来说文档修正、补充测试、小范围 Bug 和清晰的单文件修改通常比新增大型模块更合适。第二步阅读项目的贡献规范开始修改前应该先阅读README.md CONTRIBUTING.md CODE_OF_CONDUCT.md LICENSE重点确认开发环境怎么安装。分支和 Commit 如何命名。格式化、Lint 和测试命令是什么。PR 标题和描述有什么要求。是否需要先认领 Issue。是否禁止未讨论的大型修改或破坏性 API 变更。每个项目规则不同不能把自己熟悉的流程强行套到所有仓库上。第三步先在 Issue 中沟通对于非小型修改最好先留言说明自己的计划Hi, Id like to work on this issue. My plan is to follow the existing implementation, make the scoped change described above, and add unit tests for the new behavior. Could you confirm whether this approach is acceptable?这样可以避免与其他贡献者重复劳动也能提前发现自己对需求的理解是否有偏差。第四步Fork 并 Clone 仓库在 GitHub 页面点击 Fork 后Clone 的应该是自己的 Forkgitclone https://github.com/my-name/project.gitcdproject然后添加官方仓库作为另一个远程地址gitremoteaddupstream https://github.com/original-owner/project.gitgitremote-v此时两个远程地址的职责是origin → 我的 Fork我通常有 Push 权限 upstream → 官方仓库我用它获取最新代码这是开源贡献中最关键的远程关系。第五步同步官方仓库并创建分支开始新任务前先让本地main跟上官方仓库gitswitch maingitfetch upstreamgitpull upstream maingitpush origin main然后从最新的main创建任务分支gitswitch-cfix/login-validation常见分支名称包括feat/add-slack-channel fix/login-validation docs/update-installation test/add-agent-tests perf/reduce-query-count不要直接在main上开发否则不同任务容易混在一起PR 也更难整理。第六步修改代码并检查差异开发过程中经常执行gitstatusgitdiffgit status告诉我哪些文件发生了变化git diff展示尚未暂存的具体差异。提交前应该逐行检查 Diff确认没有密钥或个人配置。临时调试输出。IDE 自动生成文件。与 Issue 无关的格式化修改。意外删除的代码。第七步运行测试并提交代码具体命令以项目贡献指南为准常见检查包括pytest tests pre-commit run --all-filesJavaScript 或 TypeScript 项目可能使用npmtestnpmrun lintnpmrun build测试通过后精确选择本次需要提交的文件gitaddsrc/login.py tests/test_login.pygitcommit-mfix(auth): validate empty username初学时最好不要不加检查地执行git add .因为它可能把无关文件一起放入提交。第八步Push 分支并创建 Pull Requestgitpush-uorigin fix/login-validation上传完成后在 GitHub 上创建 PR。需要确认比较方向base repository官方仓库 base branchmain head repository我的 Fork compare branch我的任务分支PR 描述可以使用下面的结构## Summary - Validate empty usernames before authentication - Add unit tests for invalid input ## Testing - pytest tests/auth - pre-commit run --all-files Fixes #123Fixes #123表示 PR 合并后自动关闭对应 Issue。提交 PR 前还要检查项目是否要求特定的标题格式例如 Conventional Commitsfix(auth): validate empty username第九步处理 Code Review维护者提出修改意见并不代表贡献失败。Code Review 本来就是协作的一部分。只需要继续在原分支上修改、测试和提交gitaddpath/to/filegitcommit-mtest(auth): cover whitespace-only usernamesgitpush新的 Commit 会自动出现在原 PR 中不需要重新创建 PR。如果不理解某条意见可以先说明自己的理解并询问维护者不应该在没有弄清需求时盲目改代码。第十步PR 合并后清理分支确认代码已经合并后可以同步官方main并清理任务分支gitswitch maingitpull upstream maingitbranch-dfix/login-validationgitpush origin--deletefix/login-validation删除任务分支不会删除已经合并到main的代码。Fork 模式和团队分支模式有什么区别给陌生开源项目贡献时通常使用 Fork官方仓库 main ↑ Pull Request 我的 Fork / fix-branch如果我是团队成员已经拥有官方仓库的写权限通常不需要 Fork官方仓库 main ↑ Pull Request 官方仓库 fix-branch两种方式的共同点是都通过独立分支和 PR 协作而不是直接向main提交代码。初学者最容易犯的错误Commit 后以为代码已经上传Commit 只保存在本地还需要执行git push。把 Fork 和 Clone 当成同一件事Fork 是 GitHub 到 GitHubClone 是 GitHub 到本地电脑。直接在 main 分支开发应该让每个 Issue 拥有独立分支保持修改范围清晰。忘记配置 upstream没有upstream也能提交第一次 PR但以后很难方便地同步官方仓库。PR 混入无关修改修一个 Bug 时顺便格式化整个项目会让维护者难以确认真正的修改内容。一个 PR 应该只解决一个问题。没沟通就实现大型功能维护者可能不同意设计方向或者同一功能已经有人开发。大型修改应该先通过 Issue 讨论。只写代码不补测试和文档新增行为通常需要测试影响用户使用方式时也应该同步更新文档。看到 Request changes 就认为被拒绝PR 审查本来就是协作过程的一部分。收到意见后需要弄清楚问题、验证修改并保持正常沟通。我准备怎么开始第一次贡献现在直接挑战核心框架的大功能并不现实。我准备按照下面的顺序开始先创建一个自己的练习仓库完整走一遍 Branch、Commit、Push、PR 和 Merge。找带有good first issue或help wanted标签的小任务。优先考虑文档、测试和修改范围明确的小 Bug。先复现问题并读懂相关代码再在 Issue 中说明实现计划。保持一个 Issue、一个分支、一个聚焦的 PR。提交前逐行检查 Diff并运行项目要求的测试。认真处理维护者的 Review而不是只追求“提交过 PR”。对我来说有价值的开源经历不只是 GitHub 主页上多一条记录还应该能说明发现了什么问题、如何定位、为什么这样修改、写了哪些测试以及怎样和维护者完成协作。常用命令速查发布自己的项目gitinitgitadd.gitcommit-mfeat: initial project releasegitremoteaddorigin https://github.com/my-name/my-project.gitgitbranch-Mmaingitpush-uorigin main第一次贡献开源项目gitclone https://github.com/my-name/project.gitcdprojectgitremoteaddupstream https://github.com/original-owner/project.gitgitswitch maingitfetch upstreamgitpull upstream maingitswitch-cfix/my-change# 修改并测试代码gitstatusgitdiffgitaddpath/to/filegitcommit-mfix(scope): describe the changegitpush-uorigin fix/my-changePR 合并后gitswitch maingitpull upstream maingitbranch-dfix/my-changegitpush origin--deletefix/my-change今日总结这次主要理清了发布个人项目和参与开源贡献的两套流程。发布自己的项目是把本地仓库通过origin上传到自己的 GitHub 仓库给别人的项目贡献则多了 Fork、upstream和 Pull Request 这几层协作关系。整个过程中Git 负责版本记录GitHub 负责远程托管和团队协作。Branch 隔离修改Commit 保存本地版本Push 上传远程分支Pull Request 请求维护者审查和合并。命令本身不算复杂更容易忽略的是协作习惯先读规则、先沟通、控制修改范围、补充测试、检查 Diff并认真回应 Code Review。把这些步骤走一遍之后再看开源贡献就具体多了。接下来准备先用自己的练习仓库走一遍流程再选择一个边界清晰、无人认领的小 Issue 动手尝试。
返回列表