Git 是分布式版本控制系统(DVCS),是现代软件工程的源代码管理基石。它记录了代码的每一次变更,支持多人协作,是触发 CI/CD 流水线的起点。
一、Git 的核心定位
1.1 解决什么问题
| 痛点 | Git 的解法 |
|---|---|
| 代码改崩了想回退 | 版本历史:每次提交都有快照,可随时回滚到任意版本 |
| 多人同时改同一文件 | 分支与合并:各自在分支开发,完成后合并(Merge/Rebase) |
| 谁改了哪行代码、为什么改 | 提交信息 + Blame:每行代码都有作者和时间戳 |
| 代码分散在个人电脑 | 远程仓库:GitLab/GitHub 作为中央仓库,统一代码源 |
| 误删文件 | 版本库:文件一旦提交,即使本地删除也能从仓库恢复 |
1.2 分布式 vs 集中式
| 维度 | 集中式(如 SVN) | 分布式(Git) |
|---|---|---|
| 仓库位置 | 只有服务器有完整仓库 | 每个开发者本地都有完整仓库 |
| 提交方式 | 必须联网提交到服务器 | 本地提交(Commit),联网推送(Push) |
| 协作方式 | 直接改服务器文件 | 本地分支开发,再合并到远程 |
| 容错性 | 服务器挂了就完了 | 任何一台本地仓库都能恢复完整历史 |
二、Git 的四个区域
Git 操作围绕四个逻辑区域展开:
┌─────────────────────────────────────────┐
│ 远程仓库(Remote) │
│ GitLab / GitHub / Gitee │
│ origin/master, origin/dev │
└─────────────────┬───────────────────────┘
│ git push / git pull / git fetch
┌─────────────────▼───────────────────────┐
│ 本地仓库(Repository) │
│ .git 目录,存储完整版本历史 │
│ master, dev, feature/order │
└─────────────────┬───────────────────────┘
│ git commit
┌─────────────────▼───────────────────────┐
│ 暂存区(Index / Stage) │
│ git add 后,文件被标记为待提交 │
└─────────────────┬───────────────────────┘
│ git add / git rm
┌─────────────────▼───────────────────────┐
│ 工作区(Working Directory) │
│ 你实际看到的代码文件 │
│ order-service/src/main/java/... │
└─────────────────────────────────────────┘
三、核心命令详解(带注释)
3.1 仓库初始化与克隆
# ============================================
# 方式 1:在现有目录初始化 Git 仓库
# ============================================
# 进入项目目录
cd order-service
# 初始化本地仓库,生成 .git 目录
git init
# 添加远程仓库地址(通常由 GitLab/GitHub 提供)
git remote add origin https://gitlab.company.com/ecommerce/order-service.git
# ============================================
# 方式 2:克隆已有远程仓库(最常用)
# ============================================
# 将远程仓库完整复制到本地,包括所有分支和历史记录
git clone https://gitlab.company.com/ecommerce/order-service.git
# 指定本地目录名
git clone https://gitlab.company.com/ecommerce/order-service.git my-order
# 克隆后查看远程仓库信息
git remote -v
# 输出:
# origin https://gitlab.company.com/ecommerce/order-service.git (fetch)
# origin https://gitlab.company.com/ecommerce/order-service.git (push)
3.2 日常开发流程
# ============================================
# 1. 查看当前状态
# ============================================
# 查看工作区与暂存区的差异:哪些文件被修改、哪些未跟踪
git status
# 简洁版状态
git status -s
# 输出示例:
# M src/main/java/OrderController.java # M = 已修改且已暂存
# M src/main/java/OrderService.java # M = 已修改但未暂存
# ?? src/main/java/NewFile.java # ?? = 未跟踪的新文件
# ============================================
# 2. 将变更加入暂存区
# ============================================
# 添加单个文件到暂存区
git add src/main/java/OrderController.java
# 添加所有修改和新增文件
git add .
# 添加所有修改(不包括新增未跟踪文件)
git add -u
# 交互式添加,逐块选择(适合精细控制)
git add -p
# ============================================
# 3. 提交到本地仓库
# ============================================
# -m 后面写提交信息,描述本次变更的目的
# 规范格式:type(scope): subject
# 例如 feat(order): 新增秒杀订单接口
git commit -m "feat(order): 新增秒杀订单接口"
# 修改最后一次提交的提交信息(仅限未 push 时)
git commit --amend -m "feat(order): 新增秒杀订单接口与库存扣减"
# ============================================
# 4. 推送到远程仓库
# ============================================
# 将本地当前分支的提交推送到远程 origin 的同名分支
git push origin main
# 第一次推送本地分支到远程并建立关联
git push -u origin feature/order-seckill
# ============================================
# 5. 拉取远程更新
# ============================================
# fetch 只下载远程变更到本地,不自动合并(安全)
git fetch origin
# pull = fetch + merge,直接合并到当前分支
git pull origin main
# pull 使用 rebase 而非 merge,保持线性历史(推荐)
git pull --rebase origin main
3.3 分支管理(协作核心)
# ============================================
# 查看分支
# ============================================
# 查看本地分支,* 表示当前所在分支
git branch
# 查看所有分支(本地 + 远程)
git branch -a
# 查看分支最后一次提交信息
git branch -v
# ============================================
# 创建与切换分支
# ============================================
# 创建新分支(基于当前分支的代码)
git branch feature/order-seckill
# 切换到新分支
git checkout feature/order-seckill
# 创建并切换(常用简写)
git checkout -b feature/order-seckill
# Git 2.23+ 新命令:创建并切换
git switch -c feature/order-seckill
# ============================================
# 合并分支
# ============================================
# 先切换到目标分支(如 main)
git checkout main
# 将 feature/order-seckill 的变更合并到 main
git merge feature/order-seckill
# 合并后删除已完成的特性分支
git branch -d feature/order-seckill
# ============================================
# 解决合并冲突
# ============================================
# 当两人修改同一文件同一区域时,Git 无法自动合并,会标记冲突
# 冲突文件中会有以下标记:
# <<<<<<< HEAD
# 当前分支的代码
# =======
# 合并分支的代码
# >>>>>>> feature/order-seckill
#
# 手动编辑文件保留正确代码,删除标记,然后:
git add .
git commit -m "merge: 解决订单服务冲突"
# 使用工具解决冲突(如 VSCode、IDEA)
git mergetool
3.4 版本回退与历史查看
# ============================================
# 查看提交历史
# ============================================
# 查看简洁历史(单行显示)
git log --oneline
# 输出示例:
# a1b2c3d feat(order): 新增秒杀接口
# e4f5g6h fix(order): 修复库存超卖
# i7j8k9l refactor(order): 优化订单查询 SQL
# 查看图形化分支历史
git log --graph --oneline --all
# 查看某文件的修改历史
git log -p src/main/java/OrderService.java
# ============================================
# 查看某行代码是谁写的(追责/理解上下文)
# ============================================
git blame src/main/java/OrderService.java
# 输出:每行前面显示 commit 哈希、作者、时间
# ============================================
# 版本回退(三种方式)
# ============================================
# 方式 1:软回退(保留工作区和暂存区修改,只回退 commit)
# 用于:提交信息写错了,想重新提交
git reset --soft HEAD~1
# 方式 2:混合回退(保留工作区修改,清空暂存区)
# 用于:提交的内容没问题,但想重新整理暂存区
git reset --mixed HEAD~1
# 方式 3:硬回退(彻底丢弃所有修改,回到指定版本)
# ⚠️ 危险操作,未 push 的代码会丢失
git reset --hard a1b2c3d
# 方式 4:反做(推荐用于已 push 的代码)
# 生成一个新的 commit,撤销某次提交的修改
# 这样不会改写历史,适合公共分支
git revert a1b2c3d
3.5 标签管理(版本标记)
# ============================================
# 标签用于标记发布版本(如 v1.0.0, v2.1.0)
# ============================================
# 查看所有标签
git tag
# 创建轻量标签(仅指向某个 commit)
git tag v1.0.0
# 创建附注标签(包含作者、时间、说明,推荐)
git tag -a v1.0.0 -m "电商系统 1.0 正式版"
# 推送单个标签到远程
git push origin v1.0.0
# 推送所有本地标签到远程
git push origin --tags
# 删除本地标签
git tag -d v1.0.0
四、分支策略模型
4.1 Git Flow(经典模型)
适合版本发布周期明确的项目(如传统软件、企业应用):
main(主分支,只放稳定发布代码)
│
├── develop(开发分支,日常集成)
│ │
│ ├── feature/user-login(特性分支)
│ ├── feature/order-seckill(特性分支)
│ │
│ └── 合并回 develop
│
├── release/v1.1.0(预发布分支,修 Bug)
│ └── 合并到 main + develop
│
└── hotfix/payment-bug(热修复分支,基于 main)
└── 合并到 main + develop
4.2 Trunk Based Development(主干开发,云原生推荐)
适合持续部署、快速迭代的项目(如微服务、SaaS):
main(唯一长期分支,始终可发布)
│
├── feature/order-seckill(短生命周期分支,1-2 天)
├── feature/user-auth(短生命周期分支)
│
└── 频繁合并回 main,通过 Feature Flag 控制功能开关
在 K8s 电商场景中的选择:
- Git Flow:适合有明确版本节奏的 toB 产品(如每季度发一个大版本)
- Trunk Based:适合 toC 电商,每日多次部署,配合 K8s 滚动更新
五、Git 在 DevOps/K8s 工作流中的位置
Git 是整个 DevOps 流水线的触发器(Trigger):
开发者本地开发
│
▼ git commit / git push
GitLab 远程仓库
│
▼ Webhook 触发
GitLab CI / Jenkins 流水线
│
▼ 自动执行
编译 → 测试 → 构建镜像 → 推送到 Harbor
│
▼ Helm 部署到 K8s
电商微服务更新
关键衔接点:
git push→ 触发 CI 流水线git tag v2.0.0→ 触发生产环境部署.gitignore→ 排除不需要进入镜像的文件(如本地配置、日志)
六、电商实战:.gitignore 与仓库规范
# ============================================
# .gitignore:告诉 Git 哪些文件不要跟踪
# 放在仓库根目录
# ============================================
# 编译输出目录(这些由 CI 重新生成)
target/
build/
*.jar
*.war
# IDE 配置文件(每个人环境不同)
.idea/
*.iml
.vscode/
*.swp
# 本地开发配置(含敏感信息)
application-local.yml
application-dev.yml
*.env
# 日志文件
logs/
*.log
# 依赖目录(Maven/Gradle 由 CI 重新下载)
# 注意:实际项目中通常提交 Maven Wrapper 但不提交依赖
node_modules/
# 操作系统文件
.DS_Store
Thumbs.db
# K8s 本地测试文件(不应提交)
kubeconfig-local
*.pem
*.key
七、总结
| 概念 | 说明 |
|---|---|
| Git | 分布式版本控制系统,每个开发者本地都有完整仓库 |
| 工作区 | 你看到的实际文件 |
| 暂存区(Index) | git add 后,文件等待被提交 |
| 本地仓库 | .git 目录,存储完整历史 |
| 远程仓库 | GitLab/GitHub,团队协作的中央同步点 |
| Commit | 本地提交,生成不可篡改的快照 |
| Push | 将本地提交同步到远程 |
| Branch | 平行时间线,支持多人并行开发 |
| Merge | 将分支的变更合并到一起 |
| Tag | 给某个 commit 打标记,通常用于版本发布 |
一句话:Git 是代码的"时光机"和"协作协议"——它让多人可以同时在不同分支上开发,记录每一次变更的原因,并在出问题随时回退,是触发 CI/CD 流水线、最终部署到 K8s 的源头。