Git 命令大全
Git 是目前最流行的分布式版本控制系统。本文档整理了日常开发中最常用的 Git 命令,按使用场景分类,方便快速查阅。
一、配置相关
用户信息
| # 设置用户名和邮箱(全局)
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
# 设置用户名和邮箱(仅当前项目)
git config user.name "你的名字"
git config user.email "你的邮箱@example.com"
# 查看当前配置
git config --list
git config --global --list
|
别名配置
| # 设置常用别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all"
# 使用别名:git st 等价于 git status
|
换行符配置
| # Windows 推荐:提交时转 LF,检出时转 CRLF
git config --global core.autocrlf true
# macOS/Linux 推荐:提交时转 LF,检出时不转换
git config --global core.autocrlf input
# 仅关闭警告
git config --global core.safecrlf false
|
二、仓库初始化与克隆
初始化新仓库
| # 在当前目录初始化 Git 仓库
git init
# 初始化并指定默认分支名
git init -b main
|
克隆远程仓库
| # 克隆到默认目录名
git clone https://github.com/用户名/仓库名.git
# 克隆到指定目录
git clone https://github.com/用户名/仓库名.git 我的目录
# 克隆指定分支
git clone -b 分支名 https://github.com/用户名/仓库名.git
# 浅克隆(只克隆最近 N 次提交,速度快)
git clone --depth=1 https://github.com/用户名/仓库名.git
|
三、基本操作
文件状态
| # 查看文件状态
git status
# 简略状态(一行一个文件)
git status -s
# ?? Untracked(未跟踪)
# M Modified(已修改,未暂存)
# M Modified(已暂存)
# MM Modified(已暂存,又修改)
|
添加文件到暂存区
| # 添加单个文件
git add 文件名.md
# 添加所有文件
git add -A
# 或
git add .
# 添加当前目录所有 .py 文件
git add *.py
# 交互式添加(可选择部分改动)
git add -p
|
提交
| # 提交暂存区的内容
git commit -m "提交说明"
# 跳过暂存区,直接提交已跟踪文件的修改
git commit -a -m "提交说明"
# 修改上一次提交(不要已推送到远程)
git commit --amend -m "新的提交说明"
# 空提交(用于触发 CI 等)
git commit --allow-empty -m "触发构建"
|
Git Commit Message 规范(Conventional Commits 约定)
也就是 type(scope): 描述 这种格式,最常用全套类型含义,全部给你整理好。
最常用类型
| 类型 |
含义 |
说明示例 |
feat |
新功能 |
新增业务功能、新接口、新页面 |
fix |
修复 bug |
解决代码缺陷、报错、逻辑问题 |
docs |
文档更新 |
只改 README、注释、文档,不动业务代码 |
style |
代码风格调整 |
空格、分号、格式化;不修改代码逻辑 |
refactor |
代码重构 |
既不加功能,也不修bug;优化结构、提取函数 |
perf |
性能优化 |
提升速度、减少内存、优化查询等 |
test |
测试相关 |
添加测试用例、修改单元测试、e2e测试 |
chore |
构建/杂项任务 |
修改打包脚本、依赖、CI配置、工具,不影响源码 |
扩展进阶类型(团队常用)
| 类型 | 含义 |
| -------- | ------------ | -------------------------------------------------------- |
| build | 构建系统改动 | webpack、gradle、docker、编译配置修改 |
| ci | 持续集成 | github‑action、gitlab‑ci、jenkins流水线配置 |
| revert | 回滚提交 | 撤销上一次/某次 commit,示例:revert: 回滚xxx提交 |
| hotfix | 紧急热修复 | 线上紧急bug(有些规范会直接用 fix,hotfix 属于语义叫法) |
可选 scope(括号里的范围)
feat(user): 新增用户登录接口
user 就是 scope,代表改动模块/范围,可选
例子:
| feat(login): 添加短信登录功能
fix(order): 修复订单金额计算错误
docs: 更新部署文档
refactor(api): 重构请求封装
chore: 更新package依赖版本
|
完整提交消息示例
| feat(home): 首页新增轮播图
fix: 修复点击按钮无响应问题
refactor(user): 拆分用户工具函数
perf(list): 优化列表渲染速度
test: 增加购物车单元测试
chore: 升级vue版本
docs: 修改接口文档
style: 格式化多余空行
revert: 回滚"新增支付功能"提交
|
提交命令例子
| git commit -m "docs(README): 补充项目安装步骤与环境要求" -m "- 新增 Windows/Linux 双平台的依赖安装命令
- 补充 Node.js 版本要求(>= 18)及环境变量配置说明
- 修正原有快速开始章节中过期的脚本命令"
|
说明:
- 多个
-m 参数会自动用空行拼接,第一个是标题,第二个是正文。
- 正文里的换行直接在引号内换行即可,不需要额外转义。
如果是小改动只写标题:
| git commit -m "docs(README): 修正安装命令中的拼写错误"
|
完整流程一般是:
| git add .
git commit -m "docs(README): 补充项目安装步骤与环境要求" -m "- 新增 Windows/Linux 双平台的依赖安装命令
- 补充 Node.js 版本要求(>= 18)及环境变量配置说明
- 修正原有快速开始章节中过期的脚本命令"
git push
|
快速记忆口诀
feat新功能,fix修bug
docs改文档,style调格式
refactor重构造,perf提性能
test写测试,chore杂活干
查看差异
| # 查看工作区与暂存区的差异
git diff
# 查看暂存区与最近一次提交的差异
git diff --cached
# 或
git diff --staged
# 查看两个提交之间的差异
git diff 提交1的Hash 提交2的Hash
# 查看某个文件的修改历史
git diff -- 文件名.md
|
四、分支管理
查看分支
| # 查看本地分支(当前分支前有 * 号)
git branch
# 查看所有分支(含远程)
git branch -a
# 查看分支的最近一次提交
git branch -v
# 查看已合并/未合并的分支
git branch --merged
git branch --no-merged
|
创建与切换分支
| # 创建分支
git branch 分支名
# 切换分支
git checkout 分支名
# 或(新版 Git 推荐)
git switch 分支名
# 创建并切换到新分支
git checkout -b 分支名
# 或
git switch -c 分支名
# 基于远程分支创建本地分支
git checkout -b 本地分支名 origin/远程分支名
|
合并分支
| # 将指定分支合并到当前分支
git merge 分支名
# 合并时创建合并提交(即使可以快进)
git merge --no-ff 分支名
# 压缩合并(合并为一个提交)
git merge --squash 分支名
|
删除分支
| # 删除本地分支(已合并)
git branch -d 分支名
# 强制删除本地分支(未合并也能删)
git branch -D 分支名
# 删除远程分支
git push origin --delete 分支名
|
重命名分支
| # 重命名当前分支
git branch -m 新分支名
# 重命名指定分支
git branch -m 旧分支名 新分支名
|
五、远程仓库
管理远程仓库
| # 查看远程仓库
git remote -v
# 添加远程仓库
git remote add origin https://github.com/用户名/仓库名.git
# 删除远程仓库
git remote remove origin
# 修改远程仓库 URL
git remote set-url origin https://github.com/用户名/仓库名.git
|
拉取与推送
| # 拉取远程更新(不自动合并)
git fetch origin
# 拉取并合并到当前分支
git pull
# 等价于 git fetch + git merge
# 拉取并变基
git pull --rebase
# 推送本地分支到远程
git push origin 分支名
# 推送并建立上游关联(首次推送用)
git push -u origin 分支名
# 推送所有分支
git push --all
# 推送标签
git push origin --tags
# 强制推送(慎用!会覆盖远程历史)
git push --force
# 更安全的强制推送(远程拒绝时才覆盖)
git push --force-with-lease
|
六、查看历史
日志
| # 查看提交历史
git log
# 单行显示
git log --oneline
# 图形化显示
git log --graph --oneline --all
# 显示最近 N 条
git log -5
# 查看某个文件的修改历史
git log --follow -- 文件名.md
# 按日期过滤
git log --after="2024-01-01" --before="2024-12-31"
# 按作者过滤
git log --author="用户名"
# 显示每次修改的统计
git log --stat
# 搜索提交消息中的关键词
git log --grep="关键词"
|
查看具体提交
| # 查看某个提交的详细信息
git show 提交Hash
# 查看某个提交修改了哪些文件
git show --stat 提交Hash
# 查看某个文件在某次提交中的内容
git show 提交Hash:文件路径
|
七、撤销与恢复
工作区撤销
| # 撤销工作区的修改(用暂存区覆盖工作区)
git checkout -- 文件名.md
# 或
git restore 文件名.md
# 撤销所有未暂存的修改
git restore .
# 从指定提交恢复文件到工作区
git restore --source=提交Hash 文件名.md
|
暂存区撤销
| # 从暂存区移除文件(保留工作区修改)
git reset HEAD 文件名.md
# 或
git restore --staged 文件名.md
|
提交撤销
| # 撤销最近一次提交,保留修改到工作区
git reset --soft HEAD~1
# 撤销最近一次提交,保留修改到暂存区
git reset --mixed HEAD~1
# 撤销最近一次提交,丢弃修改
git reset --hard HEAD~1
# 回退到指定提交,之后的提交都被丢弃(慎用)
git reset --hard 提交Hash
# 用新提交来撤销历史提交(更安全,适合已推送的情况)
git revert 提交Hash
# 撤销多个提交
git revert 提交Hash1..提交Hash5
|
暂存工作区
| # 暂存当前工作区的修改(可以切换到其他分支工作)
git stash
# 暂存并添加说明
git stash push -m "临时保存"
# 查看暂存列表
git stash list
# 恢复最近一次暂存(保留暂存)
git stash pop
# 恢复但不删除暂存
git stash apply
# 删除指定暂存
git stash drop stash@{0}
# 清空所有暂存
git stash clear
|
八、标签管理
| # 创建轻量标签
git tag v1.0.0
# 创建带注释的标签(推荐)
git tag -a v1.0.0 -m "版本 v1.0.0"
# 为历史提交打标签
git tag -a v1.0.0 提交Hash -m "版本 v1.0.0"
# 查看所有标签
git tag
# 查看标签信息
git show v1.0.0
# 推送标签到远程
git push origin v1.0.0
# 推送所有标签
git push origin --tags
# 删除本地标签
git tag -d v1.0.0
# 删除远程标签
git push origin --delete v1.0.0
|
九、变基(Rebase)
基本变基
| # 将当前分支的提交变基到目标分支
git rebase 目标分支
# 交互式变基(修改历史提交)
git rebase -i HEAD~3
# 变基时跳过某个提交
git rebase --skip
# 中止变基(回到变基前状态)
git rebase --abort
# 变基完成后继续(解决冲突后)
git rebase --continue
|
交互式变基常用操作
| 命令 |
含义 |
pick |
保留该提交 |
reword |
保留提交,修改提交消息 |
edit |
保留提交,但停下来修改 |
squash |
合并到上一个提交 |
fixup |
合并到上一个提交,丢弃提交消息 |
drop |
删除该提交 |
十、Cherry-Pick
| # 将某个提交应用到当前分支
git cherry-pick 提交Hash
# 应用多个提交
git cherry-pick 提交Hash1 提交Hash2
# 连续应用一段提交
git cherry-pick 提交Hash1..提交Hash5
# 只应用更改,不自动提交
git cherry-pick -n 提交Hash
|
十一、子模块
| # 添加子模块
git submodule add https://github.com/用户名/仓库名.git 路径
# 初始化子模块(克隆后)
git submodule init
git submodule update
# 一条命令完成初始化+更新
git submodule update --init --recursive
# 更新子模块到最新提交
git submodule update --remote
|
十二、高级操作
查找与搜索
| # 搜索提交历史中的改动
git log -S "关键词" --all
# 或
git log -G "正则表达式" --all
# 二分查找(定位引入 Bug 的提交)
git bisect start
git bisect bad # 当前版本有 Bug
git bisect good 提交Hash # 该版本正常
# 重复:标记 bad/good → 定位到第一个有 Bug 的提交
git bisect reset # 退出二分查找
|
清理
| # 清理未跟踪的文件和目录
git clean -fd
# 预览要清理的文件
git clean -n
|
归档
| # 将当前分支打包为 ZIP
git archive --format=zip HEAD -o project.zip
# 打包指定分支
git archive --format=zip 分支名 -o project.zip
|
十三、常用工作流示例
场景一:新功能开发
| # 1. 拉取最新代码
git checkout main
git pull
# 2. 创建功能分支
git checkout -b feat-xxx
# 3. 开发过程中暂存提交
git add -A
git commit -m "feat: xxx"
# 4. 同步主分支的更新
git checkout main
git pull
git checkout feat-xxx
git rebase main # 或 git merge main
# 5. 合并回主分支
git checkout main
git merge feat-xxx
git push
|
场景二:修复 Bug
| # 从主分支创建修复分支
git checkout main
git checkout -b fix-xxx
# 修复并提交
git add -A
git commit -m "fix: xxx"
# 合并回主分支
git checkout main
git merge fix-xxx
git push
|
场景三:挽救误操作
| # 删错了文件,还没提交
git checkout -- 文件名.md
# 提交后发现错了,还没推送
git reset --soft HEAD~1 # 撤回提交,保留修改
# 提交并推送了,想撤销
git revert HEAD # 生成一个新的反向提交
git push
|
场景四:处理冲突
| # 1. 拉取时提示冲突
git pull
# 输出:CONFLICT in 文件名.md
# 2. 打开文件,搜索 <<<<<<< 和 >>>>>>>
# 手动选择保留哪部分,删除冲突标记
# 3. 标记冲突已解决
git add 文件名.md
# 4. 完成合并
git commit -m "解决合并冲突"
|
十四、 .gitignore 常用规则
| # 忽略特定文件
*.log
*.tmp
.env
.DS_Store
# 忽略目录
node_modules/
__pycache__/
.venv/
# 排除忽略(强制跟踪)
!important.log
# 忽略根目录下特定文件(不递归)
/config.json
|
十五、文件名大小写敏感性问题
问题现象
在 Windows 上重命名文件时,如果只改了英文字母大小写(如 Readme.md → README.md),Git 可能检测不到变化:
| # Windows 上执行,Git 可能认为没有变化
git mv Readme.md README.md
git status # 没有输出,Git 认为文件没变
|
原因
- Windows 文件系统(NTFS):大小写不敏感,
File.md 和 file.md 被视为同一个文件
- macOS(APFS):默认也大小写不敏感(但可以格式化时选择敏感)
- Linux(ext4/XFS):大小写敏感,
File.md 和 file.md 是两个不同的文件
- Git 本身:大小写敏感,但 Windows/macOS 上受底层文件系统限制
后果
本地开发正常,但部署到 Linux 服务器时出现 404 或构建失败:
| 本地 Windows ✅ → git push → 远程 Linux ❌ 404
|
典型场景:mkdocs.yml 中引用 Fork Git操作.md,但 Git 中实际存储的是 fork git操作.md(小写)。本地构建正常,Cloudflare Pages(Linux)上找不到文件。
解决方法
方法一:两步重命名(推荐)
在 Windows 上无法直接 File.md → file.md,需通过临时名过渡:
| # 第一步:改成一个完全不同的临时名
git mv "File.md" "file_temp.md"
# 第二步:再改回目标小写名
git mv "file_temp.md" "file.md"
# 提交
git commit -m "refactor: 统一文件名大小写"
|
方法二:强制 Git 检测大小写
| # 临时让 Git 检测大小写变化
git config core.ignorecase false
# 重命名后提交
git mv Readme.md README.md
git commit -m "fix: 修正文件名大小写"
|
方法三:直接修改 Git 索引
| # 删除旧的小写记录
git rm --cached "docs/file.md"
# 添加正确大小写的新文件
git add "docs/File.md"
# 提交
git commit -m "fix: 修正文件名大小写"
|
最佳实践
- 文件名统一使用全小写,避免大小写带来的跨平台问题
- 英文字母部分全小写,中文部分保持不变(如
git命令大全.md)
- 新增文件时,
mkdocs.yml 中的引用路径必须与实际文件名完全一致
- 提交前执行
mkdocs build --clean 验证,确保无死链
十六、远程跟踪分支与 origin/HEAD 详解
三个层级的概念
以 git branch -a 的输出为例:
| * main # ① 本地分支
remotes/origin/main # ② 远程跟踪分支
remotes/origin/HEAD -> origin/main # ③ 符号引用(远程默认分支指针)
|
| 名称 |
全称 |
存在位置 |
是什么 |
main |
本地分支 |
.git/refs/heads/main |
你实际检出的工作分支,可读可写,commit 会移动它 |
origin/main |
远程跟踪分支 |
.git/refs/remotes/origin/main |
本地缓存的一份"远程仓库 main 分支的快照",只读,不能直接 checkout 工作 |
origin/HEAD |
符号引用(symref) |
.git/refs/remotes/origin/HEAD |
不是分支,是一个指针,指向"远程默认分支",即 origin/main |
关键理解点
origin/main 不是实时的。它只在 git fetch / git pull / git clone 时更新,是"上次从远程拉取时的样子"。远程有人推送了新提交,在你不 fetch 之前,本地缓存的 origin/main 不会变。
origin/HEAD → origin/main 的含义:表示远程仓库的默认分支是 main。clone 仓库时,Git 靠它决定默认检出哪个分支。箭头右边是它实际指向的目标。
- upstream(上游跟踪):本地分支与远程分支的"配对关系"。用
git push -u origin main 建立,显示为 git branch -vv 里的 [origin/main]。它决定了 git status 显示领先/落后、git pull/git push 不带参数时的默认去向。
[origin/master: gone] 是什么:本地分支配置的上游指向 origin/master,但该远程分支在远程已不存在(被删除或改名),git 就标记为 gone(上游已消失)。
常见疑惑
| # 远程分支删了,本地为什么还显示?
# → 本地缓存没清理,需要 prune
git fetch --prune origin
# 查看本地分支的上游跟踪关系
git branch -vv
# 手动设置/取消上游跟踪
git branch --set-upstream-to=origin/main main # 设置
git branch --unset-upstream # 取消
|
十七、master 改名为 main 完整安全流程
背景:远程仓库默认分支原为 master,需要统一改名为 main。此流程保证不丢提交、不破坏他人协作。
完整命令清单
| # ① 确认工作区干净(有未提交改动先 commit 或 stash)
git status
# ② 重命名本地分支
git branch -m master main
# ③ 推送新分支并设置上游(-u 是关键!)
git push -u origin main
# ④ 【网页操作】GitHub: Settings → Branches → 默认分支改为 main
# 必须先做这步,否则第 ⑤ 步会被 GitHub 拒绝
# ⑤ 删除远程旧分支(必须在第 ④ 步之后)
git push origin --delete master
# ⑥ 清理本地过期引用 + 验证
git fetch --prune origin
git branch -vv
git status
|
三个核心坑(务必记住)
| 坑 |
后果 |
解法 |
第 ③ 步漏掉 -u |
本地分支上游仍指向旧的 origin/master,远程旧分支删除后报 upstream is gone |
推送必须带 -u,或事后 git branch --set-upstream-to=origin/main main |
| 第 ④ 步和第 ⑤ 步顺序颠倒 |
GitHub 禁止删除当前默认分支,第 ⑤ 步直接报错 |
先改默认分支,再删旧分支 |
| 未确认内容同步就删远程旧分支 |
若远程 master 与 main 有分叉(别人推过提交),直接丢提交 |
删除前检查 git log origin/master..origin/main 有无丢失提交 |
为什么改分支名推送后会出现 "upstream is gone"?
完整因果链:
- 最初本地与远程都是
master,本地 master 的上游是 origin/master;
git branch -m master main 只改分支名,不更新上游配置(branch.main.merge 仍指向 refs/heads/master);
- 推送时若不带
-u,上游跟踪也不会被更新;
- 远程
master 分支被删除后,本地缓存的 origin/master 消失,git 检测到"配置的上游分支不存在" → 报 upstream is gone。
一句话:upstream 是"名字"不是"地址"。改分支名后必须重新告诉 Git 跟踪谁。
协作者需要做的同步
| # 其他协作者拉取改名后的仓库:
git fetch --prune origin # 清理本地残留的 origin/master
git branch -u origin/main main # 修正本地 main 的上游跟踪
|
快速参考:常用命令速记表
| 操作 |
命令 |
| 查看状态 |
git status |
| 添加文件 |
git add . |
| 提交 |
git commit -m "消息" |
| 推送 |
git push |
| 拉取 |
git pull |
| 创建分支 |
git checkout -b 分支名 |
| 切换分支 |
git switch 分支名 |
| 合并分支 |
git merge 分支名 |
| 查看日志 |
git log --oneline |
| 撤销修改 |
git restore 文件名 |
| 暂存工作区 |
git stash |
| 恢复暂存 |
git stash pop |
| 撤回提交 |
git reset --soft HEAD~1 |
| 查看差异 |
git diff |
| 克隆仓库 |
git clone 地址 |