Git 仓库管理命令完全指南(超级详细版)

3 阅读30分钟

Git 是目前最流行的分布式版本控制系统。本文将系统介绍 Git 仓库管理中的常用命令,从基础配置到高级操作,每个命令都配有详细说明和实际示例。

本文基于 Git 2.x 版本,涵盖日常开发 90% 以上的使用场景。


一、基础配置

在使用 Git 之前,需要先配置用户信息,这些信息会记录在每次提交中。

1. git config — 配置 Git 选项

语法

git config [--global] <key> <value>
git config --list

常用选项

选项说明
--global全局配置(当前用户)
--system系统配置(所有用户)
--local仓库级配置(默认)
--list列出所有配置
--unset删除配置项
--edit用编辑器打开配置文件

示例

# 设置用户名和邮箱(必须)
git config --global user.name "张三"
git config --global user.email "zhangsan@example.com"

# 设置默认编辑器为 VS Code
git config --global core.editor "code --wait"

# 设置别名(简化命令)
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --all"

# 查看所有配置
git config --list

# 查看特定配置
git config user.name

# 修改已有配置
git config --global user.name "李四"

# 删除配置
git config --global --unset user.name

# 设置不同仓库使用不同身份(仓库级配置)
cd myproject
git config user.email "work@company.com"

二、创建与克隆仓库

2. git init — 初始化一个新的 Git 仓库

语法

git init [目录名]

常用选项

选项说明
--bare创建裸仓库(无工作区,用于远程中心仓库)
--template指定模板目录
--initial-branch指定初始分支名(Git 2.28+)

示例

# 在当前目录初始化仓库
cd my-project
git init
# 输出:Initialized empty Git repository in /path/to/my-project/.git/

# 在指定目录初始化
git init new-project

# 初始化时指定默认分支为 main
git init --initial-branch=main

# 创建裸仓库(常用于服务器端)
git init --bare my-project.git

# 使用模板目录初始化
git init --template=/path/to/template

3. git clone — 克隆远程仓库到本地

语法

git clone <仓库地址> [本地目录名]

常用选项

选项说明
--depth <深度>浅克隆,只拉取最近的几次提交
--branch <分支名>克隆指定分支
--single-branch只克隆一个分支
--recursive递归克隆子模块
--origin <名称>设置远程仓库别名(默认 origin)
--no-checkout克隆后不自动检出工作区

示例

# 基本克隆
git clone https://github.com/user/repo.git

# 克隆到指定目录
git clone https://github.com/user/repo.git my-folder

# 使用 SSH 协议
git clone git@github.com:user/repo.git

# 浅克隆(只拉取最近 1 次提交,节省带宽)
git clone --depth 1 https://github.com/user/repo.git

# 克隆指定分支
git clone --branch develop https://github.com/user/repo.git

# 只克隆 main 分支
git clone --single-branch --branch main https://github.com/user/repo.git

# 克隆并递归初始化所有子模块
git clone --recursive https://github.com/user/repo.git

# 克隆后不自动 checkout(用于只读仓库或 CI)
git clone --no-checkout https://github.com/user/repo.git

三、基本快照操作(工作区 ↔ 暂存区 ↔ 仓库)

4. git status — 查看工作区和暂存区的状态

语法

git status [选项]

常用选项

选项说明
-s / --short简洁模式输出
-b显示分支信息(与 -s 连用)
--ignored显示被忽略的文件

示例

# 标准输出
git status
# On branch main
# Changes not staged for commit:
#   modified:   README.md
# Untracked files:
#   newfile.txt

# 简洁模式
git status -s
#  M README.md
# ?? newfile.txt

# 显示被忽略的文件
git status --ignored

5. git add — 将文件添加到暂存区

语法

git add <文件/目录>...

常用选项

选项说明
-A / --all添加所有修改、删除、新增的文件
-u / --update只添加已跟踪文件的修改/删除,不添加新文件
-p / --patch交互式选择部分修改块添加
-i / --interactive交互式添加
-f / --force强制添加被忽略的文件

示例

# 添加单个文件
git add index.html

# 添加多个文件
git add index.html style.css

# 添加整个目录
git add src/

# 添加所有变更(包括删除和新增)
git add -A
# 或者
git add .

# 只添加已跟踪文件的修改(不添加新文件)
git add -u

# 交互式选择部分修改块(非常有用)
git add -p README.md
# 会显示每个修改块,询问是否暂存:y/n/q/a/d/e...

# 强制添加被 .gitignore 忽略的文件
git add -f ignored-file.log

# 交互式添加界面
git add -i

6. git commit — 将暂存区内容提交到仓库

语法

git commit [-m "消息"]

常用选项

