首页 Git 核心命令指南
1.0.0 2026-04-21 git/git
打开 Zread CodeWiki
340px

🧭 概念入门 >>>

先理解 Git 的快照模型,再学命令会事半功倍。

Git 快照模型

Git 不是保存文件的差异,而是保存文件的完整快照。每次提交是对整个仓库的一次拍照。
  • 工作区 working tree:你当前编辑的文件
  • 暂存区 index/staged:已标记要提交的文件
  • 仓库 repository:所有提交历史

指针与引用

引用含义
HEAD指向当前分支的最新提交
origin/main远程跟踪分支
main本地分支

命令职责对照

命令核心职责
fetch更新远程跟踪分支
pull获取 + 合并远程提交
push上传本地提交
merge合并两个分支
rebase变基,重写提交历史
checkout/switch切换分支
reset重置 HEAD 位置

☁️ fetch 与 pull >>>

fetch 和 pull 很容易混淆。关键区别是 fetch 不动本地分支,pull 会直接合并。

fetch:只看不动

git fetch origin        # 获取所有远程分支更新
git fetch origin main  # 只获取 main 分支
git fetch --prune       # 清理已删除的远程分支

pull = fetch + merge

git pull                # 默认 fetch + merge
git pull --ff-only      # 只允许快进,有冲突则失败
git pull --rebase       # fetch + rebase,保持线性历史

场景选择

场景推荐
查看远程更新,不急着合并git fetch
本地分支落后远程,需要快进git pull --ff-only
保持线性历史,减少 merge 节点git pull --rebase
不确定有没有冲突先 git fetch,再看 git log

🔀 merge >>>

merge 把两条分支合并成一条。根据分支关系不同,合并类型也不同。

三种合并类型

1. Fast-forward(快进) 当分支没有分叉时,Git 直接把指针前移。
git checkout feature
git merge main  # 快进到 main
2. 递归合并 有分叉时创建 merge commit。
git merge main  # 创建合并提交
3. 快进失败 无法快进时,Git 会创建 merge commit。

常用选项

git merge --no-ff <branch>   # 即使能快进也创建 merge commit
git merge --squash <branch>  # 压扁所有提交为一个
git merge --abort            # 放弃当前合并

冲突处理

黄金法则

✂️ rebase >>>

rebase 会重写提交历史,把当前分支的提交"复制"到目标分支之上。

基本 rebase

git checkout feature
git rebase main  # 把 feature 变基到 main

rebase vs merge 对比

维度rebasemerge
历史线性、干净有 merge 节点
提交重写保留原样
适用个人分支整理公共分支
风险只能用于私有分支安全

交互式 rebase

git rebase -i HEAD~5  # 整理最近 5 个提交
动作效果
pick保留提交
reword只改提交说明
squash合并,保留说明
fixup合并,丢弃说明
drop删除提交

黄金法则

安全推送

git push --force-with-lease  # 比 --force 更安全

撤销 rebase

git reflog                      # 查看 rebase 前的 HEAD 位置
git reset --hard HEAD@{1}       # 恢复到 rebase 前

📦 压缩合并 >>>

把多个提交合并成一个的操作。适用于整理提交历史、清理零散补丁、合并功能分支。

git merge --squash

把指定分支的所有提交压缩成一个 merge commit,合并到当前分支。
git checkout main
git merge --squash feature/login   # 把 feature 分支所有提交压成一个
git commit -m "feat: add login feature"  # 手动写一个清晰的提交说明
原理:
  • 所有来自 feature 分支的改动保留,但提交历史被压缩成一条
  • 原分支的提交不会被保留在当前分支的历史里
  • 自动生成一个待提交的 merge commit,你需要手动写 message
使用场景:
场景说明
功能分支开发完毕把零碎的开发提交合并成一个大提交
合并他人的 PR把多个人提交的补丁压成一个清晰的提交
代码审查后合并审查过程中的小改动不需要保留在历史里
常见误区:
误区正确做法
squash 后忘记提交merge --squash 后必须 git commit 才能完成
误以为是 rebase--squash 是 merge 的一种,不会改写历史
想保留多个提交squash 会把所有提交合成一个
撤销方法:
# 如果还没提交,直接 reset
git reset --hard HEAD~1

# 如果已经提交,用 revert 创建反向提交
git revert -m 1 HEAD

git rebase -i squash / fixup

