讲到 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"这几个文件的改动我要提交",它们就会被放进暂存区。
- 本地仓库(HEAD):commit 之后,改动才真正生成一个存档点,进到 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 git,CentOS/RHEL 用sudo dnf install git。
装完之后打开终端验证一下,输入git --version,能输出版本号就说明装好了。我见过不少"装完了不知道装没装上"的情况,所以这条命令建议成为你环境搭建的标准动作。另外提醒一句:如果你在网页教程里看到git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks这种超长命令,不用慌,那是某些 IDE(特别是一些国产编辑器)在后台调用 Git 时自动加的开关,core.quotepath=false是关掉中文文件名的转义,--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 commit,Git 会打开你配置的编辑器让你写详细描述。提交之后这次改动就被固化成历史了,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.git,SSH 路径长这样:git@github.com:user/repo.git。两者的本质区别我在后面的免密配置章节细讲,这里先记住一点:如果之后想免密 push,clone 的时候就要用 SSH 地址,这点非常容易踩坑。
git push把本地提交推送到远程,git push origin main是推送到名为 origin 的远程仓库的 main 分支。第一次推送新分支时用git push -u origin feature/xxx,-u 的意思是设置上游分支,之后在这个分支上直接敲git push就行,不用再写远程和分支名。
git pull是把远程的新提交拉下来合并到本地。它其实是两条命令的合体:git fetch+git 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.git,push 时输入账号密码(现在各大平台出于安全考虑,密码基本被 Personal Access Token 取代了,你输入的是 token 不是密码)。优点是简单、兼容性最好,很多企业内网只开放 HTTPS 端口;缺点是每次都要输凭据,体验差点。
SSH 方式基于公钥密钥对,clone 地址是git@github.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 key,Gitee 在个人设置 → SSH 公钥,GitLab 在 User Settings → SSH Keys。把复制的公钥内容粘贴进去,保存。
第三步,测试连通性。不同平台的测试命令不一样:
ssh -T git@github.com # GitHub ssh -T git@gitee.com # Gitee ssh -T git@gitlab.com # GitLab看到Hi username! You've 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 git@github.com:user/repo.git。
第二个坑:公司网络封了 SSH 的 22 端口。表现是ssh -T git@github.com卡住或报 "Connection refused"。这时候两个方案:一是改用 HTTPS 凭据管理器(Git Credential Manager,Windows 装 Git 时自带的那个),它会帮你记住 token;二是把 SSH 端口配置成 443,在~/.ssh/config里加:
Host github.com Hostname ssh.github.com Port 443配置完再测试连通性,能用就说明 443 方案可行。这个技巧对于受限网络环境非常实用。
另外,就算不配 SSH,Windows 上通过 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-8,Git 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 这东西,入门确实只要十来条命令,但真正让它发挥价值的是那套藏在命令背后的规范和流程,你早一天建立起来,就早一天省心。