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 看看比较安全。

注意:推送前一定要先拉取!我曾经有一次没拉取就直接push,结果把同事的代码覆盖了——那场面,简直灾难。

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

合并与变基

合并分支有两种方式:mergerebase。很多人搞不清区别,我简单说说:

# merge:保留完整历史
git checkout main
git merge feature-login

# rebase:让历史更线性
git checkout feature-login
git rebase main

merge 会生成一个合并提交,适合公共分支。而 rebase 会把你的提交「挪」到目标分支的最新位置,历史看起来更干净。但注意:不要对已经推送的公共分支做rebase,否则别人拉取时会出问题。

核心原则:公共分支用merge,私有分支用rebase。我团队里就因为这个吵过架,后来定死了这个规则。

2.5 Git Flow与分支策略

小项目随便怎么玩都行,但团队协作必须有一套规范的分支策略。目前主流的有两种:

策略 适用场景 核心分支
Git Flow 大型项目、有发布周期 main、develop、feature、release、hotfix
GitHub Flow 持续交付、小型团队 main、feature

Git Flow 比较重,但适合有固定发布节奏的项目。它的分支结构是这样的:

  • main:只放稳定版本,每次合并都打tag
  • develop:日常开发的主分支
  • feature/*:新功能分支,从develop拉出,合并回develop
  • release/*:发布前准备,修小bug、更新版本号
  • hotfix/*:线上紧急修复,从main拉出,合并回main和develop

GitHub Flow 就简单多了:所有开发都在 feature 分支上,完成后提Pull Request,审核通过后合并到 main。我个人更推荐小团队用这个,省事。

避坑指南:我曾经在一个项目里看到有人直接在main分支上开发,结果线上出bug时根本没法回滚——因为main上全是半成品代码。记住:main分支永远只放可发布的版本。

2.6 Husky + lint-staged:提交前自动检查

代码写完了,提交前最好自动检查一下格式和语法。手动检查?太累了,而且容易漏。这时候就需要 Huskylint-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的那些事儿。到时候见。