多人协同git提交工程化思路

Git 多人协同分支开发教学(mes_dev 协作版)

场景设定:团队共享的远程开发分支是 mes_dev,每个人的本地开发分支是 mes_dev_自己名字(下文以 mes_dev_zhangsan 为例)。本文覆盖:推送自己的代码、拉取远程代码、解决冲突、避免冲突,以及每一步在 IDEA 中对应的操作和所有常见场景的处理方案。


目录

  1. 分支模型总览
  2. 日常开发标准循环
  3. 如何把自己的代码推送到远程
  4. 如何把远程代码合并到本地
  5. 冲突:原理、解决与所有场景
  6. 如何避免冲突
  7. 全场景速查表
  8. IDEA 操作与快捷键对照
  9. 急救手册:出事了怎么办

一、分支模型总览

分支模型总览

关键认知:

分支 位置 谁在动 用途
origin/mes_dev 远程仓库 全组人 团队共享的开发主线,所有人的代码最终汇合到这里
mes_dev(本地) 你的电脑 只有 git pull 会动它 只是 origin/mes_dev 的本地缓存副本,不要在上面开发
mes_dev_zhangsan 你的电脑 只有你 你的专属开发分支,日常写代码都在这里

口诀:在 mes_dev_name 上开发;push 前先把 origin/mes_dev 的新代码合并进来,再推上去。

创建你自己的开发分支(首次入职做一次)

# 基于远程最新开发分支创建自己的分支
git fetch origin
git checkout -b mes_dev_zhangsan origin/mes_dev
git push -u origin mes_dev_zhangsan   # -u 建立跟踪关系,以后 push/pull 不用再写参数

IDEA 操作:右下角分支图标 → New Branch 输入 mes_dev_zhangsan(基于 origin/mes_dev 创建)→ 勾选 Check out branch


二、日常开发标准循环

日常开发标准循环

每天重复这套动作:拉新代码 → 开发 → 提交 → 推送前再拉一次 → 解决冲突(如有)→ 推送 → 发 Merge Request


三、如何把自己的代码推送到远程

命令行标准三步

# 1. 提交你的改动(在 mes_dev_zhangsan 上)
git add .
git commit -m "feat: 完成排程校验逻辑"

# 2. 推送前先同步远程(防止 push 被拒,见第四节)
git pull --rebase origin mes_dev

# 3. 推送
git push origin mes_dev_zhangsan

IDEA 操作

  1. 提交Ctrl+K(Git → Commit),勾选要提交的文件,写 commit message,点 Commit。
    • 勾选 --amend 可以把改动并进上一次提交(还没 push 时用)。
  2. 推送Ctrl+Shift+K(Git → Push),确认无误后点 Push。
    • 推荐做法:在 Commit 窗口直接勾选 "Commit and Push...",一步完成。
  3. IDEA 右上角有黄色横幅提示 "The branch has new remote changes" 时,点 Rebase(推荐)或 Merge

场景 1:本地有提交,远程没有新提交

git push origin mes_dev_zhangsan   # 直接成功,fast-forward

场景 2:本地有提交,远程也有新提交(最常见!)

先看第四节"把远程合并到本地"里的 rebase 方案,合并完再 push。

强行推送的报错长这样:! [rejected] ... (fetch first)(non-fast-forward)看到报错不要 force push! 按第四节处理。

场景 3:本地改了一半还没 commit,想推送

两个选择:

# 选择 A:先提交再走标准流程(推荐)
git add . && git commit -m "wip: xxx"

# 选择 B:暂存起来
git stash push -m "改到一半的排程页面"
git pull --rebase origin mes_dev
git stash pop

IDEA:右键项目 → Git → Uncommitted Changes → Stash Changes / Unstash Changes

场景 4:误把代码提交到了本地 mes_dev

# 还没 push:把提交"搬家"到自己的分支
git checkout mes_dev_zhangsan
git cherry-pick mes_dev          # 把 mes_dev 上最新的提交摘过来(可多次或用区间)
git checkout mes_dev
git reset --hard origin/mes_dev  # 把本地 mes_dev 恢复成远程的样子

# 已经 push 且被 MR 合入了:不要再动历史,revert(见第九节)

四、如何把远程代码合并到本地

远程 mes_dev 不断有同事的提交汇入,你必须定期同步,拖得越久冲突越多。

命令行:拉取 + 合并的完整方案

# 第一步:只下载,不动工作区(安全,随时可执行)
git fetch origin