选项说明
-m "<消息>"直接提供提交消息
-a / --all自动暂存所有已跟踪文件的修改(跳过 git add)
--amend修改上一次提交(消息或内容)
--no-edit使用原消息修改提交(配合 --amend)
-s / --signoff添加 Signed-off-by 签名
--allow-empty允许空提交
-v在消息编辑器中显示差异

示例

# 基本提交(会打开编辑器输入消息)
git commit

# 带消息的提交
git commit -m "修复登录页面的样式问题"

# 多行消息
git commit -m "添加用户认证模块" -m "实现了 JWT 令牌验证"

# 跳过暂存区,直接提交所有已跟踪文件的修改
git commit -a -m "更新配置文件和文档"

# 修改上一次提交(修正提交消息)
git commit --amend -m "修正的提交消息"

# 修改上一次提交的内容(先 add 遗漏的文件)
git add forgotten-file.txt
git commit --amend --no-edit  # 保持原消息

# 空提交(用于触发 CI 等)
git commit --allow-empty -m "触发构建"

# 添加签名
git commit -s -m "更新版权信息"

7. git rm — 从工作区和暂存区删除文件

语法

git rm <文件>...

常用选项

选项说明
--cached只从暂存区删除,保留工作区文件
-f / --force强制删除(如果文件有未暂存的修改)
-r递归删除目录

示例

# 删除文件并暂存删除操作
git rm old-file.txt

# 删除目录
git rm -r old-dir/

# 只从 Git 中移除,但保留工作区文件(相当于停止跟踪)
git rm --cached config.local.json

# 强制删除(文件有本地修改时)
git rm -f important.txt

8. git mv — 移动或重命名文件

语法

git mv <源文件> <目标文件>

说明
相当于 mv old new + git add new + git rm old 的快捷方式。

示例

# 重命名文件
git mv index.html home.html

# 移动文件到子目录
git mv style.css assets/css/

# 移动并重命名
git mv old-name.txt src/new-name.txt

四、查看历史与差异

9. git log — 查看提交历史

语法

git log [选项] [分支/提交范围]

常用选项

选项说明
--oneline单行简洁输出
--graph以 ASCII 图形显示分支结构
--all显示所有分支
--decorate显示分支/标签指向
--author=<作者>按作者过滤
--since=<时间> / --after限定时间范围
--until=<时间> / --before限定时间范围
--grep=<模式>按提交消息过滤
-p / --patch显示每次提交的差异
--stat显示简略统计(修改的文件和行数)
--pretty=format:自定义输出格式
-n <数量>限制显示条数
--no-merges不显示合并提交

示例

# 完整历史
git log

# 单行显示最近 10 条
git log --oneline -10

# 图形化显示所有分支
git log --oneline --graph --all --decorate

# 查看某个作者的提交
git log --author="张三"

# 查看最近一周的提交
git log --since="1 week ago"

# 查看包含特定关键词的提交消息
git log --grep="修复"

# 显示每次提交的修改内容
git log -p -2

# 显示简略统计
git log --stat

# 自定义格式(哈希、作者、时间、消息)
git log --pretty=format:"%h - %an, %ar : %s"

# 查看某个文件的提交历史
git log README.md

# 查看两个分支之间的差异提交
git log main..develop

10. git diff — 查看差异

语法

git diff [选项] [<路径>...]
git diff <提交1> <提交2>

常用场景

  • 工作区 vs 暂存区
  • 暂存区 vs 最新提交(HEAD)
  • 工作区 vs 最新提交
  • 两次提交之间
  • 两个分支之间

常用选项

选项说明
--cached / --staged暂存区 vs HEAD
HEAD工作区 vs HEAD
--stat只显示统计信息
--name-only只显示文件名
--color-words按单词高亮差异
--ignore-space-change忽略空格变化

示例

# 工作区 vs 暂存区(默认)
git diff

# 暂存区 vs 最新提交
git diff --cached
git diff --staged

# 工作区 vs 最新提交
git diff HEAD

# 比较两个提交
git diff abc123 def456

# 比较两个分支
git diff main..develop
# 或者
git diff main develop

# 只显示修改的文件名
git diff --name-only

# 显示统计
git diff --stat

# 比较某个文件在不同版本
git diff HEAD~2 README.md

# 查看某个提交引入的变更(也可以用 git show)
git diff abc123^!   # ^! 表示该提交与其父提交的差异

11. git show — 显示某个提交的详细信息

语法

git show [提交哈希|标签|分支]

示例

# 显示最新提交
git show

# 显示指定提交
git show abc123

# 显示某个标签的信息
git show v1.0

# 只显示某个文件在某次提交中的变化
git show abc123:README.md

# 显示提交的统计信息
git show --stat abc123

# 简洁模式
git show --oneline -s   # -s 不显示差异

五、分支管理

12. git branch — 管理分支

语法

