【无标题】

新手也能看懂的 Git 功能开发流程:从需求到 Pull Request

很多 Git 问题并不是命令不会用,而是开发顺序错了。

例如,打开项目后直接在 main 分支写代码,写到一半才想起来创建分支,就容易遇到:

  • 不同功能混在一起
  • 不知道哪些文件应该提交
  • 切换分支时担心代码丢失
  • PR 中出现无关文件
  • 测试功能和未确认功能无法分开

本文不重点讲 Git 命令,而是讲清楚一次功能开发应该按照什么顺序进行。


一、先理解 main 分支是做什么的

可以把 main 理解为项目当前稳定版本。

正常情况下,main 中应该保存:

  • 已经开发完成的功能
  • 已经测试通过的代码
  • 已经审核通过的修改
  • 可以继续部署或发布的版本

因此,不建议直接在 main 上开发新功能。

正确思路是:

text 复制代码
main 保存稳定代码
功能分支负责开发
功能完成后通过 PR 合并回 main

二、写代码之前,第一件事是创建功能分支

这是整个流程中最重要的一步。

不要先写代码,再创建分支。

正确顺序:

text 复制代码
更新 main
→ 从 main 创建功能分支
→ 在功能分支中写代码

例如,这次开发的是"测试环境标识",分支可以命名为:

text 复制代码
feature/console-environment-guard

参考命令:

bash 复制代码
git switch main
git pull --ff-only origin main
git switch -c feature/console-environment-guard

开始写代码前,可以检查当前分支:

bash 复制代码
git branch --show-current

如果显示 main,先不要写代码。


三、一个分支尽量只做一个明确需求

假设当前有三个需求:

text 复制代码
测试环境标识
返回顶部按钮
项目表头吸顶

如果三个功能都写在同一个分支里,后面可能出现:

  • 前两个已经测试通过
  • 第三个还不确定
  • 但三个功能修改了同一个 globals.css
  • 最后不知道应该提交哪些代码

更合理的方式是拆分:

text 复制代码
feature/console-environment-guard
feature/back-to-top-control
feature/project-list-sticky-header

如果两个功能关联紧密,也可以放在一个分支,但必须提前确认边界。

核心原则:

text 复制代码
一个分支只解决一个明确目标
未确认的功能不要混进当前分支

四、写代码前先把需求想清楚

不要一上来就修改代码。

至少先明确以下内容:

  • 为什么要修改
  • 用户最终会看到什么
  • 哪些页面会受到影响
  • 哪些文件可能需要修改
  • 是否涉及后端或数据库
  • 如何判断功能已经完成
  • 哪些内容暂时不做

如果项目使用 OpenSpec,可以保存:

text 复制代码
proposal.md:为什么修改
design.md:准备怎么实现
spec.md:功能应该满足什么行为
tasks.md:具体实施步骤

如果只是保存方案、暂时不开发,tasks.md 应保持未完成状态:

text 复制代码
- [ ] 待实施任务

这样以后不会误以为代码已经完成。


五、开发过程中不要把所有样式都塞进 globals.css

globals.css 适合放:

  • 全局变量
  • Reset 样式
  • 页面通用基础规则

具体功能的样式最好放在自己的文件中,例如:

text 复制代码
console-environment-guard.tsx
environment-guard.module.css

Monorepo 项目也可以建立共享样式包:

text 复制代码
libs/frontend/console-styles

这样做的好处是:

  • 一个功能对应一组文件
  • 提交时容易区分
  • 删除功能时不影响其他页面
  • 不容易把未确认功能一起提交
  • 服务器构建时依赖关系更清楚

六、开发完成后,先测试,再提交

不要代码刚写完就 Push。

建议先做:

text 复制代码
检查页面效果
→ 检查 TypeScript
→ 执行生产构建
→ 确认没有混入其他功能
→ 再 Commit

参考命令:

bash 复制代码
pnpm install --frozen-lockfile
pnpm --filter @nova-console/web build

生产构建能够提前发现:

  • 文件漏传
  • TypeScript 类型错误
  • Workspace 依赖缺失
  • CSS Module 导入错误
  • Next.js 路由错误

本地能打开页面,不代表生产构建一定能通过。


七、Commit 前要检查"这次到底提交什么"

Commit 不是把所有修改一次性塞进去。

提交前应该确认:

text 复制代码
哪些文件属于当前功能
哪些文件属于其他功能
哪些文件只是本地配置
哪些内容暂时不能提交

尤其不要看到很多文件后直接"全选"。

可以检查:

bash 复制代码
git status --short
git diff

需要按代码块选择时,可以使用:

bash 复制代码
git add -p

提交信息应说明这次做了什么:

bash 复制代码
git commit -m "feat(console): 支持测试环境标识和返回顶部控件"

常见前缀:

text 复制代码
feat:新增功能
fix:修复问题
refactor:代码重构
docs:文档修改
test:测试修改
chore:依赖、脚本或配置维护

八、没有 Commit 的代码,不真正属于任何分支

这是很容易误解的地方。

文件可能有三种状态:

text 复制代码
未追踪
已追踪但未提交
已经 Commit

即使文件已经被 Git 追踪,只要没有 Commit,它就没有真正进入分支历史。

切换分支时,未提交修改可能:

  • 被带到其他分支
  • 阻止分支切换
  • 与目标分支发生冲突
  • 在强制签出或还原时被覆盖

因此,准备切分支或合并代码前,应先处理工作区。


九、不想提交的代码,可以先 Stash

有些修改需要保留,但不应该进入当前功能分支。

这时可以使用 Stash。

Stash 的作用是:

text 复制代码
临时保存未提交内容
→ 暂时清空工作区
→ 完成切分支或合并
→ 再恢复原来的内容