# 第二步:合并远程代码,二选一 ——
方案 命令 历史形态 适合
Rebase(推荐) git rebase origin/mes_dev 一条直线,干净 你自己的开发分支没推送过 / 推送过但只有你一个人用
Merge(保守) git merge origin/mes_dev 有分叉合并节点 团队习惯如此 / 分支已共享多人使用

为什么推荐 rebase:rebase 把你的提交"搬"到远程最新提交后面,历史是一条直线(见下图);merge 会产生一堆"Merge branch 'mes_dev'..."的合并节点,日志很难看。

push 被拒绝与 rebase 原理

rebase 黄金法则:只 rebase 自己的、未与他人共享的提交。绝不对已经合入 mes_dev 的公共提交做 rebase。 如果你们组习惯全员直接往共享分支 push,那就统一用 merge。

IDEA 操作

  • 菜单:Git → Update Project(或状态栏右下角分支图标 → Update),快捷键 Ctrl+T
  • 弹出选择框时选 Rebase(推荐)或 Merge —— 这个选择对应 IDE 设置 Settings → Version Control → Git → Update method,可以设成默认 Rebase。
  • 只 fetch 不合并:Git → Fetch(相当于 git fetch),然后右下角分支面板里可以看到 origin/mes_dev 领先了几个提交。

场景 5:本地没有未提交改动,直接同步

git pull --rebase origin mes_dev

场景 6:本地有未提交的改动,又要同步

git stash push -m "同步前的临时保存"
git pull --rebase origin mes_dev
git stash pop          # 恢复改动;若 pop 时报冲突,按第五节解决

IDEA 会自动帮你处理:Update Project 时若检测到未提交改动,会提示你 Stash → Update → Unstash,直接按它的引导走即可。

场景 7:pull 时自动合并成功(无冲突)

Git 会直接把远程改动合进来,你什么都不用做,直接继续开发或 push。

场景 8:pull 时提示冲突

进入第五节,按冲突流程解决。

场景 9:想看看远程到底更新了什么(不合并)

git fetch origin
git log mes_dev_zhangsan..origin/mes_dev --oneline   # 远程比本地多的提交
git diff mes_dev_zhangsan...origin/mes_dev           # 具体差异

IDEA:右下角分支面板 → 展开 origin/mes_dev → 选中某个提交右键 → Show Diff with Working Tree


五、冲突:原理、解决与所有场景

5.1 冲突是怎么产生的

三方合并原理

  • 只有一方改了某行 → Git 自动合并,不会冲突
  • 两方改了同一文件的不同区域 → 自动合并,不会冲突
  • 两方改了同一区域的同一处且改得不一样 → Git 不知道该听谁的 → 冲突

5.2 解决冲突标准流程

第一步:找到冲突文件

git pull --rebase origin mes_dev
# 输出出现 CONFLICT (content): Merge conflict in xxx.java
git status   # both modified: 的文件就是冲突文件

第二步:打开冲突文件,看懂冲突标记

<<<<<<< HEAD                     ← 当前分支这边(rebase 时=远程,merge 时=你自己)
orderService.checkStockV2(order);
=======                          ← 分隔线
orderService.checkStockAndLock(order);
>>>>>>> origin/mes_dev           ← 另一边

易混警告:rebase 和 merge 时 HEAD 的含义相反!

  • git merge:HEAD = 你自己,origin/mes_dev = 远程
  • git rebase:HEAD = 远程,origin/mes_dev(或 theirs)= 你自己的提交

所以解决冲突不要背口诀,要看代码内容判断哪边是什么

第三步:手动编辑融合两边逻辑(不是简单二选一!),删掉 <<<<<<<=======>>>>>>> 标记。

第四步:标记已解决并继续

git add 冲突文件名           # 或 git add .
git rebase --continue       # rebase 流程用这个;会跳到下一个待重放的提交
# 如果想放弃整个 rebase:git rebase --abort(回到 rebase 前的状态,安全)
# merge 流程对应:git commit(Git 会生成合并提交)
# 如果想放弃 merge:git merge --abort

5.3 IDEA 冲突解决(强烈推荐,比命令行舒服太多)

IDEA 冲突窗口

pull/rebase/merge 触发冲突时 IDEA 会自动弹出 Merge Conflicts 对话框,每个文件三个选择:

按钮 效果 什么时候用
Accept Yours 整个文件采用"我的" 确认对方的改动不该要(谨慎)
Accept Theirs 整个文件采用"对方的" 确认自己的改动不要了(谨慎)
Merge(推荐) 打开三栏对比窗口,逐行决定 99% 的情况用这个