git branch [选项] [分支名]
git branch -d <分支名>   # 删除分支

常用选项

选项说明
(无参数)列出本地分支,当前分支带 *
-r列出远程分支
-a列出所有分支(本地+远程)
-v显示每个分支的最新提交
-vv显示本地分支关联的远程分支
-d删除已合并的分支
-D强制删除分支(无论是否合并)
-m重命名分支
-M强制重命名(覆盖同名)
--set-upstream-to=<远程分支>设置上游分支
--unset-upstream取消上游关联
--contains <提交>显示包含该提交的分支
--no-merged显示未合并到当前分支的分支

示例

# 列出本地分支
git branch
# * main
#   develop
#   feature-login

# 列出远程分支
git branch -r

# 列出所有分支
git branch -a

# 创建新分支(但不切换)
git branch feature-payment

# 创建分支并切换(等价于 git branch + git checkout)
git checkout -b feature-payment

# 删除已合并的分支
git branch -d feature-old

# 强制删除未合并的分支
git branch -D feature-abandoned

# 重命名当前分支
git branch -m new-name

# 重命名其他分支
git branch -m old-branch new-branch

# 设置上游分支(关联远程分支)
git branch --set-upstream-to=origin/develop develop

# 查看所有分支及其最后一次提交
git branch -v

# 查看哪些分支已合并到当前分支
git branch --merged

# 查看哪些分支未合并到当前分支
git branch --no-merged

# 显示包含特定提交的分支
git branch --contains abc123

13. git checkout / git switch — 切换分支或恢复文件

注意:Git 2.23 引入了 git switchgit restore 来分离 checkout 的功能。

git checkout 用法(传统方式)

git checkout <分支名>          # 切换分支
git checkout -b <新分支>       # 创建并切换
git checkout -- <文件>         # 丢弃工作区的修改
git checkout <提交> -- <文件>  # 从某次提交恢复文件

git switch 用法(推荐,更清晰)

git switch <分支名>            # 切换分支
git switch -c <新分支>         # 创建并切换
git switch --detach <提交>     # 切换到分离 HEAD 状态

示例

# 传统 checkout 切换分支
git checkout develop

# 创建并切换分支
git checkout -b feature-xyz

# 切换到上一个分支
git checkout -

# 丢弃工作区中某个文件的修改(不可恢复)
git checkout -- README.md

# 从某个提交恢复文件到工作区
git checkout abc123 -- src/app.js

# --- 使用 switch(Git 2.23+)---
git switch main

# 创建并切换
git switch -c new-feature

# 切换到上一个分支
git switch -

# 切换到某次提交(分离 HEAD)
git switch --detach abc123

14. git merge — 合并分支

语法

git merge <分支名>

常用选项

选项说明
--no-ff禁用快进合并,总是创建合并提交
--ff-only只允许快进合并,否则失败
--squash压缩合并(不记录合并来源,将所有提交压缩为一个)
--abort中止合并(解决冲突前)
--continue解决冲突后继续合并
--no-commit合并后不自动提交(用于进一步调整)
--edit在合并前编辑合并消息

示例

# 首先切换到目标分支(如 main)
git checkout main

# 将 feature 分支合并到 main
git merge feature-login

# 快进合并(默认行为,若可能)
git merge --ff-only feature-bugfix

# 强制创建合并提交(即使可以快进)
git merge --no-ff feature-new-ui

# 压缩合并(将 feature 的所有提交合并为一个)
git merge --squash feature-long
git commit -m "合并 feature-long 的所有更改"

# 合并后不自动提交(用于手动调整)
git merge --no-commit feature-test

# 中止合并(遇到冲突想放弃)
git merge --abort

# 解决冲突后继续合并
# 编辑冲突文件,然后:
git add .
git merge --continue

15. git merge 冲突解决示例

当两个分支修改了同一文件的同一区域时,Git 无法自动合并,需要手动解决。

# 尝试合并时出现冲突
git merge feature-branch
# Auto-merging index.html
# CONFLICT (content): Merge conflict in index.html
# Automatic merge failed; fix conflicts and then commit the result.

# 查看冲突文件
git status
# both modified:   index.html

# 编辑冲突文件,查找 <<<<<<<, =======, >>>>>>> 标记
# 手动修改后保存

# 标记为已解决
git add index.html

# 完成合并
git commit -m "解决合并冲突"

# 或者放弃合并
git merge --abort

16. git mergetool — 使用图形化工具解决冲突

# 启动配置的合并工具(如 vimdiff, meld, beyond compare)
git mergetool

# 设置默认合并工具
git config --global merge.tool meld

六、远程仓库协作

17. git remote — 管理远程仓库

语法

git remote [选项] [<名称>] [<URL>]

常用选项

