git进阶04_Git 工作流实战

Git 工作流实战

本章目标:掌握企业日常开发中最高频的 Git 操作,做到"闭眼操作不出错"。


一、企业日常开发的标准流程

1.1 每天早上到公司

bash 复制代码
# 第一件事:同步远程代码
git checkout main
git pull origin main

# 同步 develop(如果用 Git Flow)
git checkout develop
git pull origin develop

# 如果你昨天的功能分支还没合并,也同步一下
git checkout feature/user-login
git rebase origin/develop    # 把 develop 的最新改动变基到你的分支

1.2 开发过程中的提交

bash 复制代码
# 提交信息必须规范(下一节详细讲)
git add <具体文件>       # 不要用 git add .
git commit -m "feat(auth): add login form validation"

1.3 下班前

bash 复制代码
# 推送到远程(备份 + 让同事能看到你的进度)
git push -u origin feature/user-login

# 如果用了 rebase
git push --force-with-lease

1.4 功能开发完成

bash 复制代码
# 同步最新代码
git fetch origin
git rebase origin/develop

# 解决冲突(如果有)
# ...

# 推送
git push --force-with-lease

# 在 GitLab 上创建 Merge Request
# 等待 Code Review → 合并 → 删除分支

二、Git Commit Message 规范(Conventional Commits)

这是企业中最重要的规范之一,不遵守会被 leader 打回来

2.1 格式

复制代码
<type>(<scope>): <subject>

<body>

<footer>

2.2 Type 类型

Type 说明 示例
feat 新功能 feat(auth): add login page
fix 修复 Bug fix(payment): fix amount calculation
docs 文档更新 docs(readme): update installation guide
style 代码格式(不影响逻辑) style: fix indentation
refactor 重构(非新功能非修复) refactor(user): extract validation logic
perf 性能优化 perf(query): add database index
test 测试 test(auth): add login unit tests
chore 构建/工具/依赖 chore: update dependencies
ci CI/CD 配置 ci: add GitHub Actions workflow
revert 回滚 revert: revert "feat(auth): add login"

2.3 Scope 范围

表示影响范围(模块/组件),可选:

  • auth - 认证模块
  • payment - 支付模块
  • user - 用户模块
  • api - API 层
  • db - 数据库

2.4 实际示例

bash 复制代码
# 简单的
git commit -m "feat(auth): add user login"

# 带 body 的
git commit -m "fix(payment): fix discount calculation

The discount was not applied when using coupon codes.
This was caused by missing null check in applyDiscount().

Fixes #123"

2.5 用 Git Hooks 自动检查(推荐)

bash 复制代码
# 安装 commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional

# 创建配置文件
cat > commitlint.config.js << 'EOF'
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', [
      'feat', 'fix', 'docs', 'style', 'refactor',
      'perf', 'test', 'chore', 'ci', 'revert'
    ]],
    'subject-max-length': [2, 'always', 100],
  },
};
EOF

三、git add 的正确姿势

3.1 交互式暂存(企业推荐)

bash 复制代码
# 选择性暂存(最推荐)
git add -p <file>
# 会逐个显示代码块(hunk),选择:
# y - 暂存这个 hunk
# n - 跳过
# s - 拆分这个 hunk
# q - 退出

# 这样你可以把一个文件的改动分成多次提交

3.2 常见场景

bash 复制代码
# ✅ 推荐:只添加需要的文件
git add src/login.js src/login.css

# ❌ 不推荐:添加所有改动
git add .

# ⚠️ 谨慎:添加所有改动(跳过交互确认)
git add -A

# 查看将要提交的内容
git diff --staged

3.3 撤误操作

bash 复制代码
# 撤销 git add(取消暂存)
git reset HEAD <file>

# 或者用新语法
git restore --staged <file>

# 丢弃工作区的修改(危险!不可恢复)
git restore <file>

# 丢弃暂存区的修改
git restore --staged <file>

四、git commit 深入

4.1 好的 commit 原则

复制代码
一个 commit = 一个逻辑单元

✅ 好的:
commit 1: feat(auth): add login form
commit 2: feat(auth): add login API call
commit 3: feat(auth): add login error handling

❌ 不好的:
commit 1: feat(auth): add login (包含了 form + API + error + style)

4.2 修改最近一次 commit

bash 复制代码
# 修改 commit message
git commit --amend -m "feat(auth): add login validation"

# 修改内容(忘记 add 某个文件)
git add forgotten-file.js
git commit --amend --no-edit

4.3 修改更早的 commit(交互式 rebase)

bash 复制代码
# 修改最近 3 次 commit
git rebase -i HEAD~3

