前言
上一篇文章Git基础使用教程写了Git的基础命令,比如add、commit、branch、merge、rebase这些东西。
这篇主要记录多人协作时最常见的一套流程。
重点不是讲很多高级命令,而是搞清楚一件事:
一个功能从开始开发,到最后合并进主分支,中间到底经过哪些步骤。如果只是自己一个人写代码,可能本地改完、提交、推送就结束了。但多人一起改同一个项目时,就不能每个人都直接往主分支上推代码了,不然很容易互相覆盖、互相冲突,最后谁也不知道主分支到底还能不能正常运行。
为什么不要直接改main
main或者以前常见的master,一般代表项目当前比较稳定的代码。
比如一个网站项目,main分支上的代码可能会直接部署到线上;一个后端项目,main分支可能就是大家默认拉取和测试的版本。
如果所有人都直接在main上开发,会出现几个问题:
- 代码还没写完就被别人拉到了
- 一个半成品功能影响其他人开发
- 出了问题很难判断是哪次修改引起的
- 没有机会让别人提前检查代码
所以多人协作时,更常见的做法是:
main 保持稳定每个人在自己的分支上开发写完后通过 Pull Request 合并回 main这样主分支不会被随便改动,每个功能也有比较清楚的开发和检查过程。
常见协作流程
平时协作大概可以按这条线走:
更新主分支↓创建功能分支↓开发并提交↓推送到远程↓创建 Pull Request↓代码检查 / Review↓合并到 main↓删除功能分支看起来步骤不少,但实际熟悉之后就是一套固定动作。
简单说,就是不要把代码直接写到main,而是先从最新的main拉出一个自己的功能分支。功能写完以后,把这个分支推送到远程仓库,再创建一个Pull Request,让别人看一下改了什么,确认没问题后再合并。
开发前先更新主分支
开始写新功能前,先切回main,把远程最新代码拉下来。
git switch maingit pull这一步是为了保证自己的新分支是从最新代码上分出来的。
如果你本地的main已经落后远程很多,直接从旧代码上开分支,后面更容易遇到冲突。
创建自己的功能分支
更新完main后,再创建自己的功能分支。
git switch -c feature-login-c表示创建并切换到这个新分支。
分支名最好能看出来这个分支是干什么的,不要随便叫test、aaa、new这种名字。
常见命名方式:
feature/loginfix/login-errordocs/update-readme大概可以这样理解:
feature/xxx:开发新功能fix/xxx:修复问题docs/xxx:修改文档
团队里如果有固定命名规范,就按团队规范来。没有规范时,至少保证别人能从分支名看懂大概用途。
在分支上开发和提交
切到功能分支后,就可以正常改代码了。
改完一部分后,可以先看状态:
git status确认这次要提交哪些文件:
git add .git commit -m "添加登录页面"这里还是建议养成几个习惯:
- 提交前先看
git status - 一个提交尽量只做一件事
- 不要把临时文件、测试文件、编译产物误提交上去
- 提交说明不要只写
update
比如下面这种提交说明就比较难看懂:
git commit -m "update"过几天再看日志,根本不知道这个update到底更新了什么。
可以写得具体一点:
git commit -m "添加登录页面"git commit -m "修复登录失败提示"git commit -m "更新登录接口地址"提交说明不一定要特别长,但至少要让人知道这次提交主要做了什么。
推送分支到远程
本地提交完成后,需要把自己的功能分支推送到远程仓库。
第一次推送这个分支时,一般这样写:
git push -u origin feature-login这里的-u是设置上游分支。设置之后,以后在这个分支上再推送,就可以直接:
git push如果分支名是feature/login,命令就是:
git push -u origin feature/login推送成功后,远程仓库里就能看到这个分支了,接下来就可以创建Pull Request。
创建Pull Request
Pull Request可以简单理解成:
我这个分支写好了,请帮我看一下,没问题就合并到 main。如果使用的是Gitea,大概流程是:
- 打开仓库页面
- 选择
Pull Requests - 点击
New Pull Request base(左侧的)选择maincompare(右侧的)选择自己的功能分支- 填写标题和说明
- 提交Pull Request