选项说明
(无参数)列出远程仓库名称
-v显示远程仓库 URL(详细)
add <名称> <URL>添加新的远程仓库
remove <名称>移除远程仓库
rename <旧名> <新名>重命名远程仓库
set-url <名称> <新URL>修改远程仓库 URL
show <名称>显示远程仓库信息
prune <名称>删除本地不存在的远程分支引用

示例

# 查看远程仓库
git remote
# origin

# 查看详细信息(含 URL)
git remote -v
# origin  https://github.com/user/repo.git (fetch)
# origin  https://github.com/user/repo.git (push)

# 添加远程仓库
git remote add upstream https://github.com/original/repo.git

# 修改远程仓库 URL
git remote set-url origin https://new-url.git

# 删除远程仓库
git remote remove upstream

# 重命名
git remote rename origin upstream

# 显示某个远程仓库的详细信息
git remote show origin

# 清理远程分支引用(本地已不存在的远程分支)
git remote prune origin

18. git fetch — 从远程仓库拉取更新(不合并)

语法

git fetch [<远程名>] [<分支名>]

常用选项

选项说明
--all从所有远程仓库获取
--prune删除本地不存在的远程分支引用
--depth浅拉取
--tags同时拉取所有标签
--no-tags不拉取标签

示例

# 从 origin 拉取所有分支的更新
git fetch

# 拉取特定分支
git fetch origin main

# 拉取所有远程仓库
git fetch --all

# 拉取并清理已删除的远程分支引用
git fetch --prune

# 拉取所有标签
git fetch --tags

# 查看拉取后本地与远程的差异
git log origin/main..main   # 本地领先的提交
git log main..origin/main   # 远程领先的提交

19. git pull — 拉取并合并远程分支

语法

git pull [<远程名>] [<分支名>]

常用选项

选项说明
--rebase使用 rebase 而不是 merge 合并
--ff-only只允许快进合并
--no-commit拉取后不自动提交
--autostash自动暂存本地修改

示例

# 等同于 git fetch + git merge origin/main
git pull

# 拉取并 rebase(保持线性历史)
git pull --rebase

# 拉取指定远程分支
git pull origin develop

# 设置默认使用 rebase 方式拉取
git config --global pull.rebase true

# 拉取时自动暂存未提交的修改
git pull --autostash

20. git push — 推送本地提交到远程仓库

语法

git push [<远程名>] [<本地分支>[:<远程分支>]]

常用选项

选项说明
-u / --set-upstream设置上游分支并推送
--force / -f强制推送(覆盖远程历史)
--force-with-lease更安全的强制推送(如果远程有他人推送则拒绝)
--all推送所有分支
--tags推送所有标签
--delete删除远程分支
--dry-run模拟推送,不实际执行

示例

# 推送当前分支到 origin 的对应分支
git push

# 推送本地 main 到远程 main
git push origin main

# 推送本地 main 到远程 master(不同名称)
git push origin main:master

# 推送并设置上游跟踪
git push -u origin feature-branch
# 之后可以直接 git push

# 删除远程分支
git push origin --delete feature-old
# 或
git push origin :feature-old

# 强制推送(谨慎使用!会覆盖远程历史)
git push --force origin main

# 安全的强制推送(如果远程有新增提交会失败)
git push --force-with-lease origin main

# 推送所有分支
git push --all origin

# 推送标签
git push --tags

# 模拟推送(不实际执行)
git push --dry-run

21. git push 冲突解决

当远程有本地没有的提交时,push 会被拒绝。需要先 pull 合并或 rebase。

# 推送被拒绝
git push
# ! [rejected] main -> main (fetch first)

# 方法一:pull 后合并
git pull origin main
# 解决冲突(如果有)
git push

# 方法二:pull --rebase 保持线性历史
git pull --rebase origin main
# 解决冲突(如果有)
git rebase --continue
git push

# 方法三:强制推送(仅当确定覆盖远程,如个人分支)
git push --force-with-lease

七、撤销与恢复

22. git reset — 重置 HEAD 和暂存区/工作区

语法

git reset [--soft|--mixed|--hard] [<提交>]

三种模式

模式HEAD 指向暂存区工作区
--soft改变不变不变
--mixed (默认)改变重置到目标提交不变
--hard改变重置到目标提交重置到目标提交

示例

# 撤销最后一次提交,保留修改在工作区(等同于 uncommit)
git reset --soft HEAD~1

# 撤销最后一次提交,并将修改移回工作区(默认)
git reset HEAD~1
# 或
git reset --mixed HEAD~1

# 彻底丢弃最近 3 次提交的所有更改(危险!)
git reset --hard HEAD~3

# 取消暂存区的文件(等同于 git restore --staged)
git reset HEAD README.md

# 重置到指定提交,保留之后提交的更改在工作区
git reset --soft abc123

