目录

git-02 Git实战

1. 工作流模型

1.1 Git Flow

适合有计划版本发布的项目(如移动端 App、开源库)。

main        ──●──────────────────────────●──  (仅生产代码)
               \                        /
hotfix          ●──●───────────────────/

develop     ──●──●──●──●──●──●──●──●──●──
               \     \         /
feature/A       ●──●──/   ────/
                   \        /
feature/B           ●──●───
分支 作用 命名
main 生产代码,每个提交对应一个版本 main / master
develop 集成分支,功能开发汇聚点 develop
feature/* 单个功能开发 feature/login
release/* 发版准备,只修 bug release/1.2.0
hotfix/* 紧急线上修复 hotfix/fix-crash

1.2 GitHub Flow(推荐)

适合持续部署的 Web 服务,更简洁。

main:    ──●──────────────────────────●──●──
            \                        /
feature:     ●──●──●── PR ──review──/

流程:

  1. main 创建 feature 分支
  2. 开发、提交
  3. 发 Pull Request
  4. Code Review + CI 通过
  5. 合并到 main 并自动部署

1.3 Trunk Based Development

大型团队(如 Google)采用,所有人在单一主干上提交,用 Feature Flag 控制功能开关。


2. Cherry-pick

将指定提交"摘取"到当前分支,不合并整个分支。

git cherry-pick a1b2c3

git cherry-pick a1b2c3 d4e5f6

git cherry-pick start..end

git cherry-pick -n a1b2c3

git cherry-pick --continue
git cherry-pick --abort

典型场景: hotfix 分支修了一个 bug,需要同步到 develop 分支:

git checkout develop
git cherry-pick hotfix/fix-crash~1  # 摘取 hotfix 上的修复提交

3. Stash(储藏)

临时保存工作区的未提交变更,切换分支时非常有用。

git stash
git stash push -m "WIP: login feature"  # 带描述

git stash list

git stash pop          # 恢复最新,并从列表删除
git stash apply        # 恢复最新,保留列表
git stash apply stash@{1}  # 恢复指定

git stash drop stash@{0}
git stash clear        # 清空所有

git stash show -p stash@{0}

git stash -u

4. 版本回退实战

4.1 场景:撤销最近一次提交(未 push)

git reset --soft HEAD~1

git reset --hard HEAD~1

4.2 场景:撤销已 push 的提交

git revert HEAD
git push

git revert HEAD~3..HEAD

4.3 场景:找回误删的提交

reflog 记录了 HEAD 的所有变更,即使 reset –hard 也能找回:

git reflog

git reset --hard HEAD@{1}

4.4 场景:误删分支恢复

git reflog

git branch recovered-branch a1b2c3

5. Submodule(子模块)

将另一个 Git 仓库嵌入当前仓库。

git submodule add https://github.com/user/lib.git lib/

git clone --recurse-submodules https://github.com/user/project.git

git submodule update --init --recursive

git submodule update --remote

git submodule status

6. 多人协作实战

6.1 标准 PR 流程

git clone git@github.com:yourname/repo.git

git remote add upstream git@github.com:original/repo.git

git fetch upstream
git rebase upstream/main

git switch -c feature/my-feature

git add .
git commit -m "feat: my feature"

git push origin feature/my-feature

6.2 保持 feature 分支与 main 同步

git fetch origin
git merge origin/main

git fetch origin
git rebase origin/main

6.3 Code Review 后修改

git add .
git commit -m "fix: address review comments"

git add .
git commit --amend --no-edit

git push --force-with-lease

7. 常见问题解决

7.1 commit 了敏感信息

git add .gitignore
git commit --amend

bfg --delete-files secret.key
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force

注意:敏感信息已 push 则必须视为泄露,同时要轮换密钥。

7.2 合并了错误的分支

git reset --hard HEAD~1

git revert -m 1 HEAD  # -m 1 表示保留主线(main)

7.3 工作区一团糟,想恢复到最近提交

git restore .          # 恢复所有已追踪文件
git clean -fd          # 删除未追踪文件和目录

7.4 push 被拒绝(non-fast-forward)

git pull --rebase
git push

git fetch origin
git rebase origin/main
git push

7.5 查看两个分支的差异

git log main..feature --oneline

git diff main...feature  # 三点:从分叉点比较

8. Git Hooks 自动化

Hooks 是在特定 Git 事件触发时自动执行的脚本,存放在 .git/hooks/

常用 hooks:

Hook 触发时机 常见用途
pre-commit git commit 运行 lint、格式化
commit-msg 提交消息写入后 校验消息格式
pre-push git push 运行测试
post-merge 合并完成后 安装新依赖
#!/bin/sh
go vet ./...
if [ $? -ne 0 ]; then
  echo "go vet failed, commit aborted"
  exit 1
fi

推荐使用 husky(Node.js 项目)管理 hooks,便于团队共享。


9. 实用 alias 配置

git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.unstage "restore --staged"
git config --global alias.last "log -1 HEAD"
git config --global alias.aliases "config --get-regexp alias"

使用:

git lg   # 漂亮的分支图
git st   # 查看状态