Git 团队协作流程
来源:实操整理
一、核心心智模型
1. 一次修改如何进入远程仓库
工作区 ──git add──> 暂存区 ──git commit──> 本地仓库 ──git push──> 远程仓库git status:查看当前分支和文件状态。git diff:查看尚未暂存的修改。git diff --staged:查看已经暂存、准备提交的修改。git add:把修改放入暂存区。git commit:把暂存区内容保存为本地提交。git push:把本地提交发送到远程仓库。
2. main、origin 和 origin/main
| 名称 | 含义 |
|---|---|
main | 本地主分支 |
origin | 远程仓库在本地的常用简称 |
origin/main | 本地保存的“远程 main 当前位置” |
feature/xxx | 针对某项任务创建的功能分支 |
执行 git fetch origin 会更新 origin/main 等远程跟踪分支,但不会自动移动本地 main,也不会修改工作区文件。
3. fetch、pull 和 push
| 命令 | 核心作用 | 主要影响 |
|---|---|---|
git fetch origin | 获取远程最新提交和分支信息 | 更新远程跟踪分支 |
git pull | 先 fetch,再把上游分支整合进当前分支 | 当前分支和工作区 |
git push | 把本地提交发送到远程 | 远程分支 |
省略 origin 写成 git fetch 时,Git 通常使用当前分支配置的默认远程;仓库存在多个远程时,建议明确写出远程名称。
二、标准团队开发完整链路
以下流程采用“从 main 创建个人功能分支,通过 PR/MR 合并回 main”的模式。
1. 第一次获取项目
git clone <远程仓库地址>
cd <项目目录>git clone 会下载仓库、建立 origin 远程连接并检出默认分支。第一次获取团队项目时使用 clone,不是 pull。
2. 开始任务前更新 main
git status
git switch main
git pull --ff-only origin main切换分支前应确认工作区干净;如果存在未提交修改,先提交或使用 git stash 暂存。
3. 创建并切换到功能分支
git switch -c feature/ai-search常见命名示例:
feature/ai-search:开发新功能fix/login-error:修复普通问题hotfix/payment-error:处理紧急修复
4. 开发、检查并提交
git status
git diff
git add -A
git diff --staged
git commit -m "实现 AI 搜索功能"5. 推送功能分支
第一次推送该分支:
git push -u origin feature/ai-search-u 会建立本地分支与远程分支的跟踪关系,以后通常直接执行:
git push如果同一个远程功能分支可能被其他人或另一台电脑更新,先提交本地修改,再同步后推送:
git pull --rebase
git push6. 创建 PR / MR
在 GitHub、GitLab 或 GitCode 上创建合并请求:
feature/ai-search → main由维护者或评审人员进行代码审查,测试通过后合并。合并者不一定是仓库管理员,取决于团队权限规则。
7. 合并后清理
git switch main
git pull --ff-only origin main
git branch -d feature/ai-search确认远程功能分支不再需要时,可以删除它:
git push origin --delete feature/ai-search三、团队存在共享 dev 分支时
如果团队采用 main + dev 模式,个人仍应从 dev 创建独立功能分支:
main
└── dev
└── feature/ai-search开始任务:
git switch dev
git pull --ff-only origin dev
git switch -c feature/ai-search开发完成后把 feature/ai-search 推送到远程,并创建合并到 dev 的 PR/MR;发布时再由团队把 dev 合并到 main。
当前在 dev,如何取得最新 main
在 dev 上直接执行 git pull,默认同步的是 dev 的上游分支,通常为 origin/dev,不会自动更新本地 main。
只想切换到最新的 main:
git switch main
git pull --ff-only origin main想把远程最新 main 合入当前 dev:
git switch dev
git fetch origin
git merge origin/main既想更新本地 main,又想把它合入 dev:
git switch main
git pull --ff-only origin main
git switch dev
git merge main在 dev 上执行 git pull origin main 的含义是“把远程 main 整合进当前 dev”,不是“更新本地 main 后切换过去”。显式使用 fetch 和 merge origin/main 更容易看清操作目标。
四、同步与分叉
1. —ff-only:只允许快进
ff 是 fast-forward(快进)的缩写。当本地没有独有提交,只是落后远程时:
本地 main:A──B
远程 main:A──B──C──D执行:
git pull --ff-only origin mainGit 只把当前分支指针从 B 移到 D,不会创建额外的合并提交。
如果本地和远程已经分叉:
远程:A──B──C
本地:A──B──D--ff-only 会停止并报错,不会擅自生成合并提交。此时应根据团队规则选择显式 merge 或 rebase。
记忆:能直线前进就更新;需要合并就停下来。
--ff-only 更新的是执行命令时所在的当前分支。因此,要更新本地 main,应先 git switch main。
2. 为什么 push 前要先同步
如果远程包含本地没有的提交,直接 git push 通常会被拒绝,以避免覆盖别人的工作。个人功能分支存在远程更新时,可以使用:
git pull --rebase
git push--rebase 会先取得远程提交,再把尚未推送的本地提交重新放到远程最新提交之后。发生冲突时,需要解决冲突后再继续。
严格来说:
git fetch
git pull
git push通常会获取两次远程信息,因为 git pull 本身已经包含 git fetch。单独执行第一次 fetch 的价值在于先检查远程变化;如果不检查,通常直接 git pull --rebase 后再 git push。
基准分支和功能分支建议区别处理:
| 分支场景 | 建议 |
|---|---|
更新 main、dev 等基准分支 | 使用 git pull --ff-only,分叉时停下检查 |
| 个人功能分支同步自己的远程分支 | 可使用 git pull --rebase |
把最新 main 合入功能分支 | git fetch origin 后显式执行 git merge origin/main |
五、放弃本地修改并对齐远程
1. status 显示已与远程同步,但仍有 modified
Your branch is up to date with origin/main
modified: 某个文件这表示本地提交历史与 origin/main 一致,但工作区仍有未提交修改。提交历史一致不等于工作区干净。
2. 让本地 main 完全对齐远程
确认本地修改和本地独有提交都不需要后执行:
git switch main
git fetch origin
git reset --hard origin/main不需要再执行 git pull。git reset --hard main 只会重置到本地 main,不会前进到远程最新提交。
警告:
reset --hard会丢弃已跟踪文件的未提交修改,并可能丢弃本地独有提交。
如果还要删除未被 Git 跟踪的新文件或目录,先预览,再删除:
git clean -nd
git clean -fdgit clean -fd 删除的内容通常难以恢复。
六、常用参数精华
| 参数 | 含义 | 作用 |
|---|---|---|
git switch -c <分支> | -c = --create | 创建新分支并立即切换 |
git checkout -b <分支> | -b 表示创建分支 | 旧式的“创建并切换”写法 |
git add -A | -A = --all | 暂存整个仓库中的新增、修改和删除 |
git commit -m "说明" | -m = --message | 直接提供提交说明 |
git push -u origin <分支> | -u = --set-upstream | 推送并设置上游跟踪关系 |
git pull --ff-only | ff = fast-forward | 只允许快进,分叉时停止 |
git pull --rebase | --rebase = 变基 | 在远程最新提交之后重新应用本地提交 |
git branch -v | -v = --verbose | 显示分支、最近提交及领先/落后信息 |
git branch -d <分支> | -d = --delete | 安全删除已合并的本地分支 |
git branch -D <分支> | -D = --delete --force | 强制删除本地分支,使用前要确认 |
git remote -v | -v = --verbose | 显示远程名称及拉取、推送地址 |
git reset --hard <目标> | --hard | 同时重置分支、暂存区和工作区 |
git clean -n | -n = --dry-run | 只预览将删除的未跟踪内容 |
git clean -f | -f = --force | 实际删除未跟踪文件 |
git clean -d | -d 表示目录 | 同时处理未跟踪目录 |
短参数通常可以组合,例如 -fd 表示同时使用 -f 和 -d;长参数通常以两个连字符开头,例如 --ff-only、--rebase。
七、最重要的几条原则
- 新任务开始前,先更新基准分支,再创建功能分支。
- 不直接在
main上开发;团队有dev时,也尽量从dev创建个人功能分支。 git pull默认同步当前分支的上游分支,不会自动同步main。git switch main只负责切换,不会自动把本地main更新到最新。git fetch只更新远程信息;git pull才会整合到当前分支。git pull已包含一次fetch;先fetch再pull只有在要先检查远程变化时更有意义。git status显示 up to date 只说明提交历史一致,不代表工作区没有修改。- 不对
main、dev等共享分支执行强制推送。
附:新建本地仓库首次关联远程
git remote add origin <远程仓库地址>
git push -u origin main团队已经存在的仓库通常直接使用 git clone,不需要再次执行 git remote add。