# 重置到某个标签
git reset --hard v1.0

# 撤销合并
git reset --hard ORIG_HEAD   # ORIG_HEAD 保存了合并前的 HEAD

23. git revert — 通过创建新提交来撤销某次提交

reset 不同,revert 不会修改历史,而是生成一个反向的新提交,适合公共分支。

语法

git revert <提交哈希>

常用选项

选项说明
-n / --no-commit不自动提交(可多次 revert 后统一提交)
-m <编号>指定主线(用于 revert 合并提交)
--continue / --abort处理冲突后继续/中止

示例

# 撤销某次提交
git revert abc123
# 会打开编辑器,确认撤销消息,然后创建新提交

# 撤销最近一次提交
git revert HEAD

# 撤销但不自动提交(用于批量撤销)
git revert -n abc123 def456
git commit -m "撤销 abc123 和 def456"

# 撤销一个合并提交(需要指定主线)
git revert -m 1 merge-commit-hash

# 处理冲突后继续
git revert abc123
# 解决冲突
git add .
git revert --continue

# 中止撤销
git revert --abort

24. git restore — 恢复工作区或暂存区文件(Git 2.23+)

分离自 git checkout 的功能,更直观。

语法

git restore [--source=<提交>] [--staged] [--worktree] <文件>

示例

# 丢弃工作区的修改(恢复文件到暂存区或 HEAD 的状态)
git restore README.md

# 取消暂存(将文件移出暂存区,保留修改)
git restore --staged README.md

# 同时取消暂存并丢弃工作区修改
git restore --staged --worktree README.md

# 从某个提交恢复文件到工作区
git restore --source=abc123 README.md

# 从某个提交恢复文件到暂存区
git restore --source=HEAD~2 --staged src/app.js

25. git clean — 删除未跟踪的文件

语法

git clean [选项]

常用选项

选项说明
-n / --dry-run预览要删除的文件(安全)
-f / --force强制删除(必须)
-d同时删除未跟踪的目录
-x删除被 .gitignore 忽略的文件
-X只删除被 .gitignore 忽略的文件

示例

# 预览会删除哪些未跟踪文件
git clean -n

# 删除所有未跟踪文件(不包含目录)
git clean -f

# 删除未跟踪文件和目录
git clean -fd

# 删除包括被忽略的文件(如临时文件、构建产物)
git clean -fdx

# 只删除被 .gitignore 忽略的文件
git clean -fX

26. git reflog — 查看引用日志(救命命令)

Git 会记录 HEAD 和分支的每一次移动。即使 reset --hard 丢失了提交,也能通过 reflog 找回。

语法

git reflog [<分支名>]
git reflog expire ...   # 清理过期的引用

示例

# 查看所有 HEAD 的移动历史
git reflog
# abc123 HEAD@{0}: commit: 添加新功能
# def456 HEAD@{1}: reset: moving to HEAD~2
# 789xyz HEAD@{2}: commit: 修复bug

# 找回被 reset 丢弃的提交
git reflog
# 找到丢弃前的提交哈希(如 abc123)
git checkout abc123   # 切换到该提交
# 或基于它创建新分支
git branch recovered-branch abc123

# 查看某个分支的 reflog
git reflog main

# 恢复误删的分支(通过 reflog 找到分支最后一次指向的提交)
git reflog
# 找到类似 "branch: created from main" 的记录
git checkout -b recovered-branch abc123

八、储藏(Stash)——临时保存工作区

27. git stash — 临时保存未提交的修改

当需要切换分支但当前工作区有未提交的修改时,可以使用 stash。

语法

git stash [push] [-m "<消息>"]
git stash list
git stash pop
git stash apply
git stash drop
git stash clear

常用选项/子命令

命令说明
stash / stash push保存当前修改(包括暂存区)
stash save "<消息>"旧语法,同上
stash list列出所有储藏
stash pop应用最新的储藏并删除它
stash apply [stash@{n}]应用储藏(不删除)
stash drop [stash@{n}]删除指定储藏
stash clear删除所有储藏
stash show [stash@{n}]显示储藏的差异
stash branch <分支名>从储藏创建新分支
stash push --keep-index保存工作区,但保持暂存区不变
stash push --include-untracked同时保存未跟踪的文件

示例

# 保存当前修改(自动生成消息)
git stash

# 保存并添加描述
git stash push -m "WIP: 登录验证逻辑"

# 查看所有储藏
git stash list
# stash@{0}: On main: WIP: 登录验证逻辑
# stash@{1}: On feature: 未完成的功能

# 应用最新的储藏(保留储藏)
git stash apply

# 应用并删除最新的储藏
git stash pop

# 应用指定的储藏
git stash apply stash@{1}

