AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

git —— 版本控制 + GitOps 的底座

一句话定义

git 是分布式版本控制系统。开发用法这里不展开(assumed knowledge),这篇聚焦运维 / SRE 视角:GitOps 工作流、CI 脚本里的 git、git log 排查"谁改的"、临时改动 stash 救命、误操作的恢复。

典型场景

  • GitOps:所有 K8s manifests 在 git 里、Argo CD / Flux 监听
  • CI 脚本里克隆代码:git clone --depth=1 --branch main ...
  • 排查问题:"这个文件是谁改的、什么时候、改了啥":git log -p / git blame
  • 把临时改动收起来:git stash
  • 误删 commit 后救回来:git reflog

配置(一次性)

git config --global user.name "Yuanjun"
git config --global user.email "you@example.com"

git config --global init.defaultBranch main           # 新仓库默认分支
git config --global pull.rebase true                  # pull 用 rebase(**强烈推荐**)
git config --global rebase.autoStash true             # rebase 前自动 stash
git config --global core.editor vim
git config --global color.ui auto

# 列当前配置
git config --list
git config --get user.email

.gitconfig 在 ~/.gitconfig 或 ~/.config/git/config。


clone / pull / push 的实战 flag

clone

git clone https://github.com/org/repo.git
git clone --depth=1 https://github.com/org/repo.git    # shallow clone,CI 快很多
git clone --branch v1.0 https://github.com/org/repo.git
git clone --single-branch --branch main ...            # 只 fetch 一个分支
git clone --recurse-submodules ...                     # 含 submodule

# SSH
git clone git@github.com:org/repo.git

CI 流水线里用 --depth=1:

git clone --depth=1 --branch $TAG https://github.com/org/repo.git
# 只下最近一个 commit,比全量快 10 倍

pull vs pull --rebase

git pull                                              # 默认 fetch + merge
git pull --rebase                                      # fetch + rebase(**推荐**)

pull (merge) 会产生 merge commit、历史乱糟糟。pull --rebase 把本地 commit 重新摞在远端 HEAD 之上、历史线性、漂亮。

设默认:git config --global pull.rebase true。

push

git push                                              # 推当前分支
git push -u origin feat-x                              # 第一次推 + 设上游
git push --force                                       # 强推(**危险**)
git push --force-with-lease                            # 强推但保护别人的 commit(**推荐**)
git push origin :feat-x                                # 删远端分支
git push origin --delete feat-x                        # 等价

--force 永远不要直接用。用 --force-with-lease:

  • --force —— 不管远端有什么、用本地覆盖
  • --force-with-lease —— 远端如果有你不知道的新 commit 会拒绝(救命)

看历史:log / show / blame

git log                                              # 完整历史
git log --oneline                                     # 一行一个
git log --oneline --graph --all                       # 图形化所有分支
git log --since="2 days ago"                           # 时间过滤
git log --author="Alice"
git log --grep="bugfix"                                # message 含 "bugfix"
git log -- path/to/file                                # 某文件的历史
git log -p -- path/to/file                             # 含每个 commit 的 diff
git log --stat                                         # 含文件统计

# 单 commit 详情
git show <commit-id>
git show <commit-id> -- path/to/file                   # 该 commit 中某文件的 diff
git show <commit-id>:path/to/file                      # 该 commit 中某文件的内容

git blame —— 这行是谁改的

git blame path/to/file
# abcdef12 (Alice 2026-01-15 ...) line 1: hello
# bcdef123 (Bob   2026-02-20 ...) line 2: world

git blame -L 100,120 path/to/file                      # 只看 100-120 行

排查"这行配置是谁加的、为啥加的" 黄金套路:

git blame -L 50,60 deployment.yaml | head           # 找 commit ID
git show <commit-id>                                  # 看完整 commit message

diff —— 看改动

git diff                                              # 工作区 vs 暂存区
git diff --staged                                     # 暂存区 vs HEAD
git diff HEAD                                         # 工作区 vs HEAD
git diff main feat-x                                  # 两个分支
git diff main..feat-x                                 # 同上
git diff --stat                                       # 统计(不显示内容)
git diff --name-only                                  # 只列文件名
git diff HEAD -- path/to/file                          # 限单文件

工作流:feature branch + PR

# 1. 拉最新 main
git checkout main
git pull --rebase

