SuperAPI AI 工具集

git

编程与开发

查看项目

更新于 10-16 05:27

技能介绍

用途

Git 是现代分布式版本控制的基础工具,具备健壮的分支模型、交互式历史重写、稀疏检出(Sparse Checkout)以及面向单体仓库(monorepo)的 Scalar 支持。本技能提供专家级 Git 版本控制辅助,覆盖分支管理、交互式 rebase、cherry-pick、子模块、工作树(worktree)与冲突解决等场景。

何时使用

  • 分支与协作:管理功能隔离、拉取请求(pull request)、主干开发(trunk-based development)以及分布式团队间的代码评审。
  • 历史重写与清理:在合并到主线分支前,通过 git rebase -i 线性化提交图、压缩 WIP 提交并编辑提交信息。
  • 自动化缺陷定位:使用 git bisect 通过二分查找在数千个修订中定位引入回归的提交。
  • 并发工作区上下文:使用 git worktree 处理紧急热修复,无需 stash 或切换分支上下文。
  • 大型仓库扩展:使用 Git 稀疏检出、Scalar 和浅克隆优化大型单体仓库的性能。

快速开始

# 克隆仓库并创建新的功能分支
git clone https://github.com/myorg/project.git
cd project

# 使用现代命令创建并切换到新分支
git switch -c feature/auth-flow

# 暂存、提交并推送并设置上游跟踪
git add .
git commit -m "feat(auth): implement oauth2 authorization code flow"
git push -u origin feature/auth-flow

核心概念

三树架构(工作树、索引、HEAD)

Git 通过三种不同状态管理文件,而不仅仅是跟踪修订之间的变更:

# 1. 工作树:编辑器中已修改但未提交的文件
echo "export const API_URL = 'https://api.v2.internal';" >> config.ts

# 2. 索引(暂存区):为下一次提交准备的内容
git add config.ts

# 3. HEAD:当前分支上最后一次提交的快照
git diff --staged  # 查看暂存区与 HEAD 之间的差异
git commit -m "chore(config): update internal API endpoint"

有向无环图(DAG)与不可变对象

Git 中的每个提交都是一个不可变节点,指向父哈希和由 blob 快照组成的根树。

# 查看任意提交哈希或 HEAD 背后的原始对象
git cat-file -p HEAD
# 输出:
# tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
# parent 8f3d1e1c3a628a58a98b47cf7d12a9e32049e712
# author Alice <alice@example.com> 1727420400 +0000
# committer Alice <alice@example.com> 1727420400 +0000
#
# feat(auth): implement oauth2 authorization code flow

现代分支导航(git switch 与 git restore)

现代 Git 将重载的 git checkout 命令拆分为专用操作:

# 分支切换(替代 git checkout <branch>)
git switch main
git switch -c feature/payments   # 创建并切换

# 文件恢复(替代 git checkout -- <file>)
git restore src/app.ts           # 丢弃工作目录中未提交的更改
git restore --staged src/app.ts  # 将文件从索引取消暂存回工作树

Rebase 与 Merge 策略

  • Merge(git merge <branch>):通过双父提交保留完整历史上下文。适合集成长期存在的发布分支。
  • Rebase(git rebase <upstream>):将主题提交线性重放到上游 HEAD 之上,避免杂乱的“铁轨”图。适合在 PR 评审前清理功能分支。
# 将功能分支干净地 rebase 到最新的 main
git switch feature/auth-flow
git fetch origin main
git rebase origin/main

常见模式

使用 Git Worktrees 进行多分支开发

问题:需要 stash 未提交的工作来切换分支以修复紧急生产缺陷。

解决方案:同时将多个分支检出到不同目录:

# 为热修复分支创建并行工作树文件夹
git worktree add ../hotfix-branch main

# 在单独目录中处理热修复,不影响当前工作区
cd ../hotfix-branch
git commit -am "fix: patch critical auth vulnerability"
git push origin hotfix-branch

# 完成后清理工作树
cd ../project
git worktree remove ../hotfix-branch

交互式 Rebase 打造干净的拉取请求历史

问题:功能分支包含数十个杂乱的“WIP”、“fix typo”或“checkpoint”提交。

解决方案:在打开拉取请求前交互式压缩并清理历史。

# 交互式 rebase 最近 4 个提交
git rebase -i HEAD~4

# 在交互式编辑器中:
# pick 8f3d1e1 feat(auth): add token generation
# squash 4b825dc fix typo in token payload
# squash a1c94e2 add missing import
# reword 91f7a02 feat(auth): add refresh token endpoint

使用 Git Bisect 自动定位回归

问题:缺陷在 500 个提交中的某处引入,但确切提交未知。

解决方案:使用自动化测试执行脚本运行二分查找。

# 开始 bisect 会话
git bisect start
git bisect bad HEAD                  # 当前 HEAD 已损坏
git bisect good v2.1.0               # v2.1.0 已知正常

# 在每个 bisect 步骤自动运行测试脚本
git bisect run npm test -- --runInBand

# Git 在第一个破坏测试套件的提交处终止
git bisect reset

最佳实践

推荐做法

  • 使用 git switch 和 git restore:避免重载的 git checkout,防止意外切换分支或覆盖文件。
  • 使用 --force-with-lease 推送:防止覆盖远程分支上同事的提交。
  • 启用后台维护:运行 git maintenance start 以优化 packfile、提交图和拉取性能。
  • 使用 SSH / GPG 签名提交:在生产流水线中保证提交作者身份的真实性。
  • 编写约定式提交(Conventional Commits):使用标准化前缀(feat:、fix:、chore:、refactor:)自动化语义化版本和变更日志。

避免做法

  • 强制推送到受保护分支:绝不要在 main、master 或共享发布分支上重写历史。
  • 提交机密或凭据:使用 .gitignore 和 git-secrets/trufflehog;一旦提交,凭据即使后来删除也会保留在 packfile blob 中。
  • 直接使用巨大二进制文件:将大型模型权重或媒体存储在 Git LFS(Large File Storage)或 S3 中。
  • 合并脏工作树:在拉取或 rebase 前 stash 或提交更改,避免意外文件冲突。

故障排除

错误 原因 解决方案
fatal: refusing to merge unrelated histories 从独立初始化且无共享根提交的仓库拉取。 运行 git pull origin main --allow-unrelated-histories。
HEAD detached at ... 检出了特定提交哈希而非分支名。 从当前位置创建分支:git switch -c recovery-branch。
Merge conflict in file.txt 并发提交在相反分支上修改了相同行。 解决冲突标记(<<<<<<<),暂存文件(git add),然后运行 git commit。

参考资料

  • Git Documentation