# 查看储藏的修改内容
git stash show stash@{0}
git stash show -p stash@{0}   # 显示详细差异

# 删除指定的储藏
git stash drop stash@{0}

# 删除所有储藏
git stash clear

# 从储藏创建新分支(自动应用并删除)
git stash branch new-feature stash@{0}

# 保存未跟踪的文件
git stash push -u

九、标签(Tag)——标记重要版本

28. git tag — 管理标签

标签用于标记特定的提交(如版本号 v1.0.0)。

语法

git tag [选项] [标签名] [提交]

常用选项

选项说明
(无参数)列出所有标签
-l "<模式>"匹配模式的标签
-a创建附注标签(带信息)
-m "<消息>"附注标签的消息
-d删除标签
-f强制覆盖已存在的标签
-s使用 GPG 签名标签

示例

# 列出所有标签
git tag
# v1.0.0
# v1.1.0

# 列出匹配模式的标签
git tag -l "v1.*"

# 创建轻量标签(仅指针)
git tag v1.0.0

# 创建附注标签(推荐,包含作者、日期、消息)
git tag -a v1.0.0 -m "发布 1.0.0 版本"

# 为历史提交打标签
git tag -a v0.9.0 abc123 -m "预发布版本"

# 查看标签信息
git show v1.0.0

# 删除本地标签
git tag -d v1.0.0

# 推送标签到远程
git push origin v1.0.0

# 推送所有标签
git push --tags

# 删除远程标签
git push origin --delete v1.0.0
# 或
git push origin :refs/tags/v1.0.0

# 覆盖已存在的标签(本地+远程)
git tag -f v1.0.0 -m "更新标签"
git push --force --tags

# 切换到标签(分离 HEAD)
git checkout v1.0.0

十、高级操作

29. git rebase — 变基(重新整理提交历史)

Rebase 可以将一系列提交复制到另一个基础之上,使历史线性化。

语法

git rebase <上游分支>
git rebase -i <基础提交>   # 交互式变基

常用选项

选项说明
-i / --interactive交互式变基(编辑、合并、删除提交)
--onto将提交移动到另一个目标上
--continue解决冲突后继续
--skip跳过当前提交
--abort中止变基
--autostash自动暂存未提交的修改

示例

# 将当前分支的提交变基到 main 分支上
git rebase main
# 当前分支的提交会重新应用在 main 的最新提交之后

# 交互式变基最近 3 个提交
git rebase -i HEAD~3
# 会打开编辑器,可以执行以下操作:
# pick   = 使用提交
# reword = 修改提交消息
# edit   = 修改提交内容
# squash = 合并到前一个提交
# fixup  = 合并并丢弃消息
# drop   = 删除提交

# 将 feature 分支的某段提交移动到另一个分支上
git rebase --onto main develop feature

# 从远程拉取并变基(代替 merge)
git pull --rebase

# 处理冲突
git rebase main
# 出现冲突,解决后:
git add .
git rebase --continue
# 或者跳过
git rebase --skip
# 或者放弃
git rebase --abort

30. git cherry-pick — 挑选其他分支的提交

语法

git cherry-pick <提交哈希>...

常用选项

选项说明
-n / --no-commit只应用更改,不自动提交
--continue / --abort处理冲突后继续/中止
--edit在提交前编辑消息
-x在消息中记录来源提交

示例

# 挑选一个提交到当前分支
git cherry-pick abc123

# 挑选多个提交
git cherry-pick abc123 def456

# 挑选一个范围
git cherry-pick abc123..def456

# 只应用更改,不提交(合并到工作区)
git cherry-pick -n abc123
git commit -m "手动提交"

# 处理冲突
git cherry-pick abc123
# 解决冲突后
git add .
git cherry-pick --continue
# 放弃
git cherry-pick --abort

31. git bisect — 二分查找定位引入 bug 的提交

语法

git bisect start
git bisect bad [<提交>]
git bisect good <提交>
git bisect reset

示例

# 开始二分查找
git bisect start

# 标记当前版本有问题
git bisect bad

# 标记某个旧版本正常(如 v1.0)
git bisect good v1.0

# Git 会检出中间的一个提交,需要测试该版本是否有问题
# 根据测试结果标记
git bisect good   # 如果这个版本正常
git bisect bad    # 如果这个版本有问题

# 重复上述步骤,直到找到第一个 bad 提交
# Git 会输出引入问题的提交哈希

# 结束二分查找,回到原来的分支
git bisect reset

# 使用脚本自动测试(如运行测试套件)
git bisect start HEAD v1.0
git bisect run npm test

32. git submodule — 管理子模块

常用子命令

命令说明
git submodule add <URL> [路径]添加子模块
git submodule init初始化子模块配置
git submodule update更新子模块到记录的提交
git submodule status查看子模块状态
git submodule foreach <命令>在每个子模块中执行命令