# 2. 开新分支
git checkout -b feat-x
# 或者新写法
git switch -c feat-x

# 3. 改改改 + commit
git add -p                                            # 交互式选 chunk 加
git commit -m "feat: add x"

# 4. 推
git push -u origin feat-x

# 5. GitHub / GitLab 上发 PR
# 通过审核后被 merge

# 6. 清本地
git checkout main
git pull --rebase
git branch -d feat-x                                  # 已 merge 的分支
git fetch --prune                                     # 清远端已删的分支引用

stash —— 临时藏起改动

工作做一半要切分支处理紧急 bug:

git stash                                             # 把当前未提交改动藏起来
git stash list                                        # 看 stash 队列
# stash@{0}: WIP on feat-x: ...
# stash@{1}: WIP on main: ...

git stash pop                                         # 取出最新一个(弹出)
git stash apply                                       # 取出但不删
git stash apply stash@{1}                              # 指定哪个

git stash drop stash@{0}                              # 删某个
git stash clear                                        # 清所有 stash

git stash -u 包含未追踪的文件(新增文件 add 之前)。


救命系列

reset —— 把分支指针往回挪

git reset --soft HEAD~1                               # 撤销最近 commit,改动留在暂存区
git reset --mixed HEAD~1                              # (默认)撤销 commit + 取消暂存
git reset --hard HEAD~1                               # **删 commit + 删改动**(危险)

git reset --hard origin/main                          # 强制和远端一致(**慎用**)

--soft < --mixed < --hard,--hard 是核选项——丢的东西基本回不来(除非 reflog 救)。

revert —— 创建反向 commit 回滚

git revert <commit-id>                                # 创建一个新 commit 抵消 <commit-id>
# 历史保留,操作可被追溯

已 push 到共享分支的 commit 不要 reset,用 revert。否则别人 pull 会乱。

reflog —— 时光机

git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~1
# def5678 HEAD@{1}: commit: my important commit
# ...

每次 HEAD 移动 git 都记录。reset --hard 之后从这里救:

git reset --hard HEAD@{1}                             # 回到 reset 之前

git reflog 是程序员的 undo 历史,90% 的"完了我把代码删了"都能救。

cherry-pick —— 把单个 commit 摘到当前分支

git cherry-pick <commit-id>
git cherry-pick <id1> <id2> <id3>
git cherry-pick A..B                                  # A 之后到 B(不含 A)

bugfix 在 feature 分支、想合到 main 用 cherry-pick。

冲突时:

git cherry-pick --continue                            # 解决后继续
git cherry-pick --abort                                # 取消

rebase —— 重写历史

git rebase main                                       # 把当前分支 rebase 到 main
git rebase --interactive HEAD~3                       # 交互式 rebase 最近 3 个 commit
# 弹出编辑器,可以:
#   pick    -- 保留
#   reword  -- 改 message
#   edit    -- 暂停让你改
#   squash  -- 合并到前一个
#   fixup   -- 同 squash 但丢弃 message
#   drop    -- 删

CI 工具 / GitOps 推 PR 前常用 interactive rebase 整理 commit。

rebase 冲突处理

git rebase main
# CONFLICT in ...

# 手动改文件 / 解决冲突
git add <files>
git rebase --continue                                 # 继续
git rebase --skip                                     # 跳过当前 commit
git rebase --abort                                     # 取消(回到 rebase 前)

rebase 之后必 --force-with-lease

git rebase main
git push --force-with-lease                           # 因为历史变了,普通 push 拒

GitOps 场景

1. CI 里只拉一次代码(快)

git clone --depth=1 --branch $BRANCH https://github.com/org/manifests

2. 在 CI 里改 manifests 后推回

git config user.name "ci-bot"
git config user.email "ci@example.com"
git add k8s/deployment.yaml
git commit -m "ci: bump image to v$VERSION"
git push origin main
# Argo CD 监听 main、自动 sync

3. 看 manifests 历史 + 谁改的

git log -p --all -- k8s/deployment.yaml | less
git blame k8s/deployment.yaml

4. 回滚部署 = git revert

git revert <bad-commit-id>                            # 反向 commit
git push                                              # Argo CD 自动同步

GitOps 的好处:rollback = git revert,操作可审计。

5. 看 PR 改了什么 K8s 资源

git fetch origin pull/123/head:pr-123                  # 拉 PR
git diff main pr-123 -- k8s/