创建PR时,最重要的是确认方向不要选反。
一般应该是:
base: maincompare: feature-login意思是把feature-login分支的修改合并到main。
Pull Request里应该写什么
PR不要只写一个标题就提交。别人Review时,需要快速知道你改了什么、怎么测试、有没有需要注意的地方。
可以按这个模板写:
### 修改内容
- 添加登录页面- 添加登录接口调用- 修改路由配置
### 测试情况
- 本地启动正常- 登录成功和失败都测试过
### 注意事项
- 暂时没有接入验证码如果项目有自动化测试,也可以写测试命令是否通过:
### 测试情况
- pnpm build 通过- pnpm test 通过- 本地手动测试登录成功和失败场景PR说明不用写成作文,但要让别人不打开代码也能先知道这次改动的大概范围。
Code Review是什么
Code Review就是别人帮你看代码。
这不是找茬,也不是为了证明谁水平高,而是为了在代码合并前尽量减少问题。
Review时一般会看这些东西:
- 有没有明显bug
- 代码风格是否统一
- 有没有误提交文件
- 有没有安全问题
- 功能是否符合需求
- 命名和目录位置是否合适
- 有没有影响到其他功能
比如你写登录功能时,不小心把本地测试地址、密码、.env文件提交上去了,自己可能没注意,但Review的人可能一眼就能看出来。
再比如一个功能能跑,但写法和项目里其他地方完全不一样,后面维护的人就会很难受。Review可以提前把这些问题拦下来。
有人改了main怎么办
多人协作时,你开发自己的功能期间,别人可能已经往main合并了新的代码。
这时你的功能分支就落后了。
可以在功能分支上同步最新的main:
git switch feature-logingit fetch origingit rebase origin/main也可以简单一点:
git pull --rebase origin main个人功能分支用rebase通常会比较清爽,因为它会把你的提交放到最新的main后面,历史看起来更像一条直线。
大概可以理解成:
先把 main 的新提交拿过来再把自己的提交重新放到后面不过要注意,rebase更适合自己的功能分支。已经给很多人共同使用的公共分支,不建议随便rebase,否则容易影响别人。
发生冲突怎么办
如果你和别人改了同一个文件的同一部分,就可能出现冲突。
比如执行rebase时提示冲突,可以先看状态:
git status然后打开冲突文件,手动处理里面的冲突内容。处理完成后:
git add 冲突文件git rebase --continue如果冲突太乱,暂时不想继续,也可以取消这次rebase:
git rebase --abort冲突本身不是什么可怕的东西,它只是Git不知道该保留哪一边,需要人来判断。
处理冲突时不要只想着“让文件不报错”,还要确认功能逻辑是不是对的。尤其是两个人同时改了同一个函数、同一个配置文件时,解决完最好重新跑一下项目。
合并Pull Request
PR通过Review后,就可以合并到main。
常见合并方式有几种:
Create merge commitSquash and mergeRebase and merge
Create merge commit会保留分支上的提交记录,并额外生成一个合并提交。小团队、小项目直接用这个也没问题。
Squash and merge会把这个PR里的多个提交压成一个提交再合并。如果你开发过程中提交了很多零碎记录,比如fix、debug、update,用squash可以让main的历史更干净。
Rebase and merge会把功能分支上的提交重新放到main后面,历史也比较直,但对新手来说理解成本稍微高一点。
入门时可以先记一个简单建议:
小项目可以直接merge;想让历史干净,可以squash。
如果团队已经规定了合并方式,就按团队规则来。
合并后删除分支
功能已经合并进main后,原来的功能分支通常就可以删掉了。
远程分支可以在Gitea的PR页面里删除,一般合并后页面会有删除分支的按钮。
本地分支可以这样删:
git switch maingit pullgit branch -d feature-logingit branch -d会删除本地分支。如果Git发现这个分支还没有合并,通常会拒绝删除,避免误删。
如果你用的是feature/login这种分支名,就写:
git branch -d feature/login删分支不是删代码,因为代码已经合并到main里了。删除的是这个开发任务用完后的临时分支。
常见问题
为什么我push到main被拒绝
可能是主分支保护。
很多团队会禁止普通成员直接推送到main,只能通过Pull Request合并。这样可以避免没有Review的代码直接进入主分支。
遇到这种情况,不要强行改权限,应该新建功能分支,再通过PR提交。
为什么PR不能合并
常见原因有几个:
- 有冲突没有解决
- 自动检查没有通过
- 没有合并权限
- PR方向选错了
- 需要至少一个人Review通过
可以先看PR页面上的提示。一般Gitea、GitHub、GitLab都会告诉你当前卡在哪一步。
merge和rebase到底选哪个
简单记:
- 公共分支少
rebase - 自己的功能分支可以
rebase - 不确定就
merge
merge更直观,也更不容易影响别人。rebase能让历史更清爽,但前提是你知道自己在改哪条分支。
刚开始协作时,不需要一上来就追求特别漂亮的提交历史,先保证流程正确、代码别丢、主分支稳定更重要。
fork和branch有什么区别
branch是在同一个仓库里开分支,适合同一个团队内部协作。
fork是把别人的仓库复制一份到自己的账号下面,适合外部贡献者参与项目。
简单说:
同一个团队仓库一般用 branch外部贡献一般用 fork比如公司内部几个人一起开发一个项目,通常直接在项目仓库里建分支。
如果你想给一个开源项目贡献代码,但你没有那个仓库的写权限,就先fork到自己账号,再从自己的仓库提交PR。
总结
日常协作可以记住这条线:
main 拉最新 -> 新建分支 -> 提交 -> 推送分支 -> PR -> Review -> 合并这篇的核心不是某一个单独命令,而是完整流程。
不要直接在main上开发。功能分支写完后,通过Pull Request合并,这样代码历史更清楚,主分支更稳定,也更适合多人协作。