示例

# 添加子模块
git submodule add https://github.com/example/lib.git libs/example-lib

# 克隆包含子模块的仓库
git clone --recursive https://github.com/main/repo.git

# 已克隆但未拉取子模块
git submodule init
git submodule update

# 更新所有子模块到最新
git submodule update --remote

# 更新指定子模块
git submodule update --remote libs/example-lib

# 查看子模块状态
git submodule status

# 在每个子模块中执行 git pull
git submodule foreach git pull origin main

# 删除子模块(需要多个步骤)
git submodule deinit libs/example-lib
git rm libs/example-lib
# 手动删除 .git/modules/libs/example-lib

33. git worktree — 多工作树管理

允许同时检出多个分支到不同的目录,避免频繁切换。

语法

git worktree add <路径> [分支]
git worktree list
git worktree remove <路径>
git worktree prune

示例

# 在当前仓库外创建一个新的工作树,检出 feature 分支
git worktree add ../myproject-feature feature

# 创建新分支并检出新工作树
git worktree add -b hotfix ../myproject-hotfix main

# 列出所有工作树
git worktree list
# /path/to/main    abc123 [main]
# /path/to/feature def456 [feature]

# 移除工作树
git worktree remove ../myproject-feature

# 清理已删除工作树的引用
git worktree prune

34. git grep — 在 Git 管理的文件中搜索

语法

git grep [选项] <模式>

常用选项

选项说明
-n显示行号
-c显示匹配计数
-p显示包含匹配的函数名
-l只列出文件名
-i忽略大小写
--untracked同时搜索未跟踪文件
<提交>在指定提交中搜索

示例

# 在工作区搜索 "TODO"
git grep "TODO"

# 忽略大小写搜索
git grep -i "error"

# 显示行号
git grep -n "function"

# 只列出包含匹配的文件名
git grep -l "import React"

# 在旧版本中搜索
git grep "console.log" HEAD~5

# 跨分支搜索
git grep "fixme" main develop

# 使用正则表达式
git grep -E "TODO|FIXME"

35. git archive — 导出仓库快照为归档文件

语法

git archive --format=<格式> --output=<文件> <提交或分支>

示例

# 导出当前 HEAD 为 zip 包
git archive --format=zip --output=project.zip HEAD

# 导出为 tar.gz
git archive --format=tar.gz --output=project.tar.gz v1.0

# 导出指定分支,并排除某些目录
git archive --format=zip main | tar -x -C /tmp/project

# 带前缀的导出
git archive --prefix=myproject/ --format=zip HEAD > myproject.zip

# 导出时只包含特定路径
git archive --format=zip HEAD:src/ > src.zip

十一、维护与优化

36. git gc — 垃圾回收和仓库优化

语法

git gc [选项]

常用选项

选项说明
--aggressive更积极的优化(更慢,但压缩更好)
--auto只在必要时运行
--prune=<时间>删除过期对象

示例

# 执行常规垃圾回收
git gc

# 激进优化(适合大型仓库)
git gc --aggressive

# 自动模式(通常由 Git 自动触发)
git gc --auto

# 同时修剪过时的 reflog
git gc --prune=now

37. git fsck — 验证仓库完整性

语法

git fsck [选项]

常用选项

选项说明
--full完全检查
--unreachable显示无法访问的对象
--no-dangling不显示悬空对象

示例

# 检查仓库完整性
git fsck

# 详细输出
git fsck --full

# 检查悬空对象(可能是可恢复的数据)
git fsck --unreachable

38. git prune — 删除无法访问的对象

通常由 git gc 自动调用,但也可手动执行。

# 删除无法访问的对象(谨慎使用)
git prune

# 立即删除所有无法访问的对象
git prune --expire now

十二、调试与信息查看

39. git blame — 查看每一行代码的最后修改者

语法

git blame [选项] <文件>

常用选项

选项说明
-L <开始>,<结束>只显示指定行范围
-C检测跨文件复制的行
-M检测跨文件移动的行
-w忽略空白变化

示例

# 显示文件的每行修改记录
git blame README.md

# 显示第 10 到 20 行
git blame -L 10,20 src/app.js

# 忽略空白变化
git blame -w config.js

# 显示更详细的移动/复制检测
git blame -C -C index.html

40. git describe — 为提交生成可读的名称

基于最近的标签生成描述,如 v1.0-3-gabc123(表示在 v1.0 之后第 3 次提交,哈希 abc123)。

语法

git describe [选项] [<提交>]

示例

# 为当前 HEAD 生成描述
git describe
# v1.0.0-5-gabc123

# 使用标签名称,不显示提交计数
git describe --tags

# 总是显示完整哈希
git describe --always

# 匹配特定模式
git describe --match "v*"

