
接手新项目第一天最容易被忽略却又最能看出基本功的往往不是代码本身而是你的 Git 提交记录。我翻过太多仓库的 git log一眼就能从提交信息里看出这个人的开发习惯有人一条提交塞了十几个文件的改动有人直接写“update”还有人把调试代码、临时文件跟着功能一起推上远程。今天这篇就是给团队新同学的 Git 协作提交规范示例把“怎么写提交信息”“按什么流程提交代码”“遇到冲突怎么处理”这些事一次讲透以后不要随便乱写了。这篇内容适合刚入职或者刚加入一个协作项目的同学也适合那些自己写了好几年代码但从未认真整理过 commit 历史的开发者。我会从提交信息格式、分支命名、日常提交流程、常见问题排查四个部分展开全程结合真实场景和具体命令你可以直接照着用。1. 提交信息规范让 git log 变成项目文档提交信息写得好不好短期内看不出差别但三个月后回看历史或者线上出了故障需要回滚代码时好的提交信息能让你五分钟定位问题烂的提交信息会让你恨不得把键盘砸了。1.1 提交信息的标准格式type(scope): subject团队协作中最推荐的提交信息格式是 Conventional Commits 规范一句话概括就是type(scope): subject其中 type 是必填的scope 是可选但建议填的subject 是必填的提交描述。这个格式看起来简单但每个部分都有讲究下面拆开细说。type 表示这次提交的类型常用的有feat新增功能fix修复缺陷docs只改文档style不影响代码逻辑的格式调整比如空格、分号refactor重构既不修 bug 也不加功能perf性能优化test补充测试build构建系统或外部依赖的改动ciCI 配置或脚本改动chore其他杂项比如改 .gitignore、调整配置文件scope 表示影响范围可以是模块名、组件名、功能名比如 feat(user-center): 增加用户注册接口。scope 的作用是让提交记录可以按模块检索我见过一个后端项目全仓库几十个模块scope 填清楚之后查“订单模块的改动”只需要一行命令git log --oneline --grepordersubject 是提交的简要描述用一句话说清楚“这次提交做了什么”。注意这里有几个硬性要求用祈使句动词开头比如“增加注册接口”而不是“增加了注册接口”或“注册接口功能完成”不超过 50 个字符超长的描述放到 body 里写结尾不要加句号用中文还是英文看团队习惯但一定要统一1.2 什么时候该拆提交什么时候该合并提交新手最容易犯的毛病是两种极端一种是一条提交把所有改动全塞进去另一种是改一行存一次提交信息全写“update”。正确的做法是按逻辑单元拆分每个提交只做一件完整的事。判断标准其实很简单如果这个提交需要回滚你会不会连带把不相干的东西也回滚掉如果答案是“会”那说明这个提交拆得不够细。比如这次你同时改了登录接口和首页轮播图如果登录接口出了问题要回滚首页的改动不应该被一起带走那就应该拆成两个提交。反过来如果为了修一个 bug 反复改了同一个文件若干次中途还有临时调试代码那在最终提交前应该把调试代码清理掉把同一个小需求的多次改动合并成一个语义清晰的提交。这个操作我在第四节会详细讲。1.3 用规范的提交信息自动生成 changelog很多团队写提交规范不只是为了好看还为了后续自动化。Conventional Commits 配合工具可以直接生成 changelog甚至自动判断版本号是 major、minor 还是 patch。比如 commit 里出现了feat版本号的 minor 位自动加一出现了BREAKING CHANGEmajor 位自动加一。这里的关键是提交信息必须机器可读所以 type 不能自己随意发明fix就是fix写成fixed或bugfix后续工具就不认了。团队里如果用了这套规范大家私自发明的 type 会导致自动化流程错乱。2. 从拉代码到推远程的规范操作流程提交信息写得好只是第一步。Git 协作里真正容易出问题的是操作流程。我见过太多新同学一上来就在主干分支上开发或者从来不拉最新代码等到提交时发现冲突已经积了十几个文件整个人都懵了。这一节直接给你一套标准操作照着做不会出错。2.1 开发前先同步fetch 和 pull 的区别很多新手直接用git pull这个命令本身没问题但你要清楚它背后是两个动作的合并git fetch加git merge。fetch 只会把远程的更新拉取到本地仓库但不会改动你当前的工作区而 pull 会直接把远程的改动合并到当前分支。建议养成先 fetch 再决定怎么合并的习惯尤其是在多人频繁提交的仓库里git fetch originfetch 之后你可以用git log origin/main看看远程分支领先本地多少再决定是直接 pull 还是需要先处理本地改动。这样做的意义在于pull 是带副作用的操作它可能直接产生合并冲突而 fetch 是无副作用的任何时候执行都安全。2.2 本地改动还没提交怎么办stash 的正确用法场景你正在新功能分支上开发改到一半同事告诉你主干上有紧急修复要你马上切换到主干分支。此时工作区有一堆改了一半的文件直接切换分支会报错。正确操作是把当前改动先暂存起来git stash push -m 用户中心功能开发中尚未完成切到主干分支处理完紧急修复后再回到原来的分支恢复改动git stash pop注意 stash pop 有可能会产生冲突如果冲突了就手动解决。这个操作比提交一个带有“开发中”标记的半成品 commit 要干净得多。2.3 提交的顺序和粒度add、commit、pull、push 的正确姿势我推荐的提交顺序是git add file1 file2 git commit -m feat(user): 增加用户注销功能 git pull --rebase origin main git push origin feat-user-logout先说 add。.gitignore的重要性怎么强调都不为过node_modules、.idea、target 这类目录和编译产物永远不该进版本库。建议 clone 项目后第一时间检查 .gitignore 是否已经把当前语言的产物目录都排除了没有就趁早补上否则后面每次提交都在和它较劲。然后说 commit。我特别强调“不要用git add .一把梭”这在多人协作里真的会造成事故。我踩过一次坑是改功能的时候不小心动了配置文件然后git add .把本地环境的配置一起提交上去了结果同事 pull 下来之后直接把他的本地配置覆盖了。正确做法是提交前用git status看清楚改了哪些文件逐个 add必要时用git add -p分块暂存只把属于本次提交的改动加进去。再说 pull 的顺序。为什么要在 commit 之后才 pull因为 pull 可能会产生冲突如果你自己的改动还没提交冲突解决起来会把你的工作区搅得一团糟。所以先把改动固化成一个 commit再拉取远程变更是更安全的顺序。最后说 push。push 之前一定要确认当前分支不是主干分支我见过不少新同学直接把改动的代码推到了主干上轻则被组长说一顿重则直接导致主干分支乱掉。后面会专门讲分支保护。2.4 提交信息写错了怎么办amend 和 reset 的取舍场景提交完之后发现信息里有错别字或者少写了文件。如果这个提交还没推送到远程可以用 amend 修复git commit --amend -m feat(user): 增加用户注销功能补充单元测试amend 会替换最近一次提交相当于把上一次提交的信息和内容都改了。但这里有个坑如果你已经把提交推到了远程就不要再用 amend 了因为远程的提交和本地的提交历史会分叉你自己 push 时会被拒绝强行 force push 还会影响同事的提交记录。此时应该通过新增一个提交去修正git commit -m fix(user): 修正注销接口的返回状态码如果是提交完发现多提交了文件或者把当前提交撤回重新整理我强烈建议用git reset --soft而不是git reset --hardgit reset --soft HEAD~1--soft只撤销提交记录但保留工作区的改动。--hard会把改动也一起丢掉新手拿来即用容易丢代码真要用--hard前一定要先确认改动已经被备份或者真的不需要了。3. 分支命名与合并规范主干永远保持可发布提交信息管的是“每一次提交长什么样”分支规范管的是“代码从哪来到哪去”。这两件事配合起来才能让团队协作的秩序真正建立起来。3.1 分支命名规则主分支一般叫 main 或 master这是用于发布的分支永远保持可运行状态。开发分支一般叫 develop日常集成都在这里。新功能开发时从 develop 切出功能分支命名规则如下feature/项目代号-功能描述 fix/项目代号-缺陷描述 docs/项目代号-文档说明 refactor/项目代号-重构内容举例来说一个用户中心模块的登录功能改造分支名可以是feature/user-001-login-redesign。这个命名看起来繁琐但它解决了两个关键问题第一通过分支名前缀就能判断这是干什么的第二带上项目代号或 issue 编号可以追踪这个分支的代码对应哪个需求或工单。我自己确认过国内不少团队习惯直接用dev_张三、test_李四这种以人名命名的分支。这种方式的缺点是三个月后大家看到dev_zhangsan根本不知道这个分支对应什么需求而且人员离职后这种分支就成了历史遗留。规范的命名是成本极低但收益极高的事。3.2 保护主干分支禁止直接推主干在协作项目中主干分支应该开启保护。保护规则一般包括禁止直接推送到主干只能通过 Pull Request或 Merge Request合并代码PR 必须经过至少一个 reviewer 的审批PR 必须通过 CI 检查。GitLab 和 GitHub 都支持在项目设置里配置这些规则。团队里如果没有保护新人很容易一上来就直接往主干推。别问我怎么知道的我见过太多人因为这一步没做好把调试代码、半成品功能、别人的合并冲突全带进了主干。3.3 合并策略merge 和 rebase 怎么选这是 Git 协作里争议最大的话题之一。合并分支有两种方式# 方式一生成一个 merge commit git checkout develop git merge feature-user-001-login-redesign # 方式二reviewer 选择 rebase 后合并 git checkout feature-user-001-login-redesign git rebase develop git checkout develop git merge feature-user-001-login-redesign方式一的优点是历史完整保留了分支合并的记录缺点是 log 里会出现很多 merge commit看起来比较乱。方式二把功能分支的提交线性地重放到 develop 之上log 是一条直线非常干净但一旦冲突多且频繁rebase 会让人很痛苦。我的建议是对于多人共享的长期分支用 merge 方式避免 rebase 对其他人造成影响对于个人功能分支合并前可以先 rebase 一下 develop让提交历史更整洁。但这个事情团队内部一定要统一最怕的是有人用 merge 有人用 rebase最终 log 既不是纯线性也不保留完整拓扑两头不讨好。4. 常见问题排查与避坑实录这一节是我最想让新同学保存的部分。下面这些坑我基本都踩过或者亲眼看着别人踩过每个场景都附上了排查思路和解决命令。4.1 提交信息写错了、内容漏了、文件多了场景一提交完发现git commit -m feat(user): 增加登录接口写错了应该是“增加注销接口”而且这个提交还没 push。解法git commit --amend -m feat(user): 增加注销接口场景二提交时把临时文件debug.log一起 add 进去了同样没 push。先把文件从暂存区移除再修正提交git reset HEAD debug.log echo debug.log .gitignore git commit --amend场景三提交后发现上一次提交少加了一个文件且已经 push 了。不要 amend直接补一个提交git add missing-file.js git commit -m chore(user): 补充遗漏的配置项 git push4.2 push 被拒绝远程有别人提交的新代码报错信息大概是! [rejected] ... (fetch first)意思是远程分支有你本地没有的提交。此时如果直接 pull会产生一个 merge commit看着不干净更推荐用 rebase 方式git pull --rebase origin main git push origin mainrebase 会把本地的新提交先暂存起来拉到远程最新的提交后再把自己的提交重放到最上面。如果冲突了Git 会提示冲突文件手动解决后执行git add 解决完的文件 git rebase --continue这里要告诫一句git pull --rebase过程中如果不想解决了需要终止 rebase 恢复原状执行git rebase --abort。千万别直接git push --force那是极其危险的动作会把别人的提交直接从远程抹掉。4.3 误提交了敏感信息密码、密钥进了仓库这是最紧急的情况因为提交一旦推送到远程就相当于公开了。如果只是刚提交还没 push直接把敏感信息从文件里删掉再git add、git commit --amend即可。如果已经 push那就麻烦一些。删掉文件、提交、推送只是让最新代码里不包含敏感信息但历史记录里仍然存在。涉及敏感信息且项目是私有的建议团队紧急处理 Git 历史重写如果是公开仓库还需要去平台侧申请删除。这是严重事故一定要尽量避免。预防措施是在本地配置提交前检查钩子或者使用专业的敏感信息扫描工具提前发现。4.4 合并冲突不知道怎么解决冲突的本质是两个人改了同一个文件的同一段代码Git 不知道怎么自动合并。当冲突发生时Git 会在文件里插入这样的标记 HEAD 你本地分支的内容 对方分支的内容 feature-xxx解决步骤打开冲突文件手动选择保留哪部分内容或者把两边内容都保留并做融合删掉、、这些标记行执行git add 文件标记为已解决继续合并操作merge 就执行git merge --continuerebase 就执行git rebase --continue如果冲突一时半会儿解决不了先执行git merge --abort或git rebase --abort恢复原状不阻塞别人我认为最值得记住的一点是冲突不可怕可怕的是在冲突时乱操作导致代码丢失。任何不确定的情况先git status看清楚当前状态再决定下一步。4.5 git 命令无法识别新同学换了电脑第一次用 Git 时经常遇到git 不是内部或外部命令或者git: command not found这其实是 Git 还没安装或者没加入系统环境变量。我的建议是去 Git 官网下载对应操作系统的安装包安装时保留默认选项装完重启终端再执行git --version验证。这个问题看起来基础但在群里天天都有人问。5. 一些团队协作中不太有人明说但很重要的习惯写完上面这些操作规范还有几个心态和习惯层面的问题想聊聊。这些不算硬性规则但我觉得它们对团队协作效率的影响很大。第一提交尽量小而完整。所谓小而完整是指每个提交要能独立理解、独立回滚。如果一次提交涉及三个功能点后续定位问题时就必须逐个排查这是效率杀手。第二Code Review 的时候reviewer 正常情况下会一段一段地看你的 diff提交信息是理解你改动意图的第一线索。提交信息写得模糊reviewer 就得靠猜猜测的效率和质量都低。我的经验是提交信息多花一分钟review 阶段能省别人好几分钟这件事是共赢的。第三分支合并后要及时清理。功能分支合并进 develop 之后对应的远程分支和本地分支都可以删掉了git push origin --delete feature-user-001-login-redesign git branch -d feature-user-001-login-redesign一个仓库里堆积几十个已经合并过的残留分支会让所有人 selector 切换分支时都变得困惑。这个习惯花两秒钟收益是每次打开分支列表都是干净、可读的。第四遇到不熟悉的 Git 命令时用git help 命令查文档比去网上复制粘贴命令更靠谱。git help commit、git help rebase都会打开官方文档里面有很多细节在零散的中文教程里根本没提到。我个人现在维护的团队项目已经全面启用提交规范与分支保护新同学入职的第一天会收到一份和上面内容高度相似的文档并且要求动手把一个小功能按照这套流程完整走一遍从创建分支到提交、提 PR、合并全程有人指导。实践证明这样带出来的新同学即使在协作节奏非常快的项目里也很少给团队制造 Git 相关的事故遇到的多数问题都能对照规范自己解决掉。这套规范并不复杂但它要求的不是“知道”而是“每次都做到”真正形成肌肉记忆之后你就再也不会随便乱写了。