在交互式变基中,把多个连续的提交合并成一个。
git rebase -i HEAD~5  # 整理最近 5 个提交
squash vs fixup 对比:
动作commit message改动合并方式
squash合并后需要写新 message保留所有改动 + message
fixup直接丢弃后面的 message保留所有改动,自动用第一个 message
squash 示例:
# 在编辑器里把要合并的提交改成 squash
pick abc1234 feat: add login form
squash def5678 fix typo in form
squash 9123abc fix lint
编辑器会弹出让你写新的 commit message,保存后三个提交会合并成一个。
fixup 示例:
# fixup 会自动用第一个提交的消息,不需要写新 message
pick abc1234 feat: add login form
fixup def5678 fix typo
fixup 9123abc fix lint
常见误区:
误区正确做法
在已推送的分支上 squash不要在公共分支上操作,会改写历史
squash 后发现有问题用 git rebase --abort 取消,或 git reflog 恢复
把不相关的提交 squash 在一起只合并逻辑上相关的提交
撤销方法:
# 在 rebase 过程中取消
git rebase --abort

# rebase 完成后,用 reflog 恢复
git reflog
git reset --hard HEAD@{1}  # 恢复到 rebase 前

两种方式对比

维度merge --squashrebase -i squash/fixup
目的合并两个分支时压缩历史整理本地多个提交
结果一个 merge commit线性历史,无 merge 节点
是否改写历史否,保留原提交是,改写提交历史
适用分支任何分支只能用于本地、未推送的分支
操作时机合并时任何时候
撤销难度简单(reset 或 revert)复杂(需要 reflog)
选择建议:
  • merge --squash
  • rebase -i
  • merge --squash

🔄 checkout、switch 与 restore >>>

Git 2.23 把 checkout 的职责拆成了 switch(切换分支)和 restore(恢复文件)。

老式 checkout(仍有见到)

git checkout main        # 切换分支
git checkout -- file.txt # 丢弃文件修改

现代 switch(推荐)

git switch main          # 切换到 main
git switch -c feat/xxx   # 创建并切换
git switch -            # 回到上一个分支

restore(Git 2.23+)

git restore file.txt           # 丢弃工作区修改
git restore --staged file.txt  # 取消暂存
git restore --source=HEAD~1 file.txt  # 从指定提交恢复

职责对照

命令职责
git checkout切换分支 + 恢复文件(老式)
git switch只切换分支
git restore只恢复文件

⏪ reset >>>

reset 用于移动 HEAD 指针,配合不同模式可以控制暂存区和工作区的状态。

三种模式对比

模式HEAD暂存区工作区常见用途
--soft回退保留保留撤销提交,保留暂存
--mixed回退重置保留取消暂存,把改动放回工作区
--hard回退重置重置彻底回滚,危险

常用场景

# 撤销最近提交,保留暂存(可以重新提交)
git reset --soft HEAD~1

# 取消暂存,把改动放回工作区
git reset --mixed HEAD~1

# 彻底回滚(危险!)
git reset --hard HEAD~1

reflog 后悔药

git reflog                        # 查看所有操作历史
git reflog --date=relative        # 显示相对时间
git reset --hard HEAD@{2}         # 恢复到某个操作前

revert vs reset

场景推荐原因
撤销已推送的公共提交git revert不改历史,安全
撤销未推送的本地提交git reset不用生成反向提交

⬆️ push >>>

push 把本地提交上传到远程仓库。

基本用法

git push                          # 推送到默认 upstream
git push origin main              # 推送到指定远端分支
git push -u origin feature        # 首次推送,建立 upstream
git push --force-with-lease       # 安全强推

force-with-lease vs force

命令安全性
--force危险,可能覆盖他人推送
--force-with-lease更好,如果远程有更新会拒绝

删除远程分支

git push origin --delete old-branch

设置默认行为

git config --global push.autoSetupRemote true  # 首次 push 自动建立 upstream

📋 速查对照表

快速查找各命令的核心参数和用法。

reset 三兄弟

命令HEAD暂存区工作区
reset --soft HEAD~1回退保留保留
reset --mixed HEAD~1回退重置保留
reset --hard HEAD~1回退重置重置

pull 策略

命令效果
pullfetch + merge
pull --ff-only只接受快进,有冲突则失败
pull --rebasefetch + rebase

rebase -i 动作

动作效果
pick保留
reword改 message
squash合并,保留 message
fixup合并,丢弃 message
drop删除

checkout / switch / restore

场景命令
切换分支switch <branch>
创建并切换switch -c <branch>
恢复文件(丢弃修改)restore <file>
取消暂存restore --staged <file>