2、Git与版本控制:从安装到团队协作的完整指南
版本控制这件事,说白了就是给代码拍「后悔药」。我见过太多新手直接拿U盘备份代码,文件夹命名从「项目最终版」到「项目最终版2」再到「项目打死不改版」——嗯,这滋味我懂。但真正进入工程化开发后,Git就是你的第二条命。
这一章我会带你从零搭建Git环境,把常用命令讲透,再聊聊团队协作的分支策略和自动化检查。内容不少,但都是干货。
2.1 Git安装与基础配置
安装Git没什么难度,去官网下载对应系统的安装包就行。Windows用户记得勾选「Git Bash Here」选项,macOS用户用Homebrew会更方便:
# macOS
brew install git
# Ubuntu/Debian
sudo apt-get install git
# 验证安装
git --version
装完之后第一件事是什么?配置身份。Git每次提交都会记录作者信息,这个必须设:
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
我个人习惯还会配几个别名,省得每次敲长命令:
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all"
git config --list 查看所有配置。我曾经遇到过同事提交代码后才发现邮箱配错了,结果贡献记录全乱套——改起来很麻烦。
2.2 核心命令:从初始化到推送
Git的工作流程其实就三个区域:工作区、暂存区、版本库。理解了这个,命令就好记了。
初始化与克隆
# 初始化一个新仓库
git init
# 克隆远程仓库
git clone https://github.com/xxx/project.git
git init 会在当前目录生成一个 .git 隐藏文件夹,所有版本信息都存在里面。别手贱删它,删了版本历史就全没了。
日常操作三板斧
# 查看状态
git status
# 添加文件到暂存区
git add index.html
git add . # 添加所有变更
# 提交到版本库
git commit -m "feat: 添加首页布局"
这里有个坑:git add . 会把所有未跟踪的文件都加进去,包括一些临时文件。我建议养成用 git status 先看一眼的习惯,确认哪些文件要提交。
推送与拉取
# 推送到远程
git push origin main
# 拉取远程更新
git pull origin main
# 拉取但不合并(先看看远程改了啥)
git fetch origin
git pull 其实是 git fetch + git merge 的组合。为什么会这样?因为Git设计者觉得大部分时候你拉下来就是要合并的。但如果你不确定远程改了啥,先用 fetch 看看比较安全。
2.3 .gitignore:别把垃圾文件提交上去
每个项目都有一些不需要版本控制的文件:node_modules、编译产物、IDE配置、日志文件等。这时候就需要 .gitignore 文件了。
# 依赖目录
node_modules/
dist/
build/
# 系统文件
.DS_Store
Thumbs.db
# IDE配置
.vscode/
.idea/
# 环境变量(别把密码提交上去!)
.env
.env.local
# 日志
*.log
npm-debug.log*
我见过最惨的案例:有人把 node_modules 提交到了仓库,结果仓库体积直接飙到几百MB,每次克隆都卡半天。嗯,.gitignore 一定要在项目初始化时就配好。
.gitignore 是没用的。需要用 git rm --cached 文件名 把它从跟踪列表中移除。
2.4 分支操作与合并策略
分支是Git最强大的功能之一。说白了,分支就是让你可以在不影响主线的情况下,安心地开发新功能或修bug。
常用分支命令
# 查看分支
git branch
# 创建分支
git branch feature-login
# 切换分支
git checkout feature-login
# 创建并切换(一步到位)
git checkout -b feature-login
# 删除分支
git branch -d feature-login
合并与变基
合并分支有两种方式:merge 和 rebase。很多人搞不清区别,我简单说说:
# merge:保留完整历史
git checkout main
git merge feature-login
# rebase:让历史更线性
git checkout feature-login
git rebase main
merge 会生成一个合并提交,适合公共分支。而 rebase 会把你的提交「挪」到目标分支的最新位置,历史看起来更干净。但注意:不要对已经推送的公共分支做rebase,否则别人拉取时会出问题。
2.5 Git Flow与分支策略
小项目随便怎么玩都行,但团队协作必须有一套规范的分支策略。目前主流的有两种:
| 策略 | 适用场景 | 核心分支 |
|---|---|---|
| Git Flow | 大型项目、有发布周期 | main、develop、feature、release、hotfix |
| GitHub Flow | 持续交付、小型团队 | main、feature |
Git Flow 比较重,但适合有固定发布节奏的项目。它的分支结构是这样的:
main:只放稳定版本,每次合并都打tagdevelop:日常开发的主分支feature/*:新功能分支,从develop拉出,合并回developrelease/*:发布前准备,修小bug、更新版本号hotfix/*:线上紧急修复,从main拉出,合并回main和develop
GitHub Flow 就简单多了:所有开发都在 feature 分支上,完成后提Pull Request,审核通过后合并到 main。我个人更推荐小团队用这个,省事。
2.6 Husky + lint-staged:提交前自动检查
代码写完了,提交前最好自动检查一下格式和语法。手动检查?太累了,而且容易漏。这时候就需要 Husky 和 lint-staged 这对黄金搭档。
安装配置
# 安装依赖
npm install --save-dev husky lint-staged
# 初始化Husky
npx husky init
# 在package.json中配置lint-staged
{
"lint-staged": {
"*.{js,ts,vue}": ["eslint --fix", "prettier --write"],
"*.{css,scss}": ["stylelint --fix", "prettier --write"],
"*.md": ["prettier --write"]
}
}
然后配置Git钩子,在提交前自动运行:
# 在 .husky/pre-commit 文件中
npx lint-staged
这样每次 git commit 时,Husky 会触发 lint-staged,只检查本次修改的文件。为什么只检查修改的文件?因为全量检查太慢了,你想想看,一个项目几百个文件,每次提交都跑一遍lint,谁受得了?
git commit --no-verify。但别滥用,这相当于在代码质量上开了个后门。
2.7 总结
Git这东西,光看是学不会的。我建议你找个项目,把今天讲的命令都敲一遍。从 git init 开始,建分支、改文件、提交、合并、推送——走完一个完整流程,你就入门了。
下一章我们会聊包管理工具,npm和yarn的那些事儿。到时候见。