前言

关于Git的系统学习,我们需要建立一个从日常协作到原理认知再到灾难恢复的完整体系。很多前端开发者会用add、commit、push,但遇到代码丢了、分支乱了、回滚错了、冲突覆盖了就束手无策——这正是深度掌握Git的分水岭。


提示:以下是一份阶梯式Git学习体系,按实战频率和认知深度排序:

一、核心基石:重新理解Git的数据模型(最关键)

绝大多数Git困惑,根源在于不理解“Git存的是什么”。

1.1 真理时刻:Git存的是快照,不是差异

  • SVN:存的是文件A第1行到第10行的变化(增量存储)
  • Git:存的是整个文件A此时此刻的完整副本(快照)

推论:

  1. Git的分支不是目录副本,只是一个指针(指向某次commit)。
  2. Git的切换分支是替换工作目录的文件内容,不是SVN那样“修改几行”。
  3. Git几乎不会丢代码——只要你有commit,哪怕删了分支,用git reflog都能找回。

1.2 三个区 + 四种状态(背下来)

三个区:

区域位置作用
工作区(Working Directory)你的磁盘你肉眼看到的文件
暂存区(Staging Area/Index).git/index下一次commit的内容清单
版本库(Repository).git/objects所有历史快照

四种状态(git status看到的):

  1. 未跟踪(Untracked):新文件,Git不认识
  2. 已修改(Modified):工作区改了,还没add
  3. 已暂存(Staged):add了,等commit
  4. 已提交(Committed):安全落地

黄金命令:

# 查看这三个区的完整差异链
git diff                  # 工作区 vs 暂存区
git diff --staged         # 暂存区 vs 最近一次commit
git diff HEAD             # 工作区 vs 最近一次commit

理解这个模型,你就能回答:

  • 为什么git checkout .会丢失工作区修改?——因为它是从暂存区覆盖工作区。
  • 为什么git reset --hard会丢代码?——因为它把三个区全部指向某个旧commit。

二、日常协作的“肌肉记忆”层级

2.1 必会命令(达到条件反射)

# 基础三板斧
git add -p              # 交互式添加,只提交文件的某几行(专业素养分水岭)
git commit --amend      # 修改最近一次的commit信息,或把漏加的文件塞进去
git push --force-with-lease  # 安全的强制推送(绝不加--force裸奔)

# 分支操作
git switch -c feature   # 新版checkout -b(语义更清晰)
git branch -d feature   # 删除已合并的分支
git push origin --delete feature  # 删除远程分支

# 查看历史
git log --oneline --graph --all  # 看清整个仓库拓扑
git show <commit-id>     # 看某次commit改了什么
git blame <file>         # 谁动了这行代码(追责神器)

2.2 紧急救援(事故处理)

# 场景1:刚commit,想撤回来
git reset --soft HEAD~1  # 保留工作区和暂存区,撤销commit
git reset --mixed HEAD~1 # 保留工作区,撤销commit和暂存(默认)
git reset --hard HEAD~1  # 全丢,慎用

# 场景2:commit message写错了
git commit --amend -m "新消息"

# 场景3:本地commit了但不想push,想整理成1个commit
git reset --soft origin/main  # 把当前分支所有差异打回暂存区
git commit -m "新的大一统提交"

# 场景4:commit推上去了,想撤回(危险)
git revert <commit-id>   # 生成一个反向操作的commit,历史保留,团队安全
# 绝对禁止在公共分支上用reset,要用revert

三、分支模型与协作范式(团队生存核心)

3.1 两种主流分支策略