submodule

git submodule add https://github.com/org/lib lib       # 加
git submodule update --init --recursive                # 初始化
git submodule update --remote                          # 更新到上游最新
git clone --recurse-submodules ...                     # clone 时连带拉

submodule 难管。优先用 monorepo / 包管理替代。


tag

git tag                                               # 列所有
git tag v1.0.0                                         # 轻量 tag
git tag -a v1.0.0 -m "Release 1.0"                     # annotated tag(**推荐**)
git tag -d v1.0.0                                      # 删本地
git push origin v1.0.0                                 # 推单个 tag
git push origin --tags                                 # 推所有 tag
git push origin :refs/tags/v1.0.0                      # 删远端 tag

Helm chart / Docker image 版本通常和 git tag 绑定。


常见踩坑

坑 1:在错的分支 commit 了

# 在 main 上 commit 了改动,应该在 feat-x 上
git checkout -b feat-x                                # 在当前 commit 开新分支
git checkout main
git reset --hard origin/main                          # main 回到远端状态

坑 2:commit 包含敏感信息(密码 / key)

已 push 的话视作泄漏,下面操作只是清痕迹,密钥要换:

# 删整个文件历史
git filter-repo --invert-paths --path secrets.yml      # 现代工具
# 或老工具
git filter-branch --tree-filter 'rm -f secrets.yml' HEAD

git push --force-with-lease

或者更彻底:BFG Repo-Cleaner。

预防:.gitignore 加 .env、*.key、*-secret.yaml。

坑 3:误 git reset --hard 删了工作

git reflog                                            # 找到之前的 HEAD
git reset --hard HEAD@{1}                              # 救回

只要 git 进程还在跑、commit 没被 GC(默认 30 天)就能救。

坑 4:merge conflict 不知道怎么解

git merge main
# CONFLICT in deployment.yaml

文件里出现:

<<<<<<< HEAD
  image: nginx:1.25
=======
  image: nginx:1.26
>>>>>>> main

选一个 / 合并 / 都用、删掉 <<<<<<< ======= >>>>>>> 标记。

git add deployment.yaml
git commit                                            # 或 git merge --continue

工具辅助:

git mergetool                                         # 用 vimdiff / meld 等

坑 5:误推到 main

git push origin main
# 完了,main 有问题

如果你唯一推了:

git push --force-with-lease origin <good-commit>:main  # 强推到正确 commit

多人共享 main:用 revert 而不是 force push:

git revert <bad-commit-id>
git push origin main

坑 6:误 commit 了大文件

git add big-binary.zip                                # 1GB
git commit
git push
# 慢 / 失败 / 仓库永远大

git 不擅长大文件。用 Git LFS:

git lfs track "*.zip"

或者别 commit 大文件,用对象存储 / artifact registry。

坑 7:clone 慢

git clone https://github.com/big-org/big-repo
# 卡几分钟
git clone --depth=1 --branch main https://...         # shallow clone
git clone --filter=blob:none --branch main https://...  # 部分 clone

坑 8:line ending 跨平台问题

Windows / Linux 行尾不同(CRLF vs LF)。

.gitattributes:

* text=auto eol=lf

或全局:

git config --global core.autocrlf input            # Linux / Mac
git config --global core.autocrlf true              # Windows

坑 9:把 .git 目录提交进了 docker 镜像

COPY . /app
# /app/.git 也复制进去 → 镜像变大、可能泄漏 commit 历史

.dockerignore:

.git
.gitignore

坑 10:pull 之后本地修改没了

git pull                                             # 本地未 commit 改动消失?

git 一般不会 silently 丢——通常是有 conflict 让你解。但 git checkout . / git reset --hard 是真的丢。

防御:改之前先 git stash 或先 commit(哪怕是 wip)。


SSH key 多账号

详见 ssh-config.md 场景 3。

# ~/.ssh/config
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes
git clone git@github-work:company/repo.git           # 走公司 key

关联命令

  • ssh-config —— git over SSH 配置
  • ssh-keygen —— 生成 deploy key
  • argocd —— GitOps 工具消费 git
  • helm —— chart 通常在 git 仓库里
  • kubectl —— GitOps 最终通过 kubectl apply 收敛
  • gh / glab —— GitHub / GitLab 官方 CLI(管 PR / Issue / Action)
在 GitHub 上编辑此页