Git 在正常开发流程中的正确用法
前言
上一篇把 git 的基本命令都过了一遍,但「会用命令」和「用对流程」是两回事。实际开发里,很多人 git 用得混乱:直接在 main 上改、提交信息写 fix、合并时一团乱麻。这篇文章记录一下我在正常开发流程中会遵循的做法,从分支策略到提交规范、再到合并与同步,把「怎么算用得对」讲清楚。
文章假设读者已经会
init/add/commit/push/pull这些基础命令,这里只讲「怎么用对」。
示例以main为主分支,团队习惯叫master的话请自行替换。
分支策略
为什么不能直接在 main 上改
main 是「随时可以发布」的状态。如果直接在 main 上开发,一旦改坏,仓库就处于不可用状态,而且很难定位是哪次改动引起的。正确做法是:
main只接收「合并过、验证过」的代码,所有开发都在功能分支上进行。
分支命名规范
分支名应该能一眼看出在做什么,建议用前缀区分类型:
| 前缀 | 用途 | 示例 |
|---|---|---|
feat/ |
新功能 | feat/login-page |
fix/ |
修 bug | fix/null-pointer |
docs/ |
文档 | docs/readme |
refactor/ |
重构 | refactor/auth-module |
chore/ |
杂项 | chore/update-deps |
hotfix/ |
线上紧急修复 | hotfix/payment |
命名用短横线
-连接,不用下划线或空格。名字要短但能表意,feat/user-login-v2比feat/x好。
标准开发流程
1 | 1. 从 main 切出功能分支 |
提交规范
提交信息的格式
提交信息是项目的「历史档案」,写清楚能省掉大量沟通。推荐 type(scope): description 的格式:
1 | type(scope): 简短描述 |
type:见上一节的分支前缀(feat/fix/docs等)scope:改动的模块,可省略,如api/ui/dbdescription:一句话说清做了什么,用祈使句,不加句号
好的提交 vs 坏的提交
1 | # 坏:信息量约等于零 |
原子提交
一次提交只做一件事。 不要把「改 bug」和「重构另一个模块」混在一次提交里。
这样做的好处:
git log/git blame时能精确定位改动来源- 出问题时
git revert能干净地撤销单个功能 - 代码审查时每个提交都易于理解
如果一次改了很多,可以拆成多个 commit:
1 | git add src/login.js |
合并策略:merge vs rebase
两者的区别
| 操作 | 效果 | 适用场景 |
|---|---|---|
merge |
保留完整的分支历史,产生一个合并提交 | 多人协作的分支 |
rebase |
把提交「搬」到另一个分支的顶端,历史线性 | 个人分支整理历史 |
何时用 rebase
功能分支开发过程中,main 可能已经前进了。合并前先把分支同步到最新的 main:
1 | # 在功能分支上 |
这样你的功能分支就基于最新的 main,历史干净。
何时用 merge
合并回 main 时,用 merge,保留分支拓扑:
1 | # 在 main 上 |
铁律:永远不要 rebase 已经推送到共享分支的提交。
rebase会改写提交历史(生成新的 commit id),如果别人也拉了同一个分支,会严重冲突。只 rebase 自己本地还没推送的提交。
解决 rebase 冲突
1 | git rebase origin/main |
同步与推送
推送前保持分支最新
推送前先同步远程,避免被拒绝:
1 | git fetch origin |
处理 non-fast-forward
推送被拒绝(rejected, non-fast-forward)通常意味着远程分支有你本地没有的提交。两种处理方式:
1 | # 方式一:先合并远程 |
个人分支推荐
--rebase,团队共享分支推荐--no-rebase(merge)。
同步本地 main
main 是共享分支,永远用 merge 同步,不要 rebase:
1 | git checkout main |
代码审查(PR/MR)流程
- 功能分支推送后,在 GitHub/GitLab 发起 Pull Request
- 填写 PR 描述:做了什么、为什么、怎么测试的
- 关联相关的 issue(
Closes #123) - 等待 review,根据反馈修改并
push追加提交 - review 通过,由维护者合并
PR 描述写清楚「为什么这么改」比代码本身更重要,能让 reviewer 快速理解意图。
常用辅助命令
查看分支状态
1 | git log --oneline --graph --all # 全部分支的提交图 |
找回丢失的工作
1 | git reflog # 查看所有 HEAD 移动记录 |
reflog是救命命令,reset丢掉的提交都能在这里找回来。
清理远程分支
1 | git fetch --prune # 删除本地已不存在的远程分支引用 |
常见问题
功能分支和 main 分叉太远怎么办?
定期 rebase 到最新 main,不要等分叉太大再处理。可以养成习惯:
1 | # 每天开始/结束开发前 |
合并后发现有遗漏,怎么补?
在功能分支上补提交,再次发起合并(如果 PR 还没关)。不要在 main 上直接补,保持「main 只接受合并」的原则。
如何在合并前预览改动?
1 | git diff main..feat/login-page # 查看功能分支相对 main 的所有改动 |
小结
正常开发流程的核心就几条:
main只接受验证过的合并,开发都在功能分支- 分支名带类型前缀,能一眼看出用途
- 提交原子化,一次提交只做一件事,信息用
type(scope): 描述 - 个人分支 rebase 整理,合并回 main 用 merge
main同步永远用 merge,不要 rebase 共享分支reflog是救命命令,丢了提交先找它
这套流程的关键不是命令,而是「保持 main 干净 + 提交有粒度 + 不 rebase 共享历史」这三条原则。把这几条守住,git 用起来就顺手了。
注:本篇文章大部分由 AI 生成。

