
1. 为什么搞懂 Git、GitHub、GitLab、SVN是进入团队协作的第一步如果你刚开始写代码或者在一家还在用 SVN 的公司待过几年第一次接触 Git 时大概率会有点懵Git 和 GitHub 不是一个东西吗GitLab 又是干嘛的SVN 不也挺好吗为什么团队非要换我当年也被这套概念绕了很久后来才意识到这些名词背后其实只解决两件事怎么保存代码的历史版本以及怎么让一堆人安全地改同一份代码。先说人话版本。你写了一份文档反复修改后另存为“定稿”“最终定稿”“打死也不改版”这叫手动版本管理。如果几个人同时改还要互相发压缩包合并那就更崩溃。版本控制工具就是把这个过程自动化每次改动留下记录随时能回滚多人改同一份文件时还能自动合并或提示冲突。Git、SVN 都属于这类工具而 GitHub、GitLab 则是建立在 Git 之上的代码托管平台相当于给你的 Git 仓库配了一个远程存放和协作入口。这篇文章就是围绕这四个名词展开的目标很明确先帮你把概念关系理清再带着你用 VSCode 实际跑一遍 Git 的完整流程。不管你是学生、刚入职的新人还是从 SVN 迁移过来的老手跟着操作下来至少能解决日常 90% 的版本控制需求。后面所有步骤我都按实际开发中的习惯来写不会只给你一堆命令然后什么都不解释。1.1 版本控制到底在干什么从一个真实场景说起假设你和另一位同事同时改同一个文件你负责首页文案他负责页面样式。没有版本控制的时候你们会各自复制一份文件到本地改完再通过聊天工具互相传。传的过程中一旦覆盖错版本几个小时的修改就没了。用上 SVN 或者 Git 之后大家永远从同一个仓库拉最新代码改完提交系统自动记录谁、在什么时间、改了什么东西。就算改坏了也可以回到任何一个历史版本。这里有一个核心区别要先记住SVN 是集中式Git 是分布式。SVN 有一个中央服务器所有提交都必须先连上服务器才能完成Git 每个人本地都有一份完整仓库提交、查看历史、创建分支都可以离线完成不需要时刻连着远程。这一点差异带来了完全不同的使用习惯。用 SVN 时提交慢了卡顿、断网就没法工作是常态用 Git 后本地操作极快远程只是在需要同步的时候才连上去。所以当你听到“Git 比 SVN 先进”这种说法时不要只把它当作口号本质是设计思路变了SVN 把服务器当成唯一真相Git 让每个参与者的仓库都成为完整的真相再通过推送和拉取把各部分达成一致。今天很多团队弃用 SVN 转向 Git不是嫌 SVN 难用而是 Git 对分支、合并、离线开发、多人并行的支持更符合现代开发节奏。1.2 Git 的独特设计暂存区、提交、指针第一次用 Git 的人经常被git add和git commit分开执行搞懵。SVN 通常是右键提交就完事Git 为什么要多一步因为 Git 引入了暂存区的概念。你可以把 Git 的本地工作状态想象成三层工作区你当前实际修改的文件肉眼可见。暂存区你告诉 Git“这些改动我待会要提交”但还没真正生成版本记录。版本库已经提交成功的历史记录每次提交就是一次快照。git add是把改动从工作区放进暂存区git commit才是把暂存区的内容打包成一次版本记录。分两步的好处是你可以把一次大改拆成多个有意义的提交比如这一个提交只包含界面调整下一个提交只包含逻辑修复每一条历史都清晰可读。这在团队协作里非常实用别人 review 代码时不需要在一堆混在一起的改动里找重点。而分支操作更是 Git 的强项。SVN 创建分支通常需要复制一份目录成本高、合并也容易冲突Git 创建分支本质上只是创建一个指针瞬间完成切换成本极低。所以现实中常见的做法是每个功能开一个分支改完合并回主分支再删除临时分支。这套流程在 SVN 里不是不能做但是体验和效率差了很多。1.3 一次搞清四个名字的关系继续捋关系Git一个版本控制工具跑在你本地电脑上的程序和操作系统上有多少项目仓库无关。GitHub一个提供 Git 远程仓库托管服务的平台把 Git 仓库放到网上支持网页浏览代码、提 Issue、发起 Pull Request。核心是围绕 Git 的协作社区。GitLab和 GitHub 定位类似也是基于 Git 的托管平台但更强调私有化部署和 DevOps 一体化很多企业内部会搭建自己的 GitLab。SVN另一类版本控制工具集中式管理和 Git 是竞争关系和 GitHub、GitLab 不在一个层级。如果你刚接触容易产生“GitHub 就是 Git”的误解。实际上哪怕不用 GitHub你也可以在本地用 Git 管理项目反过来GitHub 上托管的所有内容本质上都是一个个 Git 仓库只是平台在 Git 的功能之外又加了网页界面、权限管理、自动化流水线等能力。2. GitHub 和 GitLab同样是托管平台差别在哪里有不少人问GitHub 和 GitLab 到底选哪个这个问题没有标准答案取决于你是在做开源项目、个人项目还是在公司内网搭协作环境。我先用一句话概括两者最核心的差异GitHub 更适合开放社区和外部协作GitLab 更适合需要私密性和一体化流程的团队自托管。2.1 GitHub 的优势与适用场景GitHub 是目前全球最大的代码托管平台很多开源项目都在上面。它的特点包括Pull Request 机制非常成熟。你改动一个分支后可以发起 Pull Request让别人在网页端逐行查看改动、留言、评审确认后再合并。整个流程公开透明非常适合开源协作。生态丰富。Actions 可以直接在仓库里跑测试、构建、部署还有大量第三方应用可以订阅省去自己搭 CI/CD 的麻烦。社区氛围强。Issue 讨论、星标、Fork 这些机制让项目不仅是一个代码仓库还是一个交流平台。但 GitHub 的私有仓库在早期很受限制虽然现在私有仓库也免费了但更高级的权限管理、审计功能、容量限制还是要付费。个人和小团队用起来很舒服对需要严格控制权限的大型企业来说可能就不够灵活。2.2 GitLab 的优势与适用场景GitLab 的定位从一开始就更偏向“企业级”。它最大的特点是支持自托管你可以把整个 GitLab 安装在自己的服务器上代码不出内网数据安全可控。加上 GitLab 自身集成了 CI/CD、容器镜像仓库、需求管理、Wiki 等能力一套系统能覆盖从代码托管到交付部署的完整链路。如果你们团队已经有自己的服务器又有较强的运维能力GitLab 能帮你省掉很多对接外部服务的麻烦。反过来如果只是个人学习、做开源项目GitLab 当然也能用但它的社区资源、插件生态、Findability可发现性相对差一点。一个比较常见的决策方式是比较维度GitHubGitLab开源项目展示很强一般私有仓库体验方便但高级能力有限灵活且权限细粒度高自托管一般不建议核心优势CI/CD 集成Actions 好用原生流水线很完善上手门槛更低功能多、配置稍复杂这里没有绝对的好坏。我自己见过一个团队对外开源项目放 GitHub内部项目管理放 GitLab两边同步用脚本处理也是一种思路。关键是先明白每种工具的核心理念别只听别人说哪个好就盲选。2.3 从提交到合并一次完整的协作走查不管用 GitHub 还是 GitLab核心协作流程是相通的。我以 GitHub 的 Pull Request 为例说明拿到任何平台都可以照搬思路先把主分支main最新代码同步到本地git pull origin main。基于最新主分支创建自己的功能分支git checkout -b feature/login。在功能分支上改代码分步提交过程尽量频繁但每个提交都有意义。推送到远程同名分支git push origin feature/login。在网页端发起 Pull Request让评审者看改动、留言讨论。评审通过后合并到主分支通常选择 squash 合并或普通合并看团队习惯。合并完成后删除功能分支保持仓库整洁。这套流程的关键不是具体命令而是永远不要在主分支上直接改代码。主分支应该是稳定的、可发布的所有风险都留在功能分支和评审环节里消化。这一点比学会某个按钮重要得多。3. 快速上手用 VSCode 操作 Git 的完整流程现在开始实操部分。我会按一个真实的开发场景来走新建项目、初始化仓库、提交代码、连接远程仓库、推送、拉取、创建分支、解决冲突。全程用 VSCode 的图形界面为主命令为辅因为图形界面能让你直观看到文件状态命令则能帮助你理解每一步实际发生了什么。3.1 准备工作安装 Git 和 VSCodeVSCode 内置了 Git 支持不需要额外装插件就能完成大部分操作所以我默认你已经装好了 VSCode。还有一步是安装 Git 本身安装包可以从 Git 官网下载安装时保持默认选项即可。安装完成后打开终端Windows 用 PowerShellmacOS 用 Terminal执行git --version如果能输出版本号说明安装成功。接着配置用户名和邮箱这一步会在提交时记录在历史里非常重要git config --global user.name Your Name git config --global user.email youexample.com这里的--global表示对当前电脑上的所有仓库生效。如果某个项目需要不同的身份可以在项目目录里去掉--global单独配置。3.2 用 VSCode 初始化仓库并完成第一次提交打开 VSCode用“打开文件夹”打开一个项目目录。左侧会有一个“源代码管理”图标长得像一个分支符号。如果项目还没有纳入 Git 管理点击该图标后会看到“初始化仓库”按钮点击后 VSCode 会在项目根目录生成一个.git文件夹这就是本地 Git 仓库的载体。如果你更喜欢命令行也可以在项目根目录执行git init初始化后你在项目里新增或修改文件左侧源代码管理面板会列出所有变更文件未跟踪的文件会标上字母U修改过的文件标M删除的文件标D。这些状态非常重要一眼就能看出哪些改动还没提交。第一次提交建议先创建.gitignore文件把不需要纳入版本管理的文件排除掉比如node_modules、.env、编译产物等。一个常见的.gitignore片段node_modules/ dist/ *.log .env .idea/ .vscode/然后在源代码管理面板的文件列表上点击“”号暂存改动或者执行git add .。这一步把改动放进暂存区。接着在输入框里写提交信息点击对勾图标完成提交相当于执行git commit -m 第一版项目结构提交后你会发现源代码管理面板空了说明工作区和暂存区都已经干净。用git log --oneline可以看到刚生成的提交记录。3.3 连接远程仓库并推送到 GitHub 或 GitLab本地仓库只是第一步真正的协作需要远程仓库。假设你在 GitHub 或 GitLab 上新建了一个空仓库远程地址通常是https://...格式。在 VSCode 终端执行git remote add origin 你的远程仓库地址这个命令把远程仓库命名为origin命名本身只是习惯不一定非叫这个但业界默认都用origin指代主要远程仓库。接下来推送git push -u origin main-u的意思是把本地main分支和远程main分支建立跟踪关系之后直接执行git push或git pull就能自动知道和哪个远程分支对接。推送完成后打开远程仓库网页就能看到完整的项目文件了。如果远程仓库已经有内容而本地是全新仓库推送时可能会被拒绝提示两个仓库的历史不相关。这时候要先拉取远程内容并合并git pull origin main --allow-unrelated-histories这个参数允许两个没有共同提交的仓库合并一次之后继续开发就正常了。3.4 用 VSCode 拉取代码和推送更新的完整场景假设你第二天继续开发远程仓库里可能已经有同事提交的新代码。在源代码管理面板顶部有几个图标刷新、拉取pull、推送push。点击拉取会自动执行git pull把远程改动合并到本地当前分支。如果拉取时有冲突VSCode 会弹出冲突文件列表文件里会显示类似下面的内容 HEAD 本地修改的内容 远程修改的内容 origin/main你需要手动决定保留哪些内容把、、这些标记删除保存文件后再提交一次。这个过程叫“解决冲突”是协作开发里最需要耐心的环节。我通常会建议遇到冲突先别慌仔细看两边改动如果无法判断找相关同事当面确认比瞎合并安全得多。3.5 分支操作用 VSCode 创建和切换分支日常开发中分支几乎天天用。在 VSCode 左下角可以看到当前分支名点击后会弹出分支列表和创建新分支的输入框。输入一个功能名比如feature/user-login确认后当前分支就切换过去了。等价命令是git checkout -b feature/user-login在功能分支上提交代码不会影响主分支。开发完后切回主分支再执行合并git checkout main git merge feature/user-login这里有一个经验在合并前先拉取最新的主分支否则本地主分支和远程主分支可能已经分叉合并出来的结果不是最新状态。4. 几个必须养成的 Git 操作习惯与避坑记录工具学起来快但真正拉开差距的是使用习惯。我自己刚接触 Git 时犯过不少错这里整理几条对新手最有用的经验顺便解释一下背后的原因。4.1 提交粒度宁多勿少提交信息要能看懂提交是给未来的自己和其他同事看的。不要等到一个功能全部写完才提交更不要把十几个不相关的改动混在一个提交里。正确做法是每完成一个小步骤就提交一次提交信息用一句话说明“为什么改”而不是“改文件”。比如好的提交信息修复登录页在移动端点击无效的问题差的提交信息update更差的提交信息111团队协作时如果提交信息一团糟未来排查问题时几乎等于没有历史。这个习惯不需要额外工具只要在每次 commit 前多想十秒。4.2 不要直接在主分支上开发哪怕你是单人项目单人项目确实可以只在main分支上直接提交看起来省事。但一旦项目进入多人协作或者需要同时维护多个版本直接在主分支上开发就会变成灾难。我见过太多事故都是因为有人在主分支上改了一半然后紧急需求插入导致没做完的代码也被带上线。哪怕只是自己练手也建议从第一天开始习惯分支开发。先建分支改完后合并回主分支再删除分支。这个动作成本极低带来的安全感和秩序感却很高。4.3 不小心提交了不想提交的文件怎么办很多人第一次用git add .就会后悔因为把临时文件、密码文件、编译产物全加进来了。如果只是暂存还没提交可以执行git reset HEAD .相当于把暂存区的改动退回工作区。如果已经提交了但还没推送可以撤销最近一次提交但保留改动git reset --soft HEAD~1如果已经推送到远程千万不要用reset去“改写历史”因为远程仓库已经被别人拉过强行改写可能导致大家仓库状态不一致。这时候用git revert生成一个反向提交把已推送的内容撤销掉git revert HEAD同样能回退代码但不会重写历史对协作更安全。4.4 关于pull和rebase的个人选择默认情况下git pull等于git fetchgit merge。这会产生一个分叉合并的提交记录看久了显得杂乱。如果团队希望历史更线性可以使用git pull --rebase它的意思是在拉取远程新提交之后把你本地未推送的提交“搬”到最新提交的后面而不是生成合并节点。但我给新手的建议是前期先用默认的merge方式先理解冲突和分支的机制再决定是否引入rebase。rebase确实让历史更干净但操作不当会改写提交对不熟悉的人来说风险更大。5. 常见问题与排查技巧实录按下方的表格整理是我在带新人时最常遇到的几类问题每个都附上了排查思路你可以直接对照自己的现象。现象可能原因解决办法提交时报 “Please tell me who you are”没配置 user.name 和 user.email执行git config --global user.name 你的名字和git config --global user.email 你的邮箱VSCode 源代码管理看不到任何文件项目目录不是 Git 仓库点击“初始化仓库”或在终端执行git init推送时提示remote rejected远程有本地没有的提交先git pull或git pull --rebase解决冲突后再推送拉取后文件内容变成冲突标记多人改同一处代码手动编辑冲突文件删除、、标记然后提交合并结果误删了还没合并的分支分支引用被删用git reflog查找分支最后一次提交再用git branch 分支名 提交ID恢复提交后发现密码文件被上传.gitignore 没配置或忘记 exclude生成反向提交删除文件立即在 .gitignore 中补充规则并轮换已泄露的密钥出现LF will be replaced by CRLF警告Windows 和 Linux 换行符差异团队统一配置.gitattributes或在 Git 安装时选择“checkout as is, commit as is”5.1 使用git reflog找回误删分支这个问题我想单独说一下因为太实用了。有一次我在本地清理分支手一抖把还没合并的功能分支删了当时心态有点崩。后来发现 Git 会记录你在这个仓库里的所有引用变动哪怕分支被删提交对象也不会立刻被回收。执行git reflog能看到一串操作记录包含提交 ID。找到删除前那个分支最后一次指向的提交 ID然后执行git branch recover-old-branch 提交ID分支就回来了。这个命令是我见过最反直觉的“后悔药”代价仅仅是提交 ID 还留在 reflog 里。注意 reflog 日志也会过期清理但默认 90 天内基本没问题。5.2 VSCode 里常见的状态图标是什么意思VSCode 源代码管理面板默认会显示文件状态图标含义如下U未跟踪文件从未被 Git 记录。M文件已修改尚未暂存。A新文件已暂存。D文件已删除。R文件重命名。C文件复制。只要看到这些字母就能快速判断当前工作区状态。如果不确定某个改动是不是需要的可以用 VSCode 自带的 diff 功能点击文件会在右侧打开改动对比绿色部分是新增红色部分是删除。这个功能比用眼睛盯着终端输出直观多了。5.3 冲突解决时的个人技巧我解决冲突时有一个固定顺序先在脑海里明确当前分支和对方分支各自的目标再逐段看冲突标记。如果文件大、冲突多我一般会先用 VSCode 针对冲突文件搜索确保没有遗漏的冲突标记然后逐个解决。解决完一定不要急着提交先确认所有测试通过。还有一个经验如果你连续改了好几个文件解决冲突只发生在其中一个文件上但其他文件也都被 Git 标记为“已修改”。这里的git status会显示Unmerged paths绿色表示已暂存、红色表示未暂存。需要把所有解决完的冲突文件都git add再执行git commit --no-edit这个命令会直接沿用冲突合并生成的提交信息不需要手动输入。5.4 关于 .gitignore 的一个常见误操作很多人把.gitignore写好后却发现文件仍然被追踪原因是该文件在加入.gitignore规则之前已经被 Git 跟踪了。.gitignore只对未跟踪的文件生效已经被追踪的文件不受影响。解决办法是先把文件从 Git 索引中移除git rm --cached 文件名执行后再提交一下之后该文件就会真正被忽略。如果是一个文件夹可以用git rm -r --cached 文件夹名这套操作我在换项目环境时经常用尤其是在初始化仓库时忘了配.gitignore的后续补救。6. 给从 SVN 转过来的朋友几句真心话最后针对老 SVN 用户多说几句。我刚从 SVN 转到 Git 的时候最大的不适应不是命令而是心理模型。SVN 的思维是“东西在服务器上我本地只是一份拷贝”所以提交前总担心断网、担心冲突Git 的思维是“我本地就是完整仓库服务器只是同步点”所以本地操作非常自由。这种转变带来的直接好处是你可以大胆创建分支、大胆实验做坏了直接删掉重新开一个。你不需要在 SVN 里复制目录那样小心翼翼地创建分支也不需要担心合并成本太高。Git 的底层设计把“试错”的成本变得极低这其实是它最被低估的价值。我还记得第一次用git rebase -i整理本地提交历史的感觉把几个混乱的提交合并成一条清晰的记录那种掌控感是 SVN 完全给不了的。但我也要提醒一句rebase这种事情只对还没推送到远程的提交做一旦推出去就不要再改写历史否则其他人的本地仓库会和你“失联”。我自己的建议是先花一个下午把 Git 的命令行基础过一遍再用 VSCode 的图形界面做日常操作两者结合是最舒服的状态。不要害怕冲突冲突不是 Bug而是 Git 在提醒你“这里需要人类来判断”。多冲突几次你就会慢慢理解版本控制的核心不只是记录代码更是保护团队的协作节奏。