跳转至

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

别名配置

1
2
3
4
5
6
7
8
# 设置常用别名
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

换行符配置

1
2
3
4
5
6
7
8
# Windows 推荐:提交时转 LF,检出时转 CRLF
git config --global core.autocrlf true

# macOS/Linux 推荐:提交时转 LF,检出时不转换
git config --global core.autocrlf input

# 仅关闭警告
git config --global core.safecrlf false

二、仓库初始化与克隆

初始化新仓库

1
2
3
4
5
# 在当前目录初始化 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

三、基本操作

文件状态

1
2
3
4
5
6
7
8
9
# 查看文件状态
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,代表改动模块/范围,可选 例子:
1
2
3
4
5
feat(login): 添加短信登录功能
fix(order): 修复订单金额计算错误
docs: 更新部署文档
refactor(api): 重构请求封装
chore: 更新package依赖版本

完整提交消息示例

1
2
3
4
5
6
7
8
9
feat(home): 首页新增轮播图
fix: 修复点击按钮无响应问题
refactor(user): 拆分用户工具函数
perf(list): 优化列表渲染速度
test: 增加购物车单元测试
chore: 升级vue版本
docs: 修改接口文档
style: 格式化多余空行
revert: 回滚"新增支付功能"提交

提交命令例子

1
2
3
git commit -m "docs(README): 补充项目安装步骤与环境要求" -m "- 新增 Windows/Linux 双平台的依赖安装命令
- 补充 Node.js 版本要求(>= 18)及环境变量配置说明
- 修正原有快速开始章节中过期的脚本命令"

说明:

  • 多个 -m 参数会自动用空行拼接,第一个是标题,第二个是正文。
  • 正文里的换行直接在引号内换行即可,不需要额外转义。

如果是小改动只写标题:

git commit -m "docs(README): 修正安装命令中的拼写错误"

完整流程一般是:

1
2
3
4
5
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/远程分支名

合并分支

1
2
3
4
5
6
7
8
# 将指定分支合并到当前分支
git merge 分支名

# 合并时创建合并提交(即使可以快进)
git merge --no-ff 分支名

# 压缩合并(合并为一个提交)
git merge --squash 分支名

删除分支

1
2
3
4
5
6
7
8
# 删除本地分支(已合并)
git branch -d 分支名

# 强制删除本地分支(未合并也能删)
git branch -D 分支名

# 删除远程分支
git push origin --delete 分支名

重命名分支

1
2
3
4
5
# 重命名当前分支
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="关键词"

查看具体提交

1
2
3
4
5
6
7
8
# 查看某个提交的详细信息
git show 提交Hash

# 查看某个提交修改了哪些文件
git show --stat 提交Hash

# 查看某个文件在某次提交中的内容
git show 提交Hash:文件路径

七、撤销与恢复

工作区撤销

# 撤销工作区的修改(用暂存区覆盖工作区)
git checkout -- 文件名.md
# 或
git restore 文件名.md

# 撤销所有未暂存的修改
git restore .

# 从指定提交恢复文件到工作区
git restore --source=提交Hash 文件名.md

暂存区撤销

1
2
3
4
# 从暂存区移除文件(保留工作区修改)
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        # 退出二分查找

清理

1
2
3
4
5
# 清理未跟踪的文件和目录
git clean -fd

# 预览要清理的文件
git clean -n

归档

1
2
3
4
5
# 将当前分支打包为 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

场景三:挽救误操作

1
2
3
4
5
6
7
8
9
# 删错了文件,还没提交
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.mdREADME.md),Git 可能检测不到变化

1
2
3
# Windows 上执行,Git 可能认为没有变化
git mv Readme.md README.md
git status  # 没有输出,Git 认为文件没变

原因

  • Windows 文件系统(NTFS):大小写不敏感File.mdfile.md 被视为同一个文件
  • macOS(APFS):默认也大小写不敏感(但可以格式化时选择敏感)
  • Linux(ext4/XFS):大小写敏感File.mdfile.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.mdfile.md,需通过临时名过渡:

1
2
3
4
5
6
7
8
# 第一步:改成一个完全不同的临时名
git mv "File.md" "file_temp.md"

# 第二步:再改回目标小写名
git mv "file_temp.md" "file.md"

# 提交
git commit -m "refactor: 统一文件名大小写"

方法二:强制 Git 检测大小写

1
2
3
4
5
6
# 临时让 Git 检测大小写变化
git config core.ignorecase false

# 重命名后提交
git mv Readme.md README.md
git commit -m "fix: 修正文件名大小写"

方法三:直接修改 Git 索引

1
2
3
4
5
6
7
8
# 删除旧的小写记录
git rm --cached "docs/file.md"

# 添加正确大小写的新文件
git add "docs/File.md"

# 提交
git commit -m "fix: 修正文件名大小写"

最佳实践

  1. 文件名统一使用全小写,避免大小写带来的跨平台问题
  2. 英文字母部分全小写,中文部分保持不变(如 git命令大全.md
  3. 新增文件时,mkdocs.yml 中的引用路径必须与实际文件名完全一致
  4. 提交前执行 mkdocs build --clean 验证,确保无死链

十六、远程跟踪分支与 origin/HEAD 详解

三个层级的概念

git branch -a 的输出为例:

1
2
3
* 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

关键理解点

  1. origin/main 不是实时的。它只在 git fetch / git pull / git clone 时更新,是"上次从远程拉取时的样子"。远程有人推送了新提交,在你不 fetch 之前,本地缓存的 origin/main 不会变。
  2. origin/HEAD → origin/main 的含义:表示远程仓库的默认分支是 main。clone 仓库时,Git 靠它决定默认检出哪个分支。箭头右边是它实际指向的目标。
  3. upstream(上游跟踪):本地分支与远程分支的"配对关系"。用 git push -u origin main 建立,显示为 git branch -vv 里的 [origin/main]。它决定了 git status 显示领先/落后、git pull/git push 不带参数时的默认去向。
  4. [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 禁止删除当前默认分支,第 ⑤ 步直接报错 先改默认分支,再删旧分支
未确认内容同步就删远程旧分支 若远程 mastermain 有分叉(别人推过提交),直接丢提交 删除前检查 git log origin/master..origin/main 有无丢失提交

为什么改分支名推送后会出现 "upstream is gone"?

完整因果链:

  1. 最初本地与远程都是 master,本地 master 的上游是 origin/master
  2. git branch -m master main 只改分支名,不更新上游配置branch.main.merge 仍指向 refs/heads/master);
  3. 推送时若不带 -u,上游跟踪也不会被更新;
  4. 远程 master 分支被删除后,本地缓存的 origin/master 消失,git 检测到"配置的上游分支不存在" → 报 upstream is gone

一句话:upstream 是"名字"不是"地址"。改分支名后必须重新告诉 Git 跟踪谁。

协作者需要做的同步

1
2
3
# 其他协作者拉取改名后的仓库:
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 地址