Git
发表于:2026-07-29
字数统计:5500 字
预计阅读19分钟
涵盖 Git rebase vs merge、Git 三大区、常用命令速查、Git Flow、撤销与回滚。
一、Git 三大区
Plain
┌──────────────┐ git add ┌──────────────┐ git commit ┌──────────────┐
│ Working │ ─────────→ │ Staging │ ───────────→ │ Repository │
│ Directory │ │ Area (Index) │ │ (.git) │
│ (工作区) │ git reset │ (暂存区) │ git reset │ (版本库) │
│ │ ←───────── │ │ ←─────────── │ │
└──────────────┘ -- └──────────────┘ -- └──────────────┘
(撤销暂存) (回退版本)二、git rebase vs git merge
1. 概念
Plain
共同目标:把分支合并到目标分支
merge:
- 在目标分支上创建一个 merge commit
- 保留分支历史(保留"合并动作")
- 历史是分叉的图状结构
rebase:
- 把当前分支的 commit 重新"接到"目标分支最新 commit 之后
- 改写 commit 历史(commit hash 会变)
- 历史是线性结构2. 实际效果对比
Plain
初始状态:
A---B---C (master)
\
D---E (feature)
git checkout feature
git merge master:
A---B---C---F (master)
\ /
D---E (feature)
↑
merge commit
git checkout feature
git rebase master:
A---B---C---D'---E' (feature)
↑
master 指针
效果:feature 分支的 commit 被"重新接到" master 最新 commit 之后3. 优缺点
| 维度 | merge | rebase |
|---|---|---|
| 历史 | 真实(保留分叉) | 整洁(线性) |
| commit hash | 不变 | 变化(被改写) |
| 冲突处理 | 一次合并冲突 | 每个 commit 可能都冲突 |
| 回溯 | 简单(保留 commit) | 复杂(commit hash 变了) |
| 适用场景 | 公共分支、保留历史 | 本地分支、整理提交 |
4. 黄金法则
Plain
默认不要改写其他协作者已经基于其开发的公共历史;只有团队明确协调、了解影响并允许重写时才考虑这样做。
原因:
- rebase 会改写 commit hash
- 其他人的分支会与远程不一致
- 导致协作混乱
安全使用:
- 仅对自己本地的、还未推送的分支使用 rebase
- 团队约定主分支不用 rebase
- rebase 后强制推送前确认(git push --force-with-lease)5. 实战命令
Bash
# 基础 rebase
git checkout feature
git rebase master # 把 feature 接到 master 最新 commit 后
# 解决冲突
# 1. 编辑冲突文件
# 2. git add <冲突文件>
# 3. git rebase --continue
# 4. 如要放弃:git rebase --abort
# 交互式 rebase(整理 commit)
git rebase -i HEAD~3 # 修改最近 3 个 commit
# 命令:
# pick = 保留
# reword = 修改 commit 信息
# edit = 修改 commit 内容
# squash = 合并到前一个 commit
# drop = 删除 commit6. 合并策略选择
Plain
团队分支流程:
1. 在 feature 分支开发
2. 提交前先 git fetch + git rebase origin/master
3. 解决冲突后,再合并到 master(用 merge)
4. 这种方式:master 历史线性,feature 历史保留
即:本地 rebase + 远程 merge三、Git 常用命令速查
1. 仓库操作
Bash
# 初始化
git init
git clone <url>
# 配置
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
# 远程仓库
git remote add origin <url>
git remote -v
git push -u origin main2. 基本操作
Bash
# 查看状态
git status
# 添加到暂存区
git add <file> # 单个文件
git add . # 所有修改
git add -p # 交互式添加(推荐)
# 提交
git commit -m "feat: 新增功能"
git commit --amend # 修改最后一次提交(重新写信息或追加改动)
# 查看历史
git log
git log --oneline --graph
git log -p <file> # 查看某文件的历史修改3. 撤销与回滚
Bash
# 撤销工作区修改
git checkout -- <file>
git restore <file> # 新版命令
# 撤销暂存
git reset HEAD <file>
git restore --staged <file>
# 回退版本
git reset --soft HEAD^ # 撤销 commit,保留修改在暂存区
git reset --mixed HEAD^ # 撤销 commit + 暂存,保留修改在工作区(默认)
git reset --hard HEAD^ # 撤销一切(危险!)
# 安全回退(推荐)
git revert <commit> # 生成新 commit 撤销指定 commit(适合已推送)
# 找回丢失的 commit
git reflog # 查看所有 HEAD 移动记录4. 分支操作
Bash
# 创建与切换
git branch <name>
git checkout -b <name> # 创建并切换
git switch -c <name> # 新版命令
# 查看分支
git branch -a # 所有分支(含远程)
git branch -vv # 带跟踪信息
# 合并与衍合
git merge <branch>
git rebase <branch>
# 删除分支
git branch -d <name> # 安全删除(合并后才能删)
git branch -D <name> # 强制删除5. 远程操作
Bash
# 拉取与推送
git fetch # 只拉取,不合并
git pull # fetch + merge(默认)
git pull --rebase # fetch + rebase(推荐)
# 推送
git push
git push -f # 强制推送(危险!)
git push --force-with-lease # 安全强制推送(推荐)
# 远程分支
git push origin --delete <branch> # 删除远程分支6. 储藏(Stash)
Bash
# 临时保存工作区修改
git stash
git stash save "message"
# 查看
git stash list
# 恢复
git stash pop # 恢复并删除
git stash apply stash@{0} # 恢复但保留
# 删除
git stash drop stash@{0}
git stash clear # 清除所有四、Git Flow 工作流
Plain
Git Flow 是一种经典的工作流,适合有版本发布周期的项目:
master(主分支) —— 稳定版本,每个 commit 都是一个 release
develop(开发分支) —— 日常开发
feature/*(功能分支) —— 新功能,从 develop 切出,完成后合并回 develop
release/*(发布分支) —— 版本发布准备,从 develop 切出,发布后合并到 master + develop
hotfix/*(热修复分支) —— 紧急修复,从 master 切出,修复后合并回 master + develop
工作流:
1. 从 develop 切出 feature/login
2. 开发完成,PR 到 develop
3. 准备发布,从 develop 切出 release/v1.0
4. 测试通过,合并 release/v1.0 到 master(打 tag)和 develop
5. 上线后如有问题,从 master 切出 hotfix/bug
6. 修复后合并回 master 和 develop简化版:GitHub Flow
Plain
GitHub Flow(适合持续部署):
1. master 永远是可部署的
2. 从 master 切出功能分支
3. 在功能分支提交
4. 提 PR(Pull Request)
5. Code Review 后合并回 master
6. 合并后自动部署
简单直接,适合现代 SaaS 项目五、冲突解决
Plain
冲突发生的场景:
1. 两个分支修改了同一文件的同一行
2. 一个分支删除了文件,另一个分支修改了文件
冲突标记:
<<<<<<< HEAD
当前分支的内容
=======
合并分支的内容
>>>>>>> branch-name
解决步骤:
1. git status 看哪些文件冲突
2. 编辑冲突文件,决定保留哪部分
3. 删除冲突标记
4. git add <file>
5. git commit(或 git rebase --continue)六、面试高频问答
Q1: git rebase 和 git merge 的区别?
答:
- merge:在目标分支创建一个 merge commit,保留分支历史(分叉结构)
- rebase:把当前分支的 commit 重新接到目标分支最新 commit 之后,改写历史(线性结构)
协作原则:不要在未协调的情况下 rebase 并强推共享分支;若团队明确允许历史重写,应通知协作者并优先使用 --force-with-lease,同时理解它也不是并发写入的绝对保险。
实战选择:
- 自己本地分支:用 rebase(整理历史)
- 团队协作:用 merge(保留真实历史)
- 推荐模式:本地 rebase + 远程 merge
Q2: git reset 和 git revert 的区别?
答:
- git reset:回退到指定 commit,改写历史(不推荐用于已推送)
--soft:保留修改在暂存区--mixed:保留修改在工作区(默认)--hard:完全丢弃修改(危险)
- git revert:生成一个新的 commit,撤销指定 commit 的改动(适合已推送)
- 不会改写历史
- 会保留原 commit 记录
Q3: 怎样找回被 reset --hard 的 commit?
答:
Bash
# 1. git reflog 查看所有 HEAD 移动
git reflog
# 2. 找到目标 commit hash
# a1b2c3d HEAD@{5}: commit: feat: 提交功能
# 3. 重置回去
git reset --hard a1b2c3d
# 注意:reflog 只在本地保留 30-90 天(取决于 gc 设置)Q4: git pull 和 git pull --rebase 的区别?
答:
git pull=git fetch+git mergegit pull --rebase=git fetch+git rebase
如果本地有未推送的 commit,merge 会产生 merge commit,rebase 会让本地 commit 接到远程最新 commit 之后(保持线性历史)。
推荐:默认用 git pull --rebase,可以通过配置设为默认:
Bash
git config --global pull.rebase true