参考命令:

bash 复制代码
git stash push -u -m "wip before merge main"

其中 -u 表示连未追踪的新文件一起保存。

检查工作区:

bash 复制代码
git status --short

没有输出,才表示工作区已经干净。

恢复:

bash 复制代码
git stash pop

需要注意:

  • Stash 不会上传 GitHub
  • Stash 不属于正式版本历史
  • Stash 适合临时保存
  • 长期内容应放到独立分支并 Commit

十、开发期间 main 更新了怎么办

开发功能时,其他人可能已经向 main 合并了新代码。

这时不要直接把旧功能分支推上去。

正确做法:

text 复制代码
先保存当前修改
→ 获取最新 main
→ 把 main 合并进功能分支
→ 重新测试

参考命令:

bash 复制代码
git fetch origin
git merge origin/main

也可以使用 Rebase:

bash 复制代码
git rebase origin/main

简单理解:

  • Merge:保留合并记录,比较直观
  • Rebase:提交历史更整洁
  • 已经多人使用的分支,Merge 更稳妥
  • 个人且尚未推送的分支,可以考虑 Rebase

合并成功后,要重新构建,因为 main 的变化可能影响当前功能。


十一、Push 的是功能分支,不是 main

功能开发完成后,推送功能分支:

bash 复制代码
git push -u origin feature/console-environment-guard

不要写成:

bash 复制代码
git push origin main

如果 IDEA 同时管理多个 Git 仓库,例如:

text 复制代码
nova-console
nova-common
nova-db

Push 时只勾选本次需要推送的仓库。

不要因为它们同时出现在 Push 窗口,就全部推送。


十二、Push 完成后创建 PR

Push 只是把功能分支上传到 GitHub,还不是 PR。

PR 的作用是:

text 复制代码
申请把功能分支合并到 main

GitHub 中进入:

text 复制代码
Pull requests
→ New pull request

选择:

text 复制代码
base: main
compare: feature/console-environment-guard

其中:

  • base 是准备合并到哪个分支
  • compare 是当前功能分支

PR 标题示例:

text 复制代码
feat(console): 支持测试环境标识和返回顶部控件

PR 描述应该写清楚:

markdown 复制代码
## Changes

- 增加测试环境视觉标识
- 增加返回顶部控件
- 增加共享样式包

## Verification

- pnpm install --frozen-lockfile
- pnpm --filter @nova-console/web build

十三、创建 PR 后还不能立刻合并

PR 创建后,GitHub 可能执行自动检查:

text 复制代码
TypeScript 检查
构建检查
单元测试
代码规范检查

如果页面显示:

text 复制代码
Waiting for status to be reported

表示检查还没有完成。

需要等待:

text 复制代码
All checks have passed

第一张 PR 列表显示"Open",只代表 PR 已经创建,不代表检查通过。


十四、谁来点击 Merge

是否可以 Merge,取决于:

  • 是否拥有仓库写入权限
  • CI 是否通过
  • 是否存在代码冲突
  • 是否要求其他人审核
  • main 是否配置了分支保护

团队项目中,通常建议:

text 复制代码
开发者创建 PR
→ 其他人审核
→ 维护者或管理员合并

即使自己有权限,也不建议在检查未完成时直接合并。


十五、PR 合并后,本地 main 才会出现新功能

PR 创建以后,本地 main 不会自动拥有功能代码。

只有 PR 真正合并后,再更新本地 main

bash 复制代码
git switch main
git pull --ff-only origin main

这时新功能才正式出现在本地 main

最后可以删除功能分支:

bash 复制代码
git branch -d feature/console-environment-guard

十六、一套推荐的开发顺序

以后开发新功能,可以按照下面的顺序:

text 复制代码
1. 明确需求
2. 更新 main
3. 从 main 创建功能分支
4. 确认当前不在 main
5. 编写功能代码
6. 本地测试和生产构建
7. 检查提交文件
8. Commit
9. 同步最新 main
10. 再次测试
11. Push 功能分支
12. 创建 PR
13. 等待 CI 和审核
14. 合并 PR
15. 更新本地 main

最需要记住的是:

text 复制代码
写功能前先切分支
一个分支只做一个明确需求
未确认功能不要混入当前提交
切分支前处理未提交修改
Push 前构建
PR 前检查 Files changed

Git 命令只是工具,真正重要的是养成正确的开发顺序。

相关推荐
FreeBuf_2 小时前
公开GitHub Issue可诱骗AI泄露私有数据,绕过防护仅需一词
人工智能·github·issue
JavaGuide3 小时前
又一个画图 Skill 开源,再见手动画 draw.io!
前端·后端·github
小弥儿3 小时前
GitHub今日热榜 | 2026-07-09:OfficeCLI 以 92% 日增幅入围
学习·开源·github
逛逛GitHub4 小时前
GitHub 上 5 个小众但实用的开源项目,感兴趣收藏一波。
github
逛逛GitHub4 小时前
4 个最近值得收藏的 GitHub 开源项目。
github
粤M温同学6 小时前
VS Code GitHub Copilot插件中配置 DeepSeek 模型
github·copilot
AC赳赳老秦7 小时前
传感器数据自动汇总:OpenClaw 采集多类传感器数据、清洗入库、生成趋势分析
java·人工智能·python·自动化·github·php·openclaw
csdn_aspnet8 小时前
开源项目在GitHub上的破圈方法论,解析Star增长、Issue响应、Contributor引导等真实运营技巧
开源·github·issue·readme·star
uhakadotcom9 小时前
Scrapy-Redis 里面提供哪些即开即用的功能能力模块
前端·面试·github