
带过新同事之后我发现自己每年都要把 Git 操作重新讲一遍有人只在 IDEA 里点点点有人只认 VSCode 的按钮还有人习惯敲命令行。最崩溃的是一个团队里三种操作习惯并存代码冲突、误提交、分支乱切哪一样都能让人血压升高。后来我干脆沉淀了一份《IDEA / VSCode / Git 标准操作规范》把更新代码、提交代码、切换分支、合并分支、暂存代码、回滚代码、创建分支、打 Tag 标签这些高频场景全部过了一遍发给团队当默认教材。这篇文章就是那份规范的可公开版本如果你也是带团队的人或者刚从 TortoiseGit 转到 IDE 上可以直接照着抄。1. 先说清楚一件事为什么需要一套标准操作规范很多开发者的 Git 操作是“会但是不系统”。我问过团队里不少人拉代码用哪个按钮、提交代码之前要不要先更新、合并分支用 merge 还是 rebase、改错了代码怎么恢复。答案五花八门。严格来说每种做法都对但是当这些做法混在同一个仓库里时问题就开始冒头了。举个例子。A 同事习惯先 commit 再 pull结果每次 pull 都会产生一个 merge commit日志里全是 Merge branch 的记录B 同事喜欢 push 之前强制 rebase经常把别人的提交顺序打乱C 同事切分支之前不暂存代码改了半天的文件跟着切换到了别的分支回头找不到了。这些都不是 Git 本身的错而是缺少一套统一的操作节奏。所以标准操作规范的核心不是规定“只能用命令”或者“只能用界面”而是把高频操作用一种最不容易出错的方式固定下来大家照着同一个流程走出了问题也有迹可循。以下内容以 IDEA 和 VSCode 为主视角涉及核心命令时会给出对应命令行方便你两手都会。2. 建立 Git 工作区全景认知2.1 三个区域和一整套流转关系很多操作失误根源不是按钮点错而是脑子里没有工作区的概念。Git 把代码放在四个地方工作区Working Directory、暂存区Index / Staging Area、本地仓库Local Repository、远程仓库Remote Repository。用生活里的类比解释工作区是你的办公桌代码文件散在上面暂存区是打包台你把要寄走的文件放进去本地仓库是你自己家里已经封箱的包裹远程仓库是公司统一的库房。你在办公桌上改东西工作区改完放到打包台git add打包完封箱放回家里git commit最后统一搬到公司库房git push。在 IDEA 和 VSCode 里这些区域的表现方式不一样但逻辑完全一致。IDEA 的 Commit 工具窗口里会列出自 Changed Files、Staged Files对应的就是工作区和暂存区VSCode 的源代码管理面板左侧是“更改”上方如果有“暂存更改”按钮对应的也是同一套逻辑。2.2 IDEA 和 VSCode 中的 Git 入口地图两个 IDE 的 Git 功能入口不一样但高频操作就那么几个先记住位置。IDEA 的 Git 入口很集中右上角有一个向下箭头Update Project默认快捷键 CtrlT和一个向上箭头的提交按钮右下角显示当前分支名点击可以弹出一整套分支操作菜单左下角 / 侧边栏的 Git 工具窗口Alt9 / Cmd9可以看到日志、分支、提交记录。更完整的菜单在顶部 VCS / Git 下Stash、Reset、Revert、Tag 都在里面。VSCode 的入口更分散但也更好找左侧活动栏的“源代码管理”图标是核心操作区默认快捷键 CtrlShiftG左下角显示当前分支名的按钮点开可以切分支、创建分支右上角如果有 GitLens 插件还会多出一个类似 IDEA 的 Git 工具栏。VSCode 的部分高级操作比如 Merge、Rebase没有原生按钮需要按 CtrlShiftP 打开命令面板输入 Git: 查找。3. 环境准备好了再动手3.1 配置好两个 IDE 的 Git 内核无论用哪个 IDE机器上必须先装好 Git 命令行工具。IDEA 和 VSCode 的 Git 功能本质上都是调用你在系统里安装的 Git 内核只是外面包了层图形界面。IDEA 里打开 Settings / Preferences搜索 Version Control进入 Git 页面找到 Path to Git executable确认它指向你机器上的 git.exeWindows或 /usr/bin/gitMac/Linux。如果路径不对IDEA 会提示没有配置 Git这时候需要手动选择一次。VSCode 通常会自动识别 Git但保险起见可以在 settings.json 里指定git.path: C:\\Program Files\\Git\\bin\\git.exeWindows 用户安装 Git 时会遇到 PATH 环境变量的问题如果安装时没有勾选“Add to PATH”VSCode 可能认不到。最简单的办法是重装一次 Git安装向导里选“Git from the command line and also from 3rd-party software”。3.2 提交身份信息与 SSH 免密在任何 IDE 里提交代码之前Git 需要知道你叫什么名字。这个信息写在 git config 里不是 IDE 内部配置所以只需设置一次git config --global user.name 你的名字 git config --global user.email 你的邮箱example.com如果不设置commit 时会报一个 “Please tell me who you are” 的错误IDEA 和 VSCode 都会弹窗提示。远程仓库的认证方式个人强烈建议用 SSH。配置过 SSH 之后推送代码不再每次输入账号密码也不用担心 HTTPS 令牌过期。ssh-keygen -t ed25519 -C 你的邮箱example.com一路回车生成密钥后把公钥默认在 ~/.ssh/id_ed25519.pub复制到 GitLab / GitHub / Gitee 的 SSH Keys 配置页。验证是否成功ssh -T gitgitee.com能返回欢迎信息就说明已经打通。IDEA 和 VSCode 在 clone 仓库时选择 SSH 地址之后的所有操作都会自动走免密通道。4. 每天必做的更新与提交4.1 先拉后推更新代码的标准姿势大多数人刚打开 IDE 的第一件事就是把最新代码拉下来。IDEA 里的标准动作是点击右上角的 Update Project 按钮或者按 CtrlTVSCode 里是源代码管理面板顶部的 Pull 按钮。需要注意IDEA 的 Update 和 VSCode 的 Pull 在底层做的事情不完全一样。IDEA 的 Update 默认等于 Fetch Merge如果你配置的是 rebase 策略则是 Fetch RebaseVSCode 的 Pull 默认也是 Fetch Merge。日常场景下两个都可以但有一个小区别IDEA 的 Update 在拉取的同时会尝试变基到远程分支的最新提交上如果你本地已经改了文件会先把本地改动弹出来相当于自动 stash拉完再恢复这个机制对本地未提交的修改非常友好。更新代码之前最好看一眼当前分支有没有自己未提交的修改。如果有先 commit 或 stash再进 Update可以避免 Git 因为本地改动与远程改动重叠而拒绝拉取。对应的底层命令你早晚会用到git fetch origin git pull --rebase origin 当前分支名个人习惯强烈倾向于 pull --rebase 而不是默认 merge。原因后面章节会展开。4.2 提交代码的正确流程提交代码的标准顺序是先看改动、再暂存、写信息、提交、推送。Ide 里容易出错的地方有两个一是把不想提交的文件也勾上了二是提交信息写得语焉不详。IDEA 里按 CtrlK 打开 Commit 工具窗口左侧会列出所有改动文件每个文件前面有复选框。提交之前务必逐个扫一眼排除配置文件、临时文件、数据库备份之类不该入库的东西。确认无误后在 Commit Message 里写清楚这次改动的内容然后点击 Commit如果有 Push可以一并勾选。VSCode 里操作更精简源代码管理面板会列出更改的文件点击文件旁边的加号把特定文件加入暂存区然后在输入框写提交信息按 CtrlEnter 提交。VSCode 默认只提交暂存区的文件如果你没点加号直接 CtrlEnter它会提示“没有暂存的更改”这反而逼着你养成先暂存再提交的习惯。在 IDEA 里也可以沿用这套习惯不用一次勾选所有文件可以右键单个文件选择“Git AddSelectedFiles”或者使用快捷键暂存然后再去 Commit 窗口只提交暂存区的内容。不过对于团队协作来说提交粒度只要合理暂存不暂存其实没那么重要核心是不要带无关文件。4.3 Commit Message 规范我见过最坑的提交信息是update、bug fix、test、111、aaaa。这种信息一个月后你自己都看不懂更别说别人 review 了。建议团队统一使用 Conventional Commits 风格结构很简单type(scope): subject空格开头的空主题是不规范的。常见类型有前缀含义feat新功能fix修复缺陷docs文档变更style代码风格调整不影响逻辑refactor重构行为不变test测试相关perf性能优化chore构建工具、依赖更新等杂务示例fix(login): 修复短信验证码倒计时不停止的问题提交信息用中文还是英文看团队习惯但同一个仓库应保持一致。建议至少做到“看一眼提交信息就知道这次改动的目的”。5. 分支管理创建、切换与合并5.1 创建与切换分支创建分支的动作很简单麻烦的是命名。没有规范的分支名是团队混乱的第一大来源。建议遵循 Git Flow 或简化版命名约定主分支主干长期保留main、master、develop功能分支feature/用户登录缺陷修复分支fix/登录页样式错乱发布分支release/1.2.0热修复分支hotfix/线上崩溃IDEA 里创建分支点击右下角分支名选择 New Branch输入分支名确认即可。注意 New Branch 弹窗里有一个复选框“Checkoutbranch”勾上表示创建后立即切换过去不勾则只创建不切换取决于你是不是马上要在新分支上干活。VSCode 里创建分支点击左下角分支名选择 Create New Branch输入分支名回车。创建后 VSCode 会直接切换过去。切换分支的标准动作在 IDEA 里叫 Checkout在 VSCode 里点击分支列表中的分支名即可。这里有一个血泪教训切换分支之前请先看一眼工作区有没有未提交的修改。如果本地有改动而且这个改动在两个分支之间会引发冲突Git 会阻止你切换报 “Your local changes would be overwritten by checkout”。哪怕 Git 允许你带着改动切走那些改动如果和另一个分支的代码合并在一起很可能出现“这个文件我明明在上个分支改过怎么到这个分支也不对”的情况。5.2 合并分支的两种方式与选择逻辑合并分支是团队协作中最容易出问题的环节。常见的方式有两种merge 和 rebase。merge 会把源分支的提交历史和当前分支的提交历史合并成一个新的合并提交保留两条分支的原始脉络。rebase 则是把当前分支上的提交逐个摘下来接到目标分支的最新提交之后形成一条线性历史。用生活化的说法merge 是把两份笔记订在一起边界明显rebase 是把你的笔记重新抄写到别人的最新版本之后整个本子的页码是连续的。这两种方式的取舍我的建议是分场景功能分支合并回主干用 merge。因为功能分支的提交往往是一整个完整需求merge 后保留一个清晰的合并节点方便回溯“这个功能整体是什么时候并进来的”。主干同步到自己的功能分支用 rebase。因为功能分支开发周期长主干上已经有了其他人的新提交用 rebase 能让你的功能分支在最新主干基础上继续开发同时减少未来合并时的冲突。IDEA 里执行 merge 的方式先切换到目标分支比如从 feature 切到 develop然后点击右下角分支名选择需要被合并的分支比如 feature/xxx再选择 Merge into Current。弹出对话框会告诉你合并结果。VSCode 原生不支持图形化 merge需要按 CtrlShiftP输入 Git: Merge Branch然后选择要合并的分支。rebase 在 IDEA 里的操作路径是Git 工具窗口 Log 右键当前分支头部 RebaseOntoAlternativeBranch或者使用“更新项目”时把更新策略改为 rebase。VSCode 也是通过命令面板执行 Git: Rebase Branch。5.3 处理合并冲突的实战经验不管用什么方式合并只要两边改了同一文件的同一块代码Git 就会停下来交给你解决冲突。IDEA 的冲突解决对话框比较智能会列出冲突文件双击可以进入三路合并视图左边是本地版本中间是合并后的效果右边是远程版本用上下箭头逐块选择保留哪边的代码也可以手动编辑中间窗口解决完点 Apply。VSCode 只提供文本级的冲突标记文件里会显示 HEAD 当前分支的代码 被合并分支的代码 feature/xxx你需要手动保留正确的代码删除标记保存文件。如果在 VSCode 里经常处理冲突推荐装 GitLens 或者 Git Merge 插件能友好一点。几个从实践中总结的冲突处理心得冲突标记内的两段代码不要无脑选“我这边”或者“他那边”先搞明白这段代码为什么要改成这样复杂冲突不要靠肉眼硬刚先和对方确认这段逻辑的责任人解决完冲突后先本地编译 / 跑测试再提交合并提交的 commit message 可以先用默认的 Merge branch ... 模板不用刻意美化6. 暂存代码干到一半要先让位6.1 什么时候需要 stashStash暂存的动作是把工作区未提交的修改保存到一个独立的临时区域然后把工作区恢复到干净状态。这样你就可以安全地切换分支、拉取更新之后再把暂存内容恢复回来。典型场景你在 feature/A 上写需求写到一半同事叫你紧急去修复 feature/B 的一个 bug。如果直接切分支Git 可能不允许或者把当前改动带到别的分支。这时候最安全的做法是先把改动 stash 起来切分支修 bug修完再切回来把 stash 弹出。另一个容易忽略的场景本地改了代码想 pull 更新但害怕冲突可以先把改动 stashpull 完再 stash pop。但正常情况下先 commit 更合适因为 stash 里没有版本历史长时间放着容易遗忘。6.2 IDEA 和 VSCode 中的暂存操作IDEA 里顶部菜单 Git Stash Changes会弹窗让你输入 stash message填一下便于日后识别。恢复时选择 Git UnstashChanges弹出列表选择要恢复的 stash 记录点 Apply。VSCode 里源代码管理面板标题栏的“...”菜单或更多操作选择“暂存”Stash输入消息确认。恢复时同样的“...”菜单里选“弹出暂存更改”Pop Stash。命令行写法git stash push -m 描述 git stash list git stash pop需要注意stash pop 和 stash apply 的区别pop 恢复的同时丢弃 stash 记录apply 则保留。如果恢复时遇到冲突Git 会暂停恢复流程把冲突标记在文件里你需要手工解决这是正常现象不要吓到。踩坑提醒stash 的内容跨分支也能恢复但恢复时如果和当前分支的代码冲突解决起来会非常痛苦。所以 stash 时最好养成写清楚 message 的习惯。还有 stash 不会自动跟踪新增的未跟踪文件untracked files如果需要连新文件一起暂存要用git stash push -u或者在 IDEA 里勾选 Untracked files。7. 回滚代码最需要冷静的操作7.1 还没提交丢弃本地修改这是最简单的回滚本地文件改乱了想恢复成上一次提交时的状态。IDEA 里右键文件 Git Revert弹出的对话框中选中要放弃的文件点击 Revert。VSCode 里在源代码管理面板的文件列表上或者打开文件后右上角选择“丢弃更改”Discard Changes确认即可。提醒一句这个操作不可逆。丢弃之后你在工作区对这个文件的修改就没了除非 IDE 有 local historyIDEA 有这个功能右键文件 Local History Show History可以找回最近几次保存的快照。所以丢之前多看一眼文件列表别不小心把重要的改动给丢了。7.2 已提交但未推送reset 大法错误已经进入了本地仓库还没有推送到远程。这种场景最典型的操作是提交信息写错了、提交了不该提交的文件、或者连续提交了几次想回退到某个状态。reset 有 soft / mixed / hard 三种模式区别在于回退时如何处理暂存区和工作区模式暂存区工作区适用场景--soft保留保留只撤销 commit 记录重新写提交信息--mixed默认清空保留撤销 commit 并取消暂存修改保留在工作区--hard清空清空彻底回到目标提交丢弃所有改动IDEA 里执行路径Git 工具窗口 Log 选择要回到的提交记录右键 Reset Current Branch to Here然后选择 Reset Type。绝大多数日常场景选 Soft 就够用你只是想撤销刚才的 commit文件状态仍然保持在“已暂存”重新 commit 一次即可。命令行git reset --soft HEAD~1 git reset --hard 目标commitIdHEAD~1表示回到上一个提交也可以直接写 commit id。注意 --hard 一定要三思因为工作区和暂存区的改动会全部消失。7.3 已推送到远程revert 才是正确姿势代码已经 push 到远程分支了才发现有 bug。这时不要用 reset因为你改了本地历史下次 push 会被远程拒绝甚至会影响别人的本地仓库。标准做法是 revert生成一个新提交把之前某个提交的改动反向撤销掉。这样历史没有被改写所有协作者 pull 之后都能安全同步。IDEA 里Git Log 选择要撤销的提交记录右键 Revert Commit然后 Commit 并 Push。VSCode 里同样在源代码管理 提交记录中右键对应的提交选择 Revert Commit。revert 之后原来的错误提交仍然留在历史里这是正常设计。如果 revert 时遇到冲突解决方式和 merge 冲突一样解决完继续提交。需要特别提示revert 撤销的是“改动内容”不是“时间线”。如果你 revert 掉一个非常早的提交而后续的提交又改回了同一块代码revert 可能会产生冲突。这很正常遇到就解决不用慌。7.4 从远程恢复 / 找回丢失的提交误操作之后想找回丢失的本地提交最可靠的手段是 reflog。它记录了本地 HEAD 的每一次移动轨迹哪怕你 reset 掉了提交reflog 里也能找到当时的 commit id。IDEA 里可以在 Git 工具窗口的 Log 视图左上角切换分支为 “All”然后选择“Show Reflog / 刷新”查看。推送过到远程的提交可以直接在远程分支上找到。命令行git reflog git reset --hard (reflog里看到的commitId)reflog 是本地级别的不会推送到远程。所以重要的分支尽量推送到远程远程才有兜底能力。8. Tag 标签版本发布的锚点8.1 创建与推送标签Tag 是为某个提交打一个具有业务含义的标签通常用于发布版本比如 v1.0.0、v2.3.1。它不像分支那样会随提交移动而是死死钉在某个提交上。版本号建议遵循语义化版本控制SemVer主版本号.次版本号.修订号。主版本号用于不兼容的 API 变更次版本号用于向后兼容的功能新增修订号用于向后兼容的缺陷修复。IDEA 里打标签顶部菜单 Git Tag输入标签名比如 v1.0.0最好在 Message 里写一句说明。注意创建标签后默认不会自动推送到远程需要单独推送。VSCode 里通过命令面板CtrlShiftP输入 Git: Create Tag输入标签名确认。推送标签同样要额外执行。命令行git tag v1.0.0 git push origin v1.0.0推送单个标签用上面的命令一次性推送所有本地标签git push origin --tags推送所有标签这种操作在协作仓库里不推荐因为会把本地多余的调试标签一并推上去给远程仓库制造噪声。8.2 删除与修改标签删除本地标签git tag -d v1.0.0删除远程标签git push origin :refs/tags/v1.0.0IDEA 里可以在 Git Log 中找到标签右键选择 DeleteVSCode 里也可以在提交记录中右键标签删除。要警惕如果一个标签对应的是已发布到生产环境的版本删除标签会带来很大混乱——CI/CD 系统可能根据标签构建产物别人可能已经依据这个版本号做了发布记录。有“重新打同一个版本号”的需求时宁可新增一个 v1.0.1 标签也不要删掉原来的标签重新打。标签打错位置了比如想打在 develop 最新提交却打在了 main 上也不要慌按上面的流程删除再新建即可。但因为标签名不常变最好养成打标签前看提交历史、看清 commit id 的习惯。9. 常见问题排查速查表把这些年遇到的团队高频问题整理成一张速查表按实操场景排好了你可以直接贴在工位旁边问题现象解决方案更新代码时本地有未提交修改IDEA Update 直接报错或拒绝先 stash 或先 commit再更新提交信息写错了但没推送Commit 记录还在本地git reset --soft HEAD~1重新 commit提交信息写错了但已推送远程记录已成事实用 revert 生成反向提交或强推覆盖不推荐公共分支切分支后找不到之前的改动改动带了别的工作区检查 stash list可能自动 stash 了合并冲突解决完想反悔冲突代码改得乱七八糟重新 checkout 文件或者 git merge --abort误删了分支分支被删本地找不到用 reflog 找回分支头部 commit重新创建分支pull 时提示 non-fast-forward本地有和远程不一致的提交改用 pull --rebase先变基再合并标签推送不上远程已存在同名标签先删远程标签再推或换新标签名日常操作中还有一个很容易被忽略的点在公共分支main / develop / release上不要轻易强推 reset不要在 commit 历史里删改“已经发布”的提交。这些分支应该走 merge revert 的路线。私有功能分支上可以随意 reset因为只有你一个人在用影响范围可控。最后分享一个小技巧我自己的一个固定习惯是每次动手之前先看一眼当前分支在 IDEA 右下角或 VSCode 左下角确认自己确实在你以为的那个分支上每次提交之前快速扫一眼改动文件列表确认没有把本地配置、日志文件、构建产物一并勾进去。这两个动作加起来不到五秒钟但避免过的事故远比想象中多。这套流程从最早只给自己用到后来整理成团队规范最直观的变化是新同事入职第一天不用再追着别人问“这一步怎么操作”文档往群里一发照着走就基本不会错跨分支切换、回滚、合并且这些曾经让人手心冒汗的操作也终于变成了有标准答案的例行公事。如果你也准备沉淀一份团队 Git 规范建议从这篇文章的基础流程开始再根据你们自己的开发节奏加上补充约定——比如分支命名、提交粒度、Code Review 流程——慢慢就会形成你们自己的版本。