命令敲下去,git status一刷,满屏红色文件名。很多第一次接触 Git 的人都会蒙圈:明明只是改了两行代码,为什么要面对工作区、暂存区、HEAD、origin 这一堆概念?我当年也是这样,但用到现在,我可以很负责任地说:Git 是程序员最值得早点系统学一遍的工具,没有之一。这篇教程不打算讲枯燥的历史,直接从安装配置、常用命令、远程协作到疑难杂症,按我实际摸爬滚打的路径完整走一遍,你照着操作就能上手。
1. 先搞懂Git到底能干什么
1.1 没有版本控制的日常是什么样的
你有没有经历过这种场景:项目文件夹里躺着一堆“最终版”“最终版2”“真最终版”“打死也不改了版”的压缩包?改个需求要小心翼翼复制一份再做,生怕把原来能跑的版本搞坏。
等到产品经理说“还是回到昨天那个样式吧”,你只能翻遍聊天记录、解压十几个压缩包,挨个启动看效果。更尴尬的是,两个人同时改同一个文件,最后合并时根本没有工具帮你对比差异,只能靠肉眼一行行找。
这些问题,Git 都能解决。它帮你记录每次改动的快照,哪一天、谁、改了什么、为什么改,全部有痕迹。改坏了随时回滚,多人并行开发也不会互相踩踏。说白了,Git 就是代码界的“存档系统”,而且是能开分支、能合并、能协作的高级存档系统。
1.2 统一版本历史和分布式的差别
用过 SVN 的朋友应该知道集中式版本控制的痛点:所有操作都得连服务器,离线就提交不了代码,服务器一挂,历史记录也可能跟着没。
Git 属于分布式版本控制,每个开发者 clone 下来的仓库都是一份完整的历史副本。本地提交不需要联网,服务器挂了也不影响你继续写代码、继续提交,等恢复了再推上去就行。
还有一点非常核心:Git 的分支操作极其轻量。SVN 建分支要复制整个目录,慢且占空间;Git 建分支只是创建一个指针,秒级完成。所以很多团队现在把“分支开发”玩成了日常,每个功能开个分支,开发者各自在分支上折腾,最后合并到主干。这种工作流,没有 Git 之前很难想象。
1.3 学Git前先建立四个概念
如果你一上来就背命令,很容易忘。我建议先建四个心智模型:
- 工作区:你电脑里能看到的项目目录,就是日常写代码的地方。
- 暂存区:一个临时存放区,把想提交的文件先“放进去”,相当于提交前的检查台。
- 本地仓库:
git commit之后,快照就永久落在本地仓库,相当于本地档案柜。 - 远程仓库:GitHub、Gitee、GitLab 上那个服务端仓库,相当于公司档案库,大家共享。
这四个概念记不住,后面命令就老觉得玄学。记住一句话:工作区 → 暂存区 → 本地仓库 → 远程仓库,每一步对应不同的命令,后面就好理解了。
2. 安装与环境配置:Windows 下的一站式方案
2.1 Git for Windows 安装与镜像选择
Windows 下最常规的安装包叫 Git for Windows,官方地址是 git-scm.com。如果官网下载速度实在太慢,可以找国内镜像站点,比如腾讯软件源、淘宝 npmmirror 里的 Git 安装包,版本同步也比较及时。
安装过程基本都是“Next 到底”,但有几个选项我建议你注意:
- Select Components:默认勾选即可,建议把 “Git Bash Here” 和 “Git GUI Here” 保留,右键菜单用起来很方便。
- Default editor:如果没有特别偏好,选 Notepad++ 或 VS Code 都行,别选 Vim,不然以后
git commit弹出 Vim 你都不知道怎么退出。 - Adjusting your PATH environment:务必选第二项“Git from the command line and also from 3rd-party software”。选了这一项,安装完成后在 CMD、PowerShell 里都能直接用
git命令。 - Line ending conversions:一般保持默认
Checkout Windows-style, commit Unix-style line endings,跨平台协作时能避免很多莫名其妙的换行符问题。
安装完之后,打开命令行输入:
git --version如果输出了类似git version 2.47.1.windows.1的版本号,就说明装好了。
注意:装完环境变量要重新打开终端窗口才会刷新。如果你在旧窗口执行
git提示找不到命令,先关掉重开,别急着重装。
2.2 要不要装 TortoiseGit 这个“小乌龟”
很多 Windows 老玩家习惯用 TortoiseGit,也就是常说的“小乌龟”。它最大的特点是集成到鼠标右键菜单,文件夹里能看到文件的状态图标,提交、拉取、更新都靠右键完成,对命令行有恐惧感的人来说非常友好。
我的建议是:新手上路可以把 TortoiseGit 作为辅助工具,但一定不要因此逃避命令。理由很简单,绝大多数文档、教程、CI/CD 脚本、服务器操作还是以命令行为主,你迟早要面对黑窗口。小乌龟适合快速看图、快速提交,真正排查问题还得靠命令行。
下载 TortoiseGit 时注意位数,64 位系统装 64 位版本,语言包单独下载,安装后可以在设置里切换中文。它本身不包含 Git 核心,所以需要先装 Git for Windows 再装小乌龟。
2.3 全局配置:用户名、邮箱、换行符
Git 安装完成后,第一件事不是急着建仓库,而是告诉它你是谁。每个提交记录都会带上提交人的用户名和邮箱,这两个信息不配置,提交时会直接报错。
git config --global user.name "你的名字" git config --global user.email "你的邮箱@example.com"--global表示全局生效,这台机器上所有仓库默认都用这个身份。如果想给某个仓库单独设置,去掉--global在该仓库目录下执行即可。
还可以顺手做几个小配置:
# 默认分支名改为 main,适应现在的主流习惯 git config --global init.defaultBranch main # 提交时自动处理换行符,Windows 用户强烈建议 git config --global core.autocrlf true查看当前所有配置用:
git config --list2.4 配置 GitHub / Gitee 免密登录:SSH Key
每次 push、pull 都要输用户名密码,输三次你就烦了。解决办法是配 SSH Key,配一次就能免密操作。
先在本地生成密钥对:
ssh-keygen -t ed25519 -C "你的邮箱@example.com"一路回车就行,默认保存在C:\Users\你的用户名\.ssh\id_ed25519。生成完用记事本打开.pub文件,把里面内容完整复制。
接下来登录你的 Gitee 或 GitHub,进入设置 → SSH 公钥,把内容粘贴进去保存。最后验证一下:
ssh -T git@gitee.com如果是 Gitee,会提示你“Hi XXX! You've successfully authenticated”,说明配置成功。GitHub 就换成ssh -T git@github.com。
2.5 让 Git 命令更好用的几个小配置
用久了你会发现,有些命令太长,每次敲很烦。Git 支持配置别名,我常用的几个:
git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.lg "log --oneline --graph --all --decorate"配置完之后,git st等于git status,git lg可以看分支图,非常直观。还有个小技巧,如果你觉得终端里显示的中文文件名是转义后的八进制码,可以关掉路径转义:
git config --global core.quotepath false这个选项对国内开发者特别有用,不然文件名含中文时,git status里显示的是\344\270\255\346\226\207这种乱码,看着头大。
3. 常用 Git 命令:从提交到回滚的完整闭环
3.1 初始化仓库与第一次提交
两种方式进入 Git 项目:一种是在已有目录里初始化git init,另一种是从远程克隆git clone。
本地初始化后,开始第一次提交流程:
# 查看当前仓库状态 git status # 把所有改动加入暂存区 git add . # 提交并写提交信息 git commit -m "初始化项目" # 查看提交历史 git log --oneline建议不要一上来就git add .无脑全加。先把git status当成习惯,看清楚哪些文件被修改了,再决定要不要全部提交。我见过太多人把密钥文件、构建产物、IDE 配置一股脑提交进去,后悔都来不及。
3.2 文件状态、暂存与撤销
git status里你会发现文件状态分好几种:未跟踪、已修改、已暂存、无变化。可以用git status -s看简洁版,两列状态提示,左边是暂存区状态,右边是工作区状态。
只提交部分文件时,用git add 文件名逐个添加;想撤销暂存,用:
git restore --staged 文件名仅撤销工作区的改动、恢复到最近一次提交的版本:
git restore 文件名如果你有临时改动不想形成正式提交,可以塞进暂存垃圾桶,后面再取出来:
git stash # 把当前改动暂存起来 git stash list # 查看暂存列表 git stash pop # 恢复最近一次暂存3.3 分支操作与合并冲突处理
分支是 Git 的灵魂。创建一个自己的分支:
git branch feature-login # 创建分支 git switch feature-login # 切换分支 git switch -c feature-login # 创建并切换,一步到位切回主分支用git switch main,老一点的命令是git checkout main,两者现在都支持。切分支时注意,工作区有未提交改动会跟着你“跑”,如果不想带过去,先 commit 或 stash。
合并分支时,如果两个分支改动了同一个文件同一行,就会产生冲突。冲突文件里会出现这样的标记:
<<<<<<< HEAD 这是主分支的代码 ======= 这是功能分支的代码 >>>>>>> feature-login处理方法是手动保留你想要的版本,把三行标记删掉,然后:
git add 冲突文件 git commit -m "合并分支并解决冲突"这里要提醒一句:解决冲突时不要只看自己改的那一段,要结合上下文理解两个分支的意图。我踩过一次坑,合并时保留错了逻辑,导致上线后一个优惠活动把价格算成了负数。
3.4 回滚三兄弟:reset、restore、revert
代码改崩了要回滚,先分清用哪个命令,这很重要。
git restore:只动工作区或暂存区,把单个文件恢复成某个版本。git reset:把当前分支的 HEAD 指针往后退,可以同时影响暂存区和工作区。常用参数:--soft:只移动 HEAD,所有改动还留在暂存区。--mixed(默认):移动 HEAD,改动回到工作区。--hard:改动全部丢弃,不可找回,要非常慎重。
git revert:不删除历史,而是生成一个“反向提交”。比如提交 A 加了一行代码,git revert A就生成一个新提交把这行删掉。
已经 push 到远程的提交,绝对不要用 reset 重写历史,否则别人会拉不下来代码。正确做法是用git revert生成反向修复,再把新提交推上去。
git revert 提交ID3.5 标签与发布版本
给版本打标签,相当于在历史记录上贴一个醒目的标签。比如发了个 v1.0.0,以后想回看这个版本,直接切标签就行。
git tag v1.0.0 git tag -a v1.0.0 -m "发布1.0.0版本" git tag -l标签默认不会自动推到远程,需要显式推送:
git push origin v1.0.0 # 或者一次推送所有标签 git push origin --tags4. 远程仓库协作:从 clone 到 pull request
4.1 本地仓库与远程仓库关联
初始化好的本地仓库,要跟远程仓库建立关联。在 GitHub 或 Gitee 上新建一个仓库,复制 SSH 地址,然后:
git remote add origin git@gitee.com:你的用户名/仓库名.git git remote -vorigin只是默认的远程仓库别名,你可以改成任意名字。如果 clone 下来的项目,origin 已经自动配好,不用重复添加。
4.2 push / pull 的正确打开方式
新手最容易踩的坑,就是改完代码直接git push,结果报错“远端有本地没有的提交”。原因很简单:远程被别人推了新代码,你的本地历史已经和远程分叉了。
正确的流程是:
git pull --rebase # 先把远程更新拉到本地,基于远程最新代码重放本地提交 git push # 再推送--rebase能让提交记录更线性,不容易出现“merge commit 满天飞”的情况。如果觉得 rebase 概念不好理解,刚开始直接git pull也行,就是会产生一个额外的合并提交。记住一条原则:push 之前先看别人有没有更新,别闷头推。
pull其实等于fetch + merge。fetch只是把远程更新拉下来,不改动工作区,之后你可以用git log origin/main查看远程状态;merge才是把远程分支合并进当前分支。想精细控制就用fetch再决定怎么办。
4.3 代码评审与合并请求流程
现在很多团队走的是分支开发 + 合并请求(Pull Request / Merge Request)流程:你开一个功能分支,推送到远程,然后在 Gitee 或 GitHub 上发起合并请求,让同事评审代码,评审通过后再合并进主分支。
这样做的价值不只是流程正规,更重要的是“让代码在合并前多一双眼睛检查”。实际执行时,注意别把一堆无关改动塞进一个合并请求里,每个 MR/PR 尽量只干一件事。Review 的时候不能只看 diff 本身,还要考虑兼容性、命名、异常处理。
4.4 .gitignore 忽略文件该写什么
每个 Git 仓库都应该有.gitignore,告诉你哪些文件不能被 Git 追踪。常见的要忽略:
- 依赖目录:
node_modules/、vendor/ - 构建产物:
dist/、build/、target/ - IDE 配置:
.idea/、.vscode/ - 系统文件:
.DS_Store、Thumbs.db - 环境变量与密钥:
.env、*.pem
要忽略某个已经被提交的文件怎么办?先把它从 Git 索引移除,再添加忽略规则:
git rm --cached 文件名 echo "文件名" >> .gitignore4.5 提交信息规范
代码写得好不好,看提交信息就知道。普通团队至少做到“提交信息说清楚改了什么”,规范一点的团队会按 Angular 规范走:
<type>(<scope>): <subject> feat: 新增功能 fix: 修复 bug docs: 文档变更 style: 格式调整 refactor: 重构 test: 测试 chore: 杂项举个例子:
git commit -m "fix(order): 修复优惠券金额计算为负数的问题"好的提交信息能在排查历史时帮你节省大量时间。我的习惯是:提交信息里永远说“为什么改”,而不只是“改了什么”。
5. 常见问题与疑难杂症速查
5.1 Windows 提示“git 不是内部命令”怎么处理
“git : 无法将‘git’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”——这个报错几乎每天都有新手遇到。原因只有一个:系统 PATH 环境变量里没有 Git 的安装目录。
处理方法分两步:
- 先找到 Git 安装路径,默认是
C:\Program Files\Git\cmd。 - 打开系统环境变量设置,在
Path里新增这个路径,保存后重开终端。
如果找不到安装路径,在开始菜单搜索“Git Bash”,打开后运行:
which git输出结果复制里面的路径,填进环境变量就行。还有一种情况是安装时 PATH 选项选错了,重新运行安装程序,把 PATH 改为第二项即可修复。
5.2 GitLab 登录失败:login failed. check api token or gitlab version
如果你在 IDE 或某些 Git 图形工具里拉取 GitLab 仓库,突然报这个错,大概率是以下原因之一:
- 访问令牌过期:GitLab 出于安全限制,很多私有仓库要求用 Personal Access Token 代替密码,token 过期就需要在 GitLab 设置里重新生成。
- 服务端版本太旧:一些新版本的 IDE 插件,调用 GitLab API 的方式和老版本 GitLab 不兼容。报错信息中有 “check api token or gitlab version”,就是提示你去核查这两点。
解决办法是先在浏览器里正常登录 GitLab,到用户设置里新建一个带read_repository、write_repository权限的 token,然后用用户名加 token 的方式重新认证。如果用的是 IDEA,还可以检查一下是否安装了过旧的 GitLab 插件,更新之后这个报错通常会消失。
5.3 Git 目录泄露是怎么回事
“git目录泄露如何下载”这个热词经常出现在安全相关的搜索里。它指的是:一个网站把整个 Git 仓库部署到了 Web 服务器可以直接访问的目录下,访问者通过http://域名/.git/就能把仓库里的历史记录、源码配置甚至密钥下载下来。
这属于典型的服务端安全配置失误。正确做法是:
- 不要把
.git目录暴露在 Web 根路径下,部署时只发布构建产物或指定目录。 - 在 Nginx 等 Web 服务器里显式禁止访问
.git目录:
location ~ /\.git { deny all; }如果你是开发者,也要留意自己项目在公网上是否可以被外界访问到.git路径。用浏览器或 curl 访问一下你的域名/.git/config,如果能看到内容,就必须马上处理。
5.4 VSCode 集成 Git 的使用
VSCode 内置 Git 支持,不需要装插件就能用。打开项目后,左侧“源代码管理”图标会显示修改文件数量。提交、推送、拉取、分支切换都可以在界面上完成,新手友好度很高。
但有些时候你会在 VSCode 终端看到背后执行的命令:
git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks status这行命令看起来很吓人,其实只是 VSCode 在调用 Git 时加了一些实用参数:--no-optional-locks表示执行状态查询时不获取可选锁,避免因为状态刷新影响正在进行的仓库操作;core.quotepath=false就是前面说的中文文件名显示优化。了解这个之后,遇到类似命令就不用慌了。
5.5 Git 常用命令速查表
这里给一份我日常使用频率最高的命令速查表,建议收藏:
| 场景 | 命令 | 说明 |
|---|---|---|
| 配置 | git config --global user.name "name" | 设置全局用户名 |
| 初始化 | git init | 在当前目录创建仓库 |
| 克隆 | git clone <url> | 从远程复制仓库 |
| 状态 | git status | 查看工作区状态 |
| 暂存 | git add <file> | 添加文件到暂存区 |
| 提交 | git commit -m "msg" | 提交暂存区快照 |
| 历史 | git log --oneline | 查看简洁提交记录 |
| 分支 | git branch -a | 查看所有分支 |
| 切换 | git switch <branch> | 切换分支 |
| 合并 | git merge <branch> | 合并指定分支到当前分支 |
| 拉取 | git pull --rebase | 拉取远程并变基 |
| 推送 | git push | 推送本地提交到远程 |
| 暂存 | git stash | 临时保存当前改动 |
| 回滚 | git revert <commit> | 生成反向提交 |
| 标签 | git tag v1.0.0 | 打标签 |
5.6 几个容易“社死”的低级错误
最后讲几个我亲眼见过、自己也踩过的低级错误:
- 把数据库连接密码提交到公开仓库:就算后边删掉,提交历史里可能还留着,要彻底清除得重写历史。正确做法是任何密钥都不入 Git,统一走环境变量。
- 在错误分支上改了代码:发现切不了分支是因为有改动未提交,我的处理是先
git stash,切到正确分支再git stash pop。 - 合并冲突时乱删别人的代码:这种事最容易被同事吐槽。解决冲突前,先跑一下测试,再看看上下文,别为了“赶紧合上去”而丢掉功能。
- 用 --hard 回滚后懊悔不已:
git reset --hard会丢弃工作区改动,如果之前没有 commit 也没有 stash,基本找不回来。所以操作前一定要git branch留个备份分支,或者先git stash。
我在实际项目里用 Git 这么多年,最深的体会是:命令本身并不难,难的是建立“版本管理”的思维习惯。你不需要把所有参数背下来,但一定要理解状态流转、知道每个操作会留下什么痕迹、会对远端产生什么影响。
另外再多分享一个我的习惯:每次开始一天工作前,先git pull一次,结束时确认今天的改动已提交并推送。这样哪怕电脑硬盘突然坏了,代码也不会丢。Git 这个东西,越早用、用得越狠,后面受益越大。希望这篇教程能让你少走一点弯路,赶紧去把项目里那些“最终版.zip”删了吧。