41. git shortlog — 按作者分组显示提交摘要

语法

git shortlog [选项]

示例

# 按作者分组显示所有提交
git shortlog

# 显示统计(每个作者的提交数)
git shortlog -s -n
# 15  张三
# 8   李四

# 显示邮箱
git shortlog -e

# 限制版本范围
git shortlog v1.0..v2.0

十三、实用组合与技巧

42. 常用别名配置

# 美观的日志
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset - %C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

# 查看所有分支的最后提交
git config --global alias.lb "branch -vv"

# 撤销上一次提交(保留修改)
git config --global alias.undo "reset --soft HEAD~1"

# 查看所有贡献者
git config --global alias.contributors "shortlog -sn --no-merges"

# 清理已合并的本地分支
git config --global alias.clean-branches "!git branch --merged | grep -v '\\*\\|main\\|master\\|develop' | xargs -n 1 git branch -d"

# 查看今天的状态
git config --global alias.today "log --since='00:00:00' --oneline"

43. 常用场景命令组合

场景1:放弃所有本地修改

git reset --hard HEAD
git clean -fd

场景2:将某个文件恢复到指定版本

git checkout abc123 -- path/to/file

场景3:移动最近一次提交到新分支

git branch new-feature
git reset --hard HEAD~1
git checkout new-feature

场景4:合并多个提交为一个(交互式变基)

git rebase -i HEAD~3
# 将后两个的 pick 改为 squash 或 fixup

场景5:修改历史中的某个提交消息

git rebase -i HEAD~5
# 将对应提交的 pick 改为 reword
# 保存后编辑消息

场景6:找回误删的分支

git reflog
git checkout -b recovered-branch abc123

场景7:同步 fork 仓库与上游

git remote add upstream https://github.com/original/repo.git
git fetch upstream
git checkout main
git merge upstream/main
git push origin main

场景8:暂存部分修改(交互式添加)

git add -p file.py
# 选择 y(暂存该块)、n(不暂存)、e(手动编辑块)等

场景9:撤销 git add(取消暂存)

git restore --staged file.txt
# 或
git reset HEAD file.txt

场景10:查看两个分支的差异文件列表

git diff --name-only main..develop

十四、常见错误与解决方案

错误信息原因解决方案
fatal: not a git repository不在 Git 仓库目录中git init 或 cd 到正确目录
Updates were rejected because the remote contains work远程有本地没有的提交git pull --rebase 后再 push
fatal: refusing to merge unrelated histories合并两个独立仓库git pull --allow-unrelated-histories
CONFLICT (content): Merge conflict合并时文件冲突手动解决冲突后 git add + git commit
detached HEAD处于分离 HEAD 状态创建新分支 git switch -c new-branch
fatal: cannot lock ref引用锁定问题删除 .git/refs/heads/ 下的锁文件
error: failed to push some refs强制推送被拒绝使用 --force-with-lease 或先 pull
fatal: unable to auto-detect email address未配置 user.emailgit config --global user.email "you@example.com"

十五、命令速查表

分类命令作用
配置git config --global user.name "name"设置用户名
git config --global user.email "email"设置邮箱
git config --global alias.co checkout设置别名
初始化git init初始化仓库
git clone <url>克隆仓库
基本操作git status查看状态
git add <file>暂存文件
git commit -m "msg"提交
git rm <file>删除文件
git mv <old> <new>重命名文件
历史查看git log --oneline --graph查看历史
git diff查看差异
git show <commit>查看提交详情
git blame <file>查看行归属
分支git branch列出分支
git branch <name>创建分支
git checkout <name> / git switch切换分支
git merge <branch>合并分支
git branch -d <name>删除分支
远程git remote -v查看远程
git fetch拉取更新
git pull拉取并合并
git push推送
撤销git reset --soft HEAD~1撤销提交保留修改
git reset --hard HEAD丢弃所有修改
git revert <commit>反转提交
git restore <file>丢弃工作区修改
git clean -fd删除未跟踪文件
储藏git stash暂存修改
git stash pop应用并删除暂存
标签git tag -a v1.0 -m "msg"创建附注标签
git push --tags推送标签
高级git rebase -i HEAD~3交互式变基
git cherry-pick <commit>挑选提交
git bisect start二分查找
git reflog查看引用日志
维护git gc垃圾回收
git fsck验证完整性

结语

本文涵盖了 Git 仓库管理的绝大部分常用命令和典型场景。Git 功能极其丰富,实际工作中不需要记住所有选项,但理解核心概念(工作区、暂存区、本地仓库、远程仓库、分支、提交哈希)和常用命令的用法,足以应对日常开发。遇到不确定的情况,善用 git --helpgit <command> --help 查看详细文档。

不断练习和探索,你会逐渐掌握 Git 的强大能力。