3050 字
15 分钟
Git协作流程
2026-06-01

前言#

上一篇文章Git基础使用教程写了Git的基础命令,比如addcommitbranchmergerebase这些东西。

这篇主要记录多人协作时最常见的一套流程。

重点不是讲很多高级命令,而是搞清楚一件事:

一个功能从开始开发,到最后合并进主分支,中间到底经过哪些步骤。

如果只是自己一个人写代码,可能本地改完、提交、推送就结束了。但多人一起改同一个项目时,就不能每个人都直接往主分支上推代码了,不然很容易互相覆盖、互相冲突,最后谁也不知道主分支到底还能不能正常运行。

为什么不要直接改main#

main或者以前常见的master,一般代表项目当前比较稳定的代码。

比如一个网站项目,main分支上的代码可能会直接部署到线上;一个后端项目,main分支可能就是大家默认拉取和测试的版本。

如果所有人都直接在main上开发,会出现几个问题:

  • 代码还没写完就被别人拉到了
  • 一个半成品功能影响其他人开发
  • 出了问题很难判断是哪次修改引起的
  • 没有机会让别人提前检查代码

所以多人协作时,更常见的做法是:

main 保持稳定
每个人在自己的分支上开发
写完后通过 Pull Request 合并回 main

这样主分支不会被随便改动,每个功能也有比较清楚的开发和检查过程。

常见协作流程#

平时协作大概可以按这条线走:

更新主分支
创建功能分支
开发并提交
推送到远程
创建 Pull Request
代码检查 / Review
合并到 main
删除功能分支

看起来步骤不少,但实际熟悉之后就是一套固定动作。

简单说,就是不要把代码直接写到main,而是先从最新的main拉出一个自己的功能分支。功能写完以后,把这个分支推送到远程仓库,再创建一个Pull Request,让别人看一下改了什么,确认没问题后再合并。

开发前先更新主分支#

开始写新功能前,先切回main,把远程最新代码拉下来。

Terminal window
git switch main
git pull

这一步是为了保证自己的新分支是从最新代码上分出来的。

如果你本地的main已经落后远程很多,直接从旧代码上开分支,后面更容易遇到冲突。

创建自己的功能分支#

更新完main后,再创建自己的功能分支。

Terminal window
git switch -c feature-login

-c表示创建并切换到这个新分支。

分支名最好能看出来这个分支是干什么的,不要随便叫testaaanew这种名字。

常见命名方式:

feature/login
fix/login-error
docs/update-readme

大概可以这样理解:

  • feature/xxx:开发新功能
  • fix/xxx:修复问题
  • docs/xxx:修改文档

团队里如果有固定命名规范,就按团队规范来。没有规范时,至少保证别人能从分支名看懂大概用途。

在分支上开发和提交#

切到功能分支后,就可以正常改代码了。

改完一部分后,可以先看状态:

Terminal window
git status

确认这次要提交哪些文件:

Terminal window
git add .
git commit -m "添加登录页面"

这里还是建议养成几个习惯:

  • 提交前先看git status
  • 一个提交尽量只做一件事
  • 不要把临时文件、测试文件、编译产物误提交上去
  • 提交说明不要只写update

比如下面这种提交说明就比较难看懂:

Terminal window
git commit -m "update"

过几天再看日志,根本不知道这个update到底更新了什么。

可以写得具体一点:

Terminal window
git commit -m "添加登录页面"
git commit -m "修复登录失败提示"
git commit -m "更新登录接口地址"

提交说明不一定要特别长,但至少要让人知道这次提交主要做了什么。

推送分支到远程#

本地提交完成后,需要把自己的功能分支推送到远程仓库。

第一次推送这个分支时,一般这样写:

Terminal window
git push -u origin feature-login

这里的-u是设置上游分支。设置之后,以后在这个分支上再推送,就可以直接:

Terminal window
git push

如果分支名是feature/login,命令就是:

Terminal window
git push -u origin feature/login

推送成功后,远程仓库里就能看到这个分支了,接下来就可以创建Pull Request。

创建Pull Request#

Pull Request可以简单理解成:

我这个分支写好了,请帮我看一下,没问题就合并到 main。

如果使用的是Gitea,大概流程是:

  1. 打开仓库页面
  2. 选择Pull Requests
  3. 点击New Pull Request
  4. base(左侧的)选择main
  5. compare(右侧的)选择自己的功能分支
  6. 填写标题和说明
  7. 提交Pull Request

创建PR时,最重要的是确认方向不要选反。

一般应该是:

base: main
compare: 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

Terminal window
git switch feature-login
git fetch origin
git rebase origin/main

也可以简单一点:

Terminal window
git pull --rebase origin main

个人功能分支用rebase通常会比较清爽,因为它会把你的提交放到最新的main后面,历史看起来更像一条直线。

大概可以理解成:

先把 main 的新提交拿过来
再把自己的提交重新放到后面

不过要注意,rebase更适合自己的功能分支。已经给很多人共同使用的公共分支,不建议随便rebase,否则容易影响别人。

发生冲突怎么办#

如果你和别人改了同一个文件的同一部分,就可能出现冲突。

比如执行rebase时提示冲突,可以先看状态:

Terminal window
git status

然后打开冲突文件,手动处理里面的冲突内容。处理完成后:

Terminal window
git add 冲突文件
git rebase --continue

如果冲突太乱,暂时不想继续,也可以取消这次rebase

Terminal window
git rebase --abort

冲突本身不是什么可怕的东西,它只是Git不知道该保留哪一边,需要人来判断。

处理冲突时不要只想着“让文件不报错”,还要确认功能逻辑是不是对的。尤其是两个人同时改了同一个函数、同一个配置文件时,解决完最好重新跑一下项目。

合并Pull Request#

PR通过Review后,就可以合并到main

常见合并方式有几种:

  • Create merge commit
  • Squash and merge
  • Rebase and merge

Create merge commit会保留分支上的提交记录,并额外生成一个合并提交。小团队、小项目直接用这个也没问题。

Squash and merge会把这个PR里的多个提交压成一个提交再合并。如果你开发过程中提交了很多零碎记录,比如fixdebugupdate,用squash可以让main的历史更干净。

Rebase and merge会把功能分支上的提交重新放到main后面,历史也比较直,但对新手来说理解成本稍微高一点。

入门时可以先记一个简单建议:

小项目可以直接merge;想让历史干净,可以squash。

如果团队已经规定了合并方式,就按团队规则来。

合并后删除分支#

功能已经合并进main后,原来的功能分支通常就可以删掉了。

远程分支可以在Gitea的PR页面里删除,一般合并后页面会有删除分支的按钮。

本地分支可以这样删:

Terminal window
git switch main
git pull
git branch -d feature-login

git branch -d会删除本地分支。如果Git发现这个分支还没有合并,通常会拒绝删除,避免误删。

如果你用的是feature/login这种分支名,就写:

Terminal window
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合并,这样代码历史更清楚,主分支更稳定,也更适合多人协作。

Git协作流程
https://blog.aloys233.top/posts/git多人协作/
作者
Aloys23
发布于
2026-06-01
许可协议
CC BY-NC-SA 4.0

评论