# 编辑器会显示:
pick abc1234 feat(auth): add login form
pick def5678 feat(auth): add login API
pick ghi9012 fix(auth): fix typo

# 把你想修改的那行的 pick 改成 edit 或 reword
# edit = 修改内容
# reword = 只修改 message
# squash = 合并到上一个 commit
# drop = 删除这个 commit

# 例如修改第一个 commit:
edit abc1234 feat(auth): add login form
pick def5678 feat(auth): add login API
pick ghi9012 fix(auth): fix typo

五、git stash --- 临时存储工作

场景:你正在开发功能 A,突然要修紧急 Bug。

bash 复制代码
# ===== 1. 保存当前工作 =====
git stash push -m "WIP: feature A"

# 或者更简洁
git stash

# ===== 2. 切到 main 修 Bug =====
git checkout main
git pull origin main
git checkout -b hotfix/fix-bug
# ... 修 Bug ...
git commit -m "fix: critical bug"
git push origin hotfix/fix-bug

# ===== 3. 回到功能 A 继续开发 =====
git checkout feature/user-login

# 恢复之前的工作
git stash pop

# ===== 4. stash 操作 =====
git stash list              # 查看所有 stash
git stash pop               # 恢复并删除
git stash apply stash@{1}   # 恢复但不删除
git stash drop stash@{0}    # 删除指定 stash
git stash clear             # 清空所有 stash

六、git cherry-pick --- 精确移植提交

场景:你在 feature 分支修了一个 Bug,需要把这个修复也同步到 release 分支。

bash 复制代码
# 先找到要移植的 commit hash
git log --oneline feature/user-login
# 输出:abc1234 fix(auth): fix login timeout

# 切到目标分支
git checkout release/v1.2.0

# 精确移植这个 commit
git cherry-pick abc1234

# 如果有冲突,解决后
git cherry-pick --continue

# 取消本次 cherry-pick
git cherry-pick --abort

七、git bisect --- 二分查找 Bug

场景:你知道某个 commit 引入了 Bug,但不知道是哪个。

bash 复制代码
# 启动二分查找
git bisect start

# 标记当前版本是有 Bug 的
git bisect bad

# 标记某个已知好的版本
git bisect good v1.0.0

# Git 会自动 checkout 中间的 commit
# 你测试一下,然后告诉 Git:
git bisect good     # 这个版本没问题
# 或
git bisect bad      # 这个版本有问题

# 重复几次,Git 会找到引入 Bug 的第一个 commit
# 结束后
git bisect reset

八、git log 进阶

bash 复制代码
# 简洁一行显示
git log --oneline

# 带分支图
git log --oneline --graph --all --decorate

# 按时间范围
git log --since="2 weeks ago"
git log --since="2024-01-01" --until="2024-01-31"

# 按作者
git log --author="张三"

# 按文件
git log -- src/login.js

# 按内容搜索
git log --grep="fix login"

# 查看每次提交的改动
git log -p

# 查看统计信息
git log --stat

# 自定义格式
git log --pretty=format:"%h - %an, %ar : %s"

九、git diff 进阶

bash 复制代码
# 工作区 vs 暂存区
git diff

# 暂存区 vs 最新提交
git diff --staged

# 两个 commit 之间的差异
git diff abc1234 def5678

# 两个分支之间的差异
git diff main..feature/user-login

# 只看文件名
git diff --stat main..feature/user-login

# 按单词比较(更精确)
git diff --word-diff

十、配置企业 Git Hooks

pre-commit:提交前检查

bash 复制代码
# .husky/pre-commit(如果用 husky)
#!/bin/sh
npx lint-staged

# lint-staged 配置(package.json)
{
  "lint-staged": {
    "*.{js,ts}": ["eslint --fix", "prettier --write"],
    "*.{css,scss}": ["prettier --write"],
    "*.{json,md}": ["prettier --write"]
  }
}

commit-msg:检查 commit 信息

bash 复制代码
# .husky/commit-msg
#!/bin/sh
npx commitlint --edit $1

pre-push:推送前检查

bash 复制代码
# .husky/pre-push
#!/bin/sh
npm run test

十一、练习清单

学完本章,请完成以下操作:

  • git add -p 把一个文件的改动分多次提交
  • git stash 暂存工作,切换分支修 Bug,再恢复
  • git cherry-pick 移植一个 commit 到另一个分支
  • git rebase -i 修改/合并/删除最近 3 次 commit
  • git log --graph --all 查看完整的分支图
  • 配置 commitlint,提交一个不规范的 commit 试试

上一章02-企业分支管理策略

下一章04-团队协作与Code Review(04-团队协作与Code Review.md)