三栏窗口用法:

  • 左栏(Local)/ 右栏(Remote):点击代码块旁边的 » / « 箭头把一侧代码采纳进中间。
  • 中栏(Result):合并结果,可以直接编辑——把两边逻辑融合后手写进去。
  • 窗口顶部的冲突计数器会自动跳到下一个冲突点,全部解决后点 Apply
  • 底部预览区可以看最终效果;解决完 IDEA 自动 git add,rebase 的话再执行 git rebase --continue(IDEA 有时会自动继续重放,注意看 Git 输出面板)。

重要提示:IDEA 在 rebase 时把"你的提交"显示为 Remote/Incoming、把"远程分支"显示为 Local——和直觉相反。不确定时看代码内容,别按位置猜。

5.4 所有冲突场景与合并方案

场景 10:两人改了同一个文件的不同方法/区域
Git 自动合并,无需干预。推送即可。

场景 11:两人改了同一行代码(经典冲突)
先问自己:这两处改动是不是要同时保留?

  • 都要 → 在 IDEA 中栏手工融合,如"同事改了方法名 + 你加了参数"→ 写成融合后的最终形态;
  • 只要一边 → 点对应箭头采纳。
  • 拿不准就找同事对一下(微信/口头确认谁的业务逻辑是最新的),30 秒的事,比合错代码返工便宜得多。

场景 12:一人改代码,另一人删了整个文件(modify/delete 冲突)
命令行会提示 CONFLICT (modify/delete)。决策:文件该不该删?

  • 该删 → git rm 文件名 && git rebase --continue
  • 不该删 → git add 文件名 && git rebase --continue(保留你的修改版)。
    IDEA 中在冲突列表选 Accept Yours(保留文件)或 Accept Theirs(删除文件),看清哪边是删除侧再点。

场景 13:两人都新增了同名文件 / 同名方法

  • 同名文件:内容不同则手动融合成一个,删掉多余的那个;git add 保留的那个。
  • 同名方法:编译期不会报错但逻辑可能冲突——融合后跑一遍编译和单测再继续。

场景 14:改动被包含在多个连续提交里,rebase 时同一个冲突反复弹
这是因为你的多个提交都碰了同一块代码。逐个 git rebase --continue 处理即可;也可以改用 git merge(冲突只弹一次)。长期方案见第六节"小步提交"。

场景 15:解决冲突解决到一半,想放弃重来

git rebase --abort    # rebase 流程:完全回到 rebase 之前
git merge --abort     # merge 流程:同上

IDEA:Git 面板中的通知栏有 Abort 按钮。

场景 16:stash pop 时冲突
同普通冲突流程解决,解决后 stash 记录要手动删:git stash drop

场景 17:合并后代码丢了 / 合错了,想恢复

  • 还没 push:git reflog 找到合并前的 HEAD 记录 → git reset --hard <id>
  • 已 push:git revert(见第九节)。

六、如何避免冲突

