讲到 git 使用大多数教程上来就是让你背命令git add、git commit、git push一步步敲下去。但真正把 Git 用好靠的不是背命令而是理解它背后的版本管理思路。我见过太多团队工具装好了、仓库建好了结果三天两头出现覆盖代码、提交信息写成update、合并冲突不知道怎么解的情况。其实这些问题的根源几乎都不是 Git 本身难学而是没有建立一套适合自己的使用习惯和提交规范。这篇文章我会从零开始把 Git 的使用方式完整走一遍先讲清楚它到底解决了什么问题、三个区域是怎么回事然后带你装环境、写配置、上手高频命令再到提交规范和免密配置最后把我踩过的坑和排查思路汇总成速查表。不管你是刚接触 Git 的初学者还是被各种疑难杂症折腾过几次的老朋友按照这个顺序过一遍应该都能把日常开发中的版本管理理顺。1. Git到底解决了什么问题先把使用思路捋顺1.1 版本控制的本质给项目装一个时间机器很多人学 Git 第一反应是这不是代码管理工具吗但我觉得更合适的类比是游戏存档。你打游戏打到一半存个档后面操作失误了、BOSS 打不过去了随时读档重来。Git 做的事情完全一样每一次 commit 就是一个存档点存完之后你可以放心大胆地改代码改坏了就回到上一个存档。没有版本控制的时候是什么状态写论文的人最有体会桌面上一堆最终版_v3_真的最终版.docx。代码项目比文档更严重因为代码是多人协作的A 改了一部分、B 改了一部分最后拿 U 盘拷来拷去拷贝的时候谁覆盖了谁的改动都说不清。Git 的设计就是来解决这两个问题的一是后悔药二是多人并行协作还不打架。Git 是分布式版本控制系统这个分布式的意思和 SVN 那种中央集权式完全不同。SVN 的仓库只有一个中心服务器你提交代码必须联网连服务器。Git 不一样每个人的本地都有一份完整的仓库历史没网也能提交、能看日志、能回退等有网了再推送到远端。这就意味着日常开发里 99% 的操作都是本地进行的速度极快不受网络影响这也是它能成为行业标配的根本原因。1.2 三个区域工作区、暂存区、历史区用 Git 之前至少要先把三个区域这个概念刻进脑子里否则后面所有的命令都像在背咒语。三个区域分别是工作区Working Directory你肉眼能看到的那些文件就是编辑器里打开、改动的实际文件。暂存区Index / Staging Area可以理解成一个待提交清单。你告诉 Git这几个文件的改动我要提交它们就会被放进暂存区。本地仓库HEADcommit 之后改动才真正生成一个存档点进到 Git 的历史里。用一个生活场景来套工作区是你家厨房暂存区是购物车历史区是仓库。你把菜放到购物车git add结完账把东西搬回家放仓库git commit。你完全可以只把购物车装满但不去结账只 add 不 commit也可以随时把购物车里的东西放回货架git reset / git restore。这个模型是所有 Git 命令的地基。搞清楚了它你再看git add、git commit、git reset、git restore这些命令就明白它们其实只是在往不同的区域搬东西而已。遇到我不小心 add 错了怎么办我 commit 之后想改怎么办这类问题本质上就是在问东西现在在哪个区域、我要把它搬到哪里去。2. 安装与配置把Git环境一次搭对2.1 三个平台的安装步骤与版本选择安装 Git 本身没什么难度但有些小选项选不对后面会不停踩坑。先说下载方式。Windows 用户直接去 Git 官网 git-scm.com 下载 Git for Windows安装包是 exe双击一路往下走。安装过程中的几个关键选项我单独提一下默认编辑器建议选 Visual Studio Code如果没有就选 Notepad 或 Vim不要用默认的 Vim因为新手在 Vim 里连保存退出都不会很容易卡死在提交窗口。调整 PATH 环境变量一定要选第二项或第三项推荐第三项 Git from the command line and also from 3rd-party software这样才能在终端、IDE 里正常调用 git 命令。配置行结束符转换保持默认的 Checkout Windows-style, commit Unix-style line endings 就行团队协作时这个默认值能避免大部分换行符问题。Git Credential Manager保留默认启用后面免密配置会用到。macOS 用户有两个选择一是装官方 dmg 包二是用 Homebrew 执行brew install git。个人推荐 brew因为后续升级方便brew upgrade git就完事。Linux 就更简单了Ubuntu/Debian 用sudo apt install gitCentOS/RHEL 用sudo dnf install git。装完之后打开终端验证一下输入git --version能输出版本号就说明装好了。我见过不少装完了不知道装没装上的情况所以这条命令建议成为你环境搭建的标准动作。另外提醒一句如果你在网页教程里看到git -c diff.mnemonicprefixfalse -c core.quotepathfalse --no-optional-locks这种超长命令不用慌那是某些 IDE特别是一些国产编辑器在后台调用 Git 时自动加的开关core.quotepathfalse是关掉中文文件名的转义--no-optional-locks是避免 Git 在 diff 时异步更新索引文件属于工具自动行为普通人不用手动敲。2.2 第一次 commit 前必须做的两件事装完 Git 先别急着 clone 仓库有一件事不做你的每次提交都会有麻烦配置用户名和邮箱。很多新手跳过这一步结果 commit 的时候 Git 会从系统里猜一个身份或者干脆提交失败报一堆看不懂的错。在终端里执行这两条命令git config --global user.name 你的名字 git config --global user.email 你的邮箱example.com这里的--global表示全局配置写一次之后这台机器上的所有仓库都会用。邮箱不一定非要用真实邮箱但强烈建议用你代码托管平台比如 GitHub、Gitee、GitLab上注册的那个邮箱这样提交记录才能和你的账号关联上头像、贡献度、代码评审里的关联信息才能正确显示。Git 的配置分三个层级--system整台机器、--global当前用户、--local当前仓库。三者的优先级是 local global system也就是说你可以在某个项目里单独覆盖身份信息。为什么需要这个比如你同时给两家公司干活公司 A 的仓库要用公司邮箱公司 B 用个人邮箱这时候就在各自仓库目录下用--local配一次就行。查看当前所有配置用git config --list只想看某一项用git config user.name。配置信息会保存在用户目录下的.gitconfig文件里你完全可以手动编辑这个文件格式很直白。2.3 终端选择Git Bash、Windows Terminal 和小乌龟命令行是 Git 的主战场但很多人一开始是抗拒的这很正常。我建议分三个场景来选工具。第一个场景是纯命令行Windows 上推荐 Git Bash它比 CMD 和 PowerShell 对 Git 的支持更自然而且支持很多 Linux 命令ls、grep、cat 都能用新手和老手都舒服。macOS 和 Linux 直接用系统自带终端就行。第二个场景是图形化工具最出名的是 TortoiseGit也就是大家常说的小乌龟。它在 Windows 资源管理器右键菜单里直接提供各种 Git 操作提交、拉取、看日志都非常直观对完全不想碰命令行的人很友好。但我必须说实话图形工具虽然上手快可一旦遇到冲突、历史改写这类复杂情况你不懂底层命令连图形界面里的按钮都看不懂是干什么的。所以我的建议是小乌龟可以当辅助工具用但主力操作尽量还是命令行。第三个场景是 IDE 集成。现在 VSCode、Cursor、JetBrains 全家桶都内置了完好的 Git 面板日常的提交、推送、查看改动、解决冲突在编辑器里就能搞定效率很高。很多人问Cursor 哪里查看绑定 Git其实和 VSCode 一样左侧活动栏最下面有个源代码管理图标一个分支样子的图标点开就能看到当前仓库的分支、改动文件、提交按钮想确认当前绑定的是哪个远端仓库点右上角的...菜单选远程就能看到 remote 地址。我给大多数朋友的建议组合主力用命令行操作 add、commit、push 这些高频动作用 IDE 的 Git 面板看 diff 和快速解决冲突偶尔需要看完整分支历史、找某次提交引入的变更时再打开小乌龟或者其他图形工具。三个工具各干各擅长的部分反而最省心。3. 高频命令拆解日常开发就靠这十来个3.1 本地提交流水线status、add、commit、log几乎所有 Git 操作都是从这四兄弟开始的。很多人把它们背下来了但还是不知道什么时候该用哪个我逐个讲一下。git status是你随时都要敲的命令它会告诉你当前仓库处于什么状态哪些文件被修改了、哪些文件已暂存、当前在哪个分支。我建议养成敲任何 Git 命令之前先看一眼 status的习惯它会明确告诉你下一步该做什么。git status -s是短格式输出更简洁适合高频使用。git add是把文件从工作区挪到暂存区它可以接具体文件名、目录名也可以接git add .把当前目录所有改动加进去。我的个人建议是尽量不要养成git add .的习惯因为你不知道工作区里到底多了哪些文件万一带进去一个不该提交的临时文件就麻烦了。用git add src/xxx.js tests/xxx.test.js这种方式至少你明确知道自己在提交什么。git commit是生成存档点。git commit -m 提交信息是日常最常用的写法如果是多行提交信息可以不加 -m 直接执行git commitGit 会打开你配置的编辑器让你写详细描述。提交之后这次改动就被固化成历史了git log可以查看所有历史记录。git log以及它的各种参数值得单独说说git log # 完整历史每条包含 hash、作者、日期、提交信息 git log --oneline # 每条历史只显示一行缩写 hash 提交信息 git log --graph --all # 图形化显示分支结构 git log -p # 显示每次提交的具体改动内容我用git log --oneline --graph --all最多一条命令就能看到所有分支的拓扑结构谁在上面、谁落后了多少提交一目了然。3.2 远程协作clone、push、pull、fetch本地仓库搞得再溜不打通远程仓库就无法和别人协作。远程这块最常用的命令是 clone、push、pull。git clone拉取远程仓库它有两种地址形式HTTPS 地址和 SSH 地址。HTTPS 路径长这样https://github.com/user/repo.gitSSH 路径长这样gitgithub.com:user/repo.git。两者的本质区别我在后面的免密配置章节细讲这里先记住一点如果之后想免密 pushclone 的时候就要用 SSH 地址这点非常容易踩坑。git push把本地提交推送到远程git push origin main是推送到名为 origin 的远程仓库的 main 分支。第一次推送新分支时用git push -u origin feature/xxx-u 的意思是设置上游分支之后在这个分支上直接敲git push就行不用再写远程和分支名。git pull是把远程的新提交拉下来合并到本地。它其实是两条命令的合体git fetchgit merge。但这里有个重要的概念差异git fetch只是把远程的新提交下载到本地并不会动你的工作文件你可以看看远程更新了啥再决定怎么处理git pull则是直接下载并合并很可能触发冲突。我的习惯是想了解远程进展用 fetch确定要合并远程改动到当前分支了才用 pull。查看当前仓库绑定的远程地址用git remote -v它会列出所有远程仓库的 fetch 和 push 地址。有时候你发现 push 到了错误的仓库、或者想把远程地址从 HTTPS 换成 SSH用git remote set-url origin 新地址就可以。3.3 分支和合并让多人协作不乱套分支是 Git 里最强大的功能也是很多人实践最少的操作。打个比方分支就是游戏的平行存档你可以在主干线上正常开发同时在另一条线尝试一个新功能两条线互不干扰最后把新功能验证好了再合并回主线。日常使用中我强烈建议从一开始就养成功能分支开发的习惯。不要直接在 main或 master上改代码而是为每个功能或者每个 bug 单独建一个分支。分支的命名一般遵循类型/描述的格式比如feature/user-login、fix/cart-price-bug、docs/readme-update。原因很简单主线永远保持可发布状态你在分支上随便折腾都不影响别人功能稳定后再合并回主分支。分支相关的命令git branch # 查看本地分支当前分支前面有 * 号 git branch -a # 查看本地和远程全部分支 git branch feature/xxx # 创建新分支 git switch feature/xxx # 切换到指定分支新版推荐老版用 git checkout git switch -c feature/xxx # 创建并切换等价于 git checkout -b feature/xxx git merge feature/xxx # 把 feature/xxx 合并到当前分支 git branch -d feature/xxx # 删除已合并的分支合并这里有个争议用 merge 还是 rebase。日常协作我建议默认用 merge因为 merge 会保留真实的合并历史回退和排查都更安全。rebase 适合在自己本地整理提交历史把多个小提交压成一个或者把分支基底更新到最新主分支但 rebase 会改写历史千万不要对已经推送到远程的分支做 rebase否则同事会疯掉。另外提醒一下很多人在网上看到git checkout的用法但新版 Git 更推荐git switch和git restore这两个更清晰的分工switch 只管切分支restore 只管恢复文件。老命令 checkout 身兼数职对新手容易造成混淆。4. 提交规范与 .gitignore让协作干净可回溯4.1 提交信息为什么要规范如果你在一个团队里打开git log看到的是这样的历史update fix 修改 1 222 asdf你会是什么感受根本没法用。你只知道某个文件被改过很多次但完全不知道哪次改了什么、为什么改。等哪天线上出问题需要回溯时只能一条一条看 diff效率低到崩溃。提交信息的本质是给未来的人包括未来三天的你自己留的便签。规范的提交信息能让你一小时内从历史里定位到具体问题不规范的提交信息会让排查历史变更变成一场灾难。所以提交规范不是形式主义是团队协作效率的一部分。一个简单但有共识的规范就是使用类型 描述的结构让每个人扫一眼就知道这次提交属于什么类别、做了什么。4.2 常用提交类型与格式模板目前业界比较通行的提交消息格式是 Conventional Commits但你不必把它想得那么复杂核心就是一句话type(scope): subjecttype 是提交类型scope 是影响范围可选比如模块名subject 是简要描述。常用类型有这些feat新增功能例如feat(login): 增加手机号登录方式fix修复 bug例如fix(cart): 修复购物车数量为0时无法删除的问题docs文档变更例如docs(readme): 补充安装说明style代码格式调整不改逻辑例如style(button): 调整按钮缩进refactor重构代码不增功能不修 bug例如refactor(user): 拆分用户验证逻辑test新增或修改测试例如test(api): 增加登录接口单元测试chore构建、工具链、依赖等杂项例如chore: 升级 eslint 到 9.xperf性能优化例如perf(list): 优化长列表渲染速度subject 部分建议用祈使句或简洁短语能一眼看懂就行。别写修改了一堆东西这种话写了等于没写。粒度上一次提交只做一件事。你改了一个 bug顺手又改了个样式应该分成两条 commit而不是混在一起因为将来如果这个 bug 要回退混着的提交会把样式改动也一起带回去。如果你 commit 完之后发现消息写错了或者漏提交了一个小改动可以用git commit --amend把最近一次提交的信息修改掉或者把一个小改动追加进上一次提交。注意这个操作是改写历史只适用于还没推送的提交。4.3 .gitignore 的正确写法与常见坑.gitignore这个文件平时不起眼但很多人因为没配好它吃了大亏。它的作用是告诉 Git某些文件或目录不要纳入版本管理。最经典的问题是把node_modules提交进仓库。一个依赖目录动辄几百 MB提交进去之后仓库体积爆炸其他人 clone 下来还带着一堆跟他本机环境无关的文件害人害己。类似的还有.env环境变量通常含密钥、dist构建产物、target、*.log等。.gitignore 的基本语法很简单# 注释用井号 node_modules/ # 忽略整个目录 dist/ # 忽略构建输出目录 *.log # 忽略所有日志文件 !.gitkeep # 不忽略 .gitkeep 文件用于保留空目录 .DS_Store # macOS 的目录元数据文件 .env # 环境变量文件GitHub 上有非常完整的官方模板库 github/gitignore里面按语言和框架整理了.gitignore模板直接拿来改改就能用。VS Code、JetBrains 这些 IDE 在创建项目时也可能自动生成一份你可以改它而不是删掉它。这里有一个非常经典的坑必须单独强调.gitignore只对尚未被跟踪的文件生效。如果你之前已经把node_modules提交过了现在在 .gitignore 里加一行node_modules/是没用的因为 Git 已经把它纳入了跟踪。你需要先把它从版本控制中移除再靠 .gitignore 拦住git rm -r --cached node_modules--cached的意思是只从 Git 的索引里移除不动你本地文件。执行完这条命令再提交一次node_modules 才会真正脱离版本管理。5. 免密配置再也不用每次push输密码5.1 先选协议HTTPS 还是 SSH每次 push 都要输用户名密码输几次就烦了。要彻底解决先要搞明白远程仓库的两种访问协议。HTTPS 方式最直观clone 地址是https://xxx.gitpush 时输入账号密码现在各大平台出于安全考虑密码基本被 Personal Access Token 取代了你输入的是 token 不是密码。优点是简单、兼容性最好很多企业内网只开放 HTTPS 端口缺点是每次都要输凭据体验差点。SSH 方式基于公钥密钥对clone 地址是gitgithub.com:user/repo.git。你生成一对公钥和私钥把公钥放到代码托管平台上私钥留在本地之后所有操作都基于密钥完成完全不需要输密码。优点是免密、稳定、更安全私钥不出本机缺点是需要配置一次而且某些环境会封 22 端口需要特殊处理。我的建议是个人项目、长期使用的项目优先 SSH只是临时 clone 一个公开仓库看看代码HTTPS 就够了反正不需要 push。5.2 SSH Key 配置三步走SSH 免密配置整个过程三步生成密钥、添加公钥到平台、测试连通性。第一步在终端执行ssh-keygen -t ed25519 -C 你的邮箱或备注一路回车即可默认会在~/.ssh/下生成两个文件id_ed25519私钥和id_ed25519.pub公钥。如果你之前已经生成过可以不加-C重新生成但注意会覆盖旧密钥要谨慎。第二步查看公钥内容并复制cat ~/.ssh/id_ed25519.pub然后登录你的代码托管平台找到 SSH Keys 设置页GitHub 在 Settings → SSH and GPG keys → New SSH keyGitee 在个人设置 → SSH 公钥GitLab 在 User Settings → SSH Keys。把复制的公钥内容粘贴进去保存。第三步测试连通性。不同平台的测试命令不一样ssh -T gitgithub.com # GitHub ssh -T gitgitee.com # Gitee ssh -T gitgitlab.com # GitLab看到Hi username! Youve successfully authenticated之类的提示就说明配置成功了之后 clone 和 push 都不用再输凭据。5.3 两个常见的免密坑第一个坑clone 的时候用的是 HTTPS 地址。很多人配置完 SSH key发现每次 push 还是要密码排查半天最后一看git remote -v远程地址还是 HTTPS。SSH key 只对 SSH 协议的请求生效你 clone 的是 HTTPS 地址当然要输凭据。解决办法要么重新用 SSH 地址 clone要么改远程地址git remote set-url origin gitgithub.com:user/repo.git。第二个坑公司网络封了 SSH 的 22 端口。表现是ssh -T gitgithub.com卡住或报 Connection refused。这时候两个方案一是改用 HTTPS 凭据管理器Git Credential ManagerWindows 装 Git 时自带的那个它会帮你记住 token二是把 SSH 端口配置成 443在~/.ssh/config里加Host github.com Hostname ssh.github.com Port 443配置完再测试连通性能用就说明 443 方案可行。这个技巧对于受限网络环境非常实用。另外就算不配 SSHWindows 上通过 Git Credential Manager 也能做到 HTTPS 模式下第一次输入后记住后续自动用保存的 token 认证。所以不用纠结必须用 SSH两个方案能免密就是好方案。6. 常见问题与排查技巧实录6.1 命令找不到git无法识别Windows 上最常见的报错是git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。这个错误的原因只有一个系统找不到 git.exe。要么没装 Git要么装了但没把 Git 的路径加到 PATH 环境变量里。最典型的场景是安装 Git 的时候那一屏 PATH 选项选错了选了 Use Git from Git Bash only于是 CMD、PowerShell 里就没有 git 命令。解决办法也很简单打开系统设置 → 环境变量在 Path 里加上 Git 的 cmd 目录默认是C:\Program Files\Git\cmd然后重新打开一个终端窗口再执行git --version验证。如果还是不识别检查一下安装路径是不是和默认不一样把实际路径写进 PATH 就行。6.2 中文文件名乱码git status时看到文件名字变成了一串\346\265\213\350\257\225.txt这种八进制转义不是文件坏了是 Git 默认对非 ASCII 字符做了转义。解决办法git config --global core.quotepath false配完之后再git status中文文件名就能正常显示了。另外如果你在 Windows 终端里看到中文乱码还要检查终端编码是不是 UTF-8Git Bash 一般没问题老版本 CMD 可能需要chcp 65001切换代码页。6.3 登录失败token与平台版本兼容有些 IDE 的 GitLab、GitHub 插件会报类似 login failed. check api token or gitlab version 的错误。这个报错信息很有迷惑性它其实在说插件拿着你填的 API token 去请求 GitLab 接口但平台验不过或者版本不兼容。排查思路分三步第一步确认 token 有没有过期现在很多平台默认给个人访问令牌设置有效期过期了就要去平台设置里重新生成。第二步确认 token 的权限范围GitLab 的 token 可以限定 read_repository 还是 write_repository有的操作需要的权限比你申请时的范围大就会报错。第三步确认 GitLab 版本太旧的 GitLab 服务器可能不支持新版 token 格式或不支持某些 API 接口这种情况可以换个方式用 IDE 自带的账号登录流程比如 JetBrains 的 GitLab 登录它会走完整的 OAuth 流程比手动填 token 更省心。HTTPS push 时频繁要密码也属于这一类。现在 GitHub 已经不支持用账号密码 push 了要用 Personal Access Token 当作密码很多教程还在讲旧方法这就导致你本地明明密码是对的push 却一直失败。6.4 合并冲突与误操作恢复合并冲突是 Git 使用里绕不开的一关很多人第一次遇到冲突时特别慌其实冲突的解决逻辑非常固定。当你 merge 或 pull 时发生冲突Git 会把冲突文件里两边不同的内容用标记标出来。打开冲突文件你会看到 HEAD 这里是你当前分支的代码 这里是要合并进来的代码 feature/xxx你需要做的是把、、这些标记删掉决定保留哪边的代码或者手工改成最终想要的逻辑。改完之后git add这个文件再git commit完成合并。用 VSCode 或小乌龟解决冲突会有图形化界面点一下接受当前更改或者接受传入更改就行比纯手工编辑器舒服很多。误操作这块我把最常见的几种场景整理成速查表场景用什么命令注意事项文件已 add想撤出暂存区git restore --staged 文件不会丢工作区改动工作区改动想全部丢弃git restore .改动直接没了慎用commit 完发现消息写错git commit --amend -m 新消息只改最近一次提交未推送时最安全本地回退到上一个提交git reset --hard HEAD~1会把工作区一起重置未推送时可用已经推送的提交想撤销git revert commit-hash生成一个反向提交历史不被改写这里最容易被坑的是reset --hard它真的会把你工作区的所有未提交改动抹掉。万一手滑了别慌Git 还有个终极大招git reflog它能查到你所有历史操作记录包括被 reset 掉的那些提交。找到想回的提交 hash 后再执行git reset --hard hash就能找回来。所以 Git 里其实没有真正删不回来的东西除非你清理了 reflog这也是它比文件拷来拷去安全得多的原因。6.5 安全提醒不要把 .git 目录交出去最后提醒一个容易被忽略的安全问题.git目录里存的是整个仓库的完整历史包括你所有提交过的文件内容。如果项目部署到服务器、静态托管平台时把.git目录也一起上传了别人就能直接访问https://你的域名/.git/来下载你的源码历史这就是常说的Git 目录泄露。这不是危言耸听网上有不少专门扫描网站 .git 目录的工具一旦你的站点暴露了 .git等于把源码管道的钥匙交给了别人。防范办法很简单部署时排除所有隐藏文件和 .git 目录比如你用 Nginx 部署可以加一条拒绝规则或者干脆在构建流程里把 .git 目录删掉再上传。检查一下线上环境是否有/.git/HEAD或/.git/config的可访问记录有的话立刻整改。凡是涉及密钥、密码、token 的文件一律不要提交进 Git 仓库使用.env 环境变量.gitignore 里配好。Git 本身是个工具用好了效率翻倍但如果把不该暴露的东西交出去麻烦也很大。这些安全习惯和提交规范一样是使用方式里最容易忽略、但最值得花时间建立的部分。最后聊点我自己用 Git 的习惯。我在本地建了一个~/workspace目录每个项目 clone 下来之后的第一件事是改好 .gitignore、配好 local 级别的 user.email确保这个仓库的提交身份不会带错。提交的时候我很少用git add .而是git add具体文件保证提交内容是自己确认过的不会把临时文件一起带进去。这个习惯帮我少处理了很多次无意义的 revert。Git 这东西入门确实只要十来条命令但真正让它发挥价值的是那套藏在命令背后的规范和流程你早一天建立起来就早一天省心。