Git Flow(适合版本周期明确的传统项目):

  • main:永远可部署
  • develop:开发主干
  • feature/*:功能分支
  • release/*:发布前修修补
  • hotfix/*:线上紧急补丁

GitHub Flow(适合持续交付的互联网产品):

  • main:唯一主干,永远可部署
  • feature/*:从main切出,PR合回main
  • 没有develop分支,强调小步快跑、频繁合入

前端项目强烈推荐GitHub Flow。原因:前端发布简单、无需维护多个线上版本、PR即部署。

3.2 Pull Request/Merge Request 黄金流程

  1. 从最新main切分支:git switch main && git pull && git switch -c feat-xxx
  2. 小步提交:每个commit逻辑独立(如“添加组件”、“修复样式”)
  3. 推送到远端:git push origin feat-xxx
  4. 创建PR:描述“做了什么、为什么、怎么测试”
  5. 处理反馈:
git commit -m "fix: review comment"
git push
# PR自动更新
  1. 合并:选择Squash and merge(单commit合入)或Rebase and merge(线性历史)

四、Git进阶能力(资深工程师分水岭)

4.1 Rebase:变基与交互式重写历史

Rebase不是炫技,而是让历史更清晰。

场景1:同步上游变更(避免merge污染)

# 错误做法
git pull origin main  # 产生Merge branch 'main' into feat-xxx 的无用commit

# 正确做法
git pull --rebase origin main  # 把你的commit放在main的最新commit之后,历史是直线
# 或
git fetch origin
git rebase origin/main

场景2:整理本地commit再推送

git rebase -i HEAD~3   # 修改最近3个commit
# 常用指令:
# p/pick - 保留
# r/reword - 改commit message
# s/squash - 合并到上一个
# e/edit - 修改内容
# d/drop - 删除commit

黄金法则:绝不对已推送到公共分支的commit执行rebase。只对自己的、还未PR的commit执行。

4.2 Cherry-pick:精准移植

# 把feature分支的某个bug修复commit,捡到hotfix分支
git switch hotfix
git cherry-pick <commit-id>

实战价值:避免合入整个分支,只取需要的修改。

4.3 Reflog:Git的后悔药(救命级)

git reflog
# 输出:
# abc123 HEAD@{0}: commit: 修复登录bug
# def456 HEAD@{1}: reset: moving to HEAD~1
# ghi789 HEAD@{2}: commit: 添加支付功能

# 找回“丢失”的commit
git checkout abc123   # 直接回到那个状态

核心认知:Git的垃圾回收(GC)默认90天,只要你操作过,90天内都能找回。

五、Git钩子与自动化

5.1 客户端钩子(本地)

.git/hooks/
├── pre-commit      # commit前执行(lint代码、格式化)
├── commit-msg      # 校验commit message格式
├── pre-push        # push前执行(运行测试)

实战:不用手动写钩子脚本,用Husky。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

5.2 服务端钩子

  • pre-receive:合入前校验PR规范、禁止直接push到main
  • post-receive:合入后触发CI/CD(自动化部署)

六、Git原理认知(高级工程师视野)

6.1 .git目录解剖

.git/
├── HEAD            # 当前分支指向(ref: refs/heads/main)
├── config          # 仓库配置(user.name、remote地址)
├── refs/           # 指针
│   ├── heads/      # 本地分支
│   └── remotes/    # 远程分支
├── objects/        # 所有数据(commit、tree、blob)
│   ├── 12/         # SHA-1前两位作为目录
│   └── 34/         
└── index           # 暂存区

核心对象类型:

  • Blob:文件内容
  • Tree:目录结构(文件名→blob)
  • Commit:指向tree、父commit、作者、消息

理解这个,你就能懂:

  • Git为什么快?——文件对比不需要逐行,只比较blob的SHA。
  • Git为什么存不下大文件?——每次修改都会产生新的blob。大文件用Git LFS(存指针)。

6.2 图解Git

强推学习资源:

  • Learn Git Branching:可视化交互式教程,玩通关就懂了rebase和merge的区别。
  • Pro Git 2nd Edition:官方电子书,免费。

七、前端Git工作流最佳实践(可直接复制)

7.1 仓库初始化规范

# 全局配置
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
git config --global core.editor code --wait  # 用VSCode写commit message
git config --global pull.rebase true          # 默认git pull用rebase模式
git config --global init.defaultBranch main   # 不再用master

# 项目级配置
git config user.name "公司全名"  # 公司邮箱,覆盖全局

7.2 Commit Message 规范(Angular规范)

<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>

type:

  • feat:新功能
  • fix:修复bug
  • docs:文档
  • style:格式(空格、分号等,无逻辑变化)
  • refactor:重构
  • test:测试
  • chore:构建/工具链

示例:

feat(user): 添加登录弹窗组件

- 实现手机号验证
- 集成短信验证码接口

Closes #123

配套工具:

  • Commitizen:git cz交互式生成
  • commitlint:校验格式
  • standard-version:自动生成CHANGELOG

7.3 企业级Git协作规范(可直接落地)

  1. 禁止直接push到main:设置分支保护,必须PR
  2. PR前务必同步最新main:git pull --rebase origin main,解决冲突再提
  3. PR至少1人Approval:小团队互审,大团队代码所有者
  4. 合并方式统一:建议Squash and merge,一个功能一个commit
  5. Commit message必须规范:不符则CI拦截
  6. 标签版本化:git tag -a v1.0.0 -m “发布v1.0.0”,对应线上版本

总结

Git学习路径图:

阶段目标标志性能力
L1 能工作会commit/push/pull能提交代码,不覆盖别人
L2 能协作理解分支、PR、冲突解决能参与团队开发,能review代码
L3 能救火会reset、revert、reflog能把删掉的分支、commit找回来
L4 能提效会用alias、hooks、rebase -i能自动化校验、整理干净的历史
L5 能设计理解对象模型、自定义工作流能为团队设计Git规范、搭建CI

Git不需要“学完”,而是需要“带着问题查”。最有效的学习路径是:日常用熟练L1-L2,遇到事故实战L3,然后带着对原理的好奇去补L5。

你现在停留在哪个层级?可以从你最近一次被Git坑到的场景入手,针对性突破。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