冲突的根源是 两个人改同一处代码 + 同步间隔太长。对策按有效性排序:

  1. 小步高频同步:每天上班第一件事 git pull --rebase origin mes_dev,下班前 push。拖一周再同步,冲突会滚雪球。
  2. 任务分工错开:领任务时和组长/同事确认"我改排程模块,你别动 SchedulingController"——改不同文件是根治手段。
  3. 拉自己的分支开发mes_dev_zhangsan 只你一人提交,主分支永远干净;通过 MR 合入,冲突在 MR 阶段暴露而非污染主线。
  4. 大改动前先沟通:要改公共类(如 ResultBaseController)时,先在群里说一声,避免和别人撞车。
  5. 拆小提交、拆小 MR:一次提交几百行 vs 一天多个小提交——后者冲突概率和解决难度都低得多。
  6. 文件内部善用拆分:3000 行的巨型类是冲突温床;代码层面拆分方法/类,等于物理隔离了改动区域。
  7. 配置好 .gitignoretarget/*.iml.idea/、本地配置文件(application-local.yml)不进版本库,消除一类无意义冲突。
  8. 统一格式化配置:全组用同一套 IDEA 代码格式化配置(Editor → Code Style → 导出/导入 scheme),否则"你自动格式化了他没格式化"就是隐形冲突制造机。

七、全场景速查表

# 场景 命令 IDEA 操作
1 首次创建个人分支 git checkout -b mes_dev_zhangsan origin/mes_dev 分支面板 → New Branch
2 同步远程(无本地改动) git pull --rebase origin mes_dev Ctrl+T / Update Project → Rebase
3 同步远程(有未提交改动) git stash → pull → stash pop 按弹窗引导 Stash→Update→Unstash
4 提交代码 git add . && git commit -m "..." Ctrl+K
5 推送自己的分支 git push origin mes_dev_zhangsan Ctrl+Shift+K
6 push 被拒(non-fast-forward) git pull --rebase origin mes_dev → 再 push 点黄色横幅的 Rebase
7 拉取时冲突 解决 → git add .git rebase --continue Merge Conflicts 弹窗 → Merge
8 想放弃冲突处理 git rebase --abort / git merge --abort 弹窗 Abort 按钮
9 改了一半想临时切换分支 git stash push -m "..."git checkout ... Git → Stash Changes
10 误提交到 mes_dev cherry-pick 到自己分支 → reset 分支面板右键提交 → Cherry-Pick
11 撤销未 push 的提交 git reset --soft HEAD~1(保留改动) Git Log 右键 → Undo Commit
12 撤销已 push 的提交 git revert <commit> Git Log 右键 → Revert Commit
13 修改最后一次提交信息 git commit --amend Commit 窗勾选 Amend
14 查看远程更新了什么 git fetch + git log ..origin/mes_dev 分支面板看 origin/mes_dev
15 查看某次改动谁写的 git blame 文件名 / git log -p 右键行号 → Annotate with Git Blame

八、IDEA 操作与快捷键对照

操作 快捷键 / 入口 说明
Update Project(拉取+合并) Ctrl+T 或 Git 菜单 弹窗选 Rebase
Commit Ctrl+K 可勾选 Commit and Push 一步到位
Push Ctrl+Shift+K 推送前看一眼 Diff
VCS 操作弹窗 `Alt+`` (反引号) 万能入口:commit/push/pull/stash 全在这
分支面板 IDEA 窗口右下角 切换/新建/删除分支、看远程分支
Stash Changes Git 菜单 → Uncommitted Changes 存放当前未提交改动
查看历史 Alt+9(Git 工具窗口) Log 分支图、右键各种操作
冲突解决 自动弹窗;或 Git 菜单 → Resolve Conflicts 三栏对比窗口
Annotate(看谁写的) 右键行号 → Annotate with Git Blame 排查某行改动的责任人
Undo Commit Git Log 右键提交 仅限未 push 的本地提交
Revert Commit Git Log 右键提交 已 push 的安全撤销

建议的 IDEA 设置Settings → Version Control → Git → Update method 设为 RebaseCommit tool window 勾选常用检查项;开启 Before Commit → Reformat code 前先确认(若全组格式不统一则关闭 Reformat,避免无谓 diff)。


九、急救手册:出事了怎么办

原则:先停下来看 git status,再动手。别慌着删分支、别 force push。

事故 解法
rebase / merge 到一半搞砸了 git rebase --abort / git merge --abort,一切回到操作前
commit 了不想要的文件(未 push) git reset --soft HEAD~1 → 重新挑选文件提交
reset --hard 把改动弄没了 git reflog 找到之前的 HEAD id → git reset --hard <id> 找回
push 错了分支 / push 错了内容 git revert 生成反向提交再 push(已 push 的公共提交永远不要 reset/force push
提交信息写错了(未 push) git commit --amend -m "新信息"
把别人的提交 rebase 丢了 git reflog 里 rebase 前的记录还在,git reset --hard <旧id> 恢复
完全乱了想要干净重来 git fetch origin && git reset --hard origin/mes_dev会丢弃本分支所有未推送内容,确认后再用
什么操作都不敢做了 停手,找组长。Git 几乎不会真正丢数据(reflog 在),慌乱操作才会

一图记住全部流程

上班:  git checkout mes_dev_zhangsan
        git pull --rebase origin mes_dev     ← 拿最新代码

开发:  写代码 → git add . → git commit      ← 小步提交

推送:  git pull --rebase origin mes_dev     ← 推之前再拉一次(关键!)
        有冲突?→ IDEA 三栏窗口解决 → git add . → git rebase --continue
        git push origin mes_dev_zhangsan

收尾:  发起 Merge Request:mes_dev_zhangsan → mes_dev,等 Review 合入

记住一句话:你的分支随便造,主线靠 MR 进;push 前先 rebase,冲突当天清。

posted @ 2026-09-18 09:12  白鹿为溪  阅读(7)  评论(0)    收藏  举报