云计算百科
云计算领域专业知识百科平台

Git 操作大全

Git 操作大全

本文档涵盖 Git 从入门到高级的完整操作指南


一、基础配置

1.1 用户信息配置

# 设置全局用户名(所有仓库生效)
git config –global user.name "Your Name"

# 设置全局邮箱
git config –global user.email "your.email@example.com"

# 仅对当前仓库设置用户名(覆盖全局配置)
git config user.name "Project Specific Name"

# 仅对当前仓库设置邮箱
git config user.email "project@example.com"

1.2 编辑器配置

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

# 设置默认编辑器为 Vim
git config –global core.editor "vim"

# 设置默认编辑器为 Nano
git config –global core.editor "nano"

# Windows 记事本
git config –global core.editor "notepad"

1.3 差异比较工具配置

# 设置 diff 工具为 VS Code
git config –global diff.tool vscode
git config –global difftool.vscode.cmd 'code –wait –diff $LOCAL $REMOTE'

# 设置 merge 工具为 VS Code
git config –global merge.tool vscode
git config –global mergetool.vscode.cmd 'code –wait $MERGED'

1.4 其他常用配置

# 设置默认分支名(新建仓库时使用)
git config –global init.defaultBranch main

# 开启颜色输出
git config –global color.ui auto

# 设置换行符处理(Windows 用户推荐)
git config –global core.autocrlf true # 提交时转 LF,检出时转 CRLF
# Linux/Mac 用户推荐
git config –global core.autocrlf input # 提交时转 LF,检出时不转换

# 设置凭证缓存时间(秒)
git config –global credential.helper cache –timeout=3600

# Windows 使用 Git Credential Manager
git config –global credential.helper manager

# 查看所有全局配置
git config –global –list

# 查看所有配置(包括系统、全局、本地)
git config –list

# 查看某个具体配置
git config user.name

# 删除某个配置项
git config –global –unset user.name

1.5 配置文件层级

# Git 有三个层级的配置文件,优先级从高到低:
# 1. 本地配置(.git/config) -> –local 仅对当前仓库生效
# 2. 全局配置(~/.gitconfig) -> –global 对当前用户所有仓库生效
# 3. 系统配置(/etc/gitconfig) -> –system 对所有用户生效

# 编辑配置文件
git config –global -e # 用编辑器打开全局配置文件
git config –local -e # 用编辑器打开本地配置文件


二、仓库初始化与克隆

2.1 初始化新仓库

# 在当前目录初始化一个新的 Git 仓库
git init

# 初始化并指定目录名
git init my-project

# 初始化一个裸仓库(通常用于服务器端)
git init –bare my-project.git

# 使用默认分支名初始化(Git 2.28+)
git init -b main my-project

2.2 克隆远程仓库

# 克隆仓库(默认使用 HTTPS)
git clone https://github.com/user/repo.git

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

# 使用 SSH 克隆(推荐,需配置 SSH Key)
git clone git@github.com:user/repo.git

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

# 浅克隆(只克隆最近 N 次提交,节省时间和空间)
git clone –depth 1 https://github.com/user/repo.git # 只克隆最近 1 次
git clone –depth 10 https://github.com/user/repo.git # 克隆最近 10 次

# 克隆特定分支的浅克隆
git clone –depth 1 -b main https://github.com/user/repo.git

# 递归克隆(包含子模块)
git clone –recursive https://github.com/user/repo.git

# 克隆后补充克隆子模块
git clone https://github.com/user/repo.git
cd repo
git submodule update –init –recursive

# 稀疏克隆(只克隆仓库的部分目录)
git clone –filter=blob:none –sparse https://github.com/user/repo.git
cd repo
git sparse-checkout set src/ docs/ # 只检出 src 和 docs 目录


三、基本工作流

3.1 Git 三个区域

工作区(Working Directory) –> 暂存区(Staging Area/Index) –> 本地仓库(Repository)
修改文件 git add git commit

3.2 查看状态

# 查看工作区和暂存区的状态
git status

# 简洁模式显示状态
git status -s
# 输出说明:
# M 文件名 → 已修改且已暂存
# M 文件名 → 已修改但未暂存
# A 文件名 → 新添加到暂存区的文件
# D 文件名 → 已删除的文件
# R 文件名 → 重命名的文件
# ?? 文件名 → 未跟踪的新文件
# MM 文件名 → 已修改并暂存后又在工作区再次修改

# 查看简短状态(分支信息 + 简洁文件状态)
git status -sb

3.3 添加到暂存区

# 添加单个文件
git add filename.txt

# 添加多个文件
git add file1.txt file2.txt file3.txt

# 添加当前目录下的所有修改(新增 + 修改 + 删除)
git add .

# 添加所有 .py 文件
git add *.py

# 添加 src 目录下所有文件
git add src/

# 交互式添加(可以选择要暂存的文件部分修改)
git add -p
# 交互式选项说明:
# y – 暂存这个区块
# n – 不暂存这个区块
# s – 将当前区块拆分为更小的区块
# e – 手动编辑当前区块
# q – 退出

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

# 强制添加被 .gitignore 忽略的文件
git add -f filename.txt

3.4 提交

# 提交暂存区的所有文件,打开编辑器写提交信息
git commit

# 使用 -m 直接写提交信息
git commit -m "feat: 添加用户登录功能"

# 添加所有已跟踪文件的修改并提交(跳过 git add 步骤)
git commit -am "fix: 修复登录验证 bug"

# 修改最近一次提交的信息
git commit –amend

# 修改最近一次提交的内容(保持提交信息不变)
git add forgotten-file.txt
git commit –amend –no-edit

# 创建空提交(常用于触发 CI)
git commit –allow-empty -m "chore: 触发构建"

# 使用模板文件作为提交信息
git commit -t .git/commit-template.txt

# 签名提交(GPG 签名)
git commit -S -m "feat: 安全的提交"

3.5 提交信息规范(Conventional Commits)

完整格式

<type>(<scope>): <subject>
<body>

# – type: 提交类型,必填,见下方类型表
# – scope: 影响范围,可选,用小括号包裹
# – subject: 简述,必填,祈使句,首字母小写,结尾不加句号
# – 总长度不超过 50 个字符

type 类型表
类型说明示例
feat 新功能 feat(auth): 添加微信登录
fix 修复 bug fix(api): 修复空指针异常
docs 文档变更 docs(readme): 更新安装说明
style 代码格式(不影响功能) style: 统一缩进为 4 空格
refactor 重构(不新增功能/修复 bug) refactor(db): 拆分查询逻辑
perf 性能优化 perf(query): 添加索引加速查询
test 测试相关 test(auth): 添加登录单元测试
chore 构建/工具变动 chore: 升级 webpack 到 v5
ci CI/CD 配置 ci: 添加 GitHub Actions 工作流
build 构建系统或外部依赖 build: 迁移到 pnpm
revert 回退提交 revert: 回退 feat(auth)
WIP 工作进行中(不推荐推送到主分支) WIP: 登录功能开发中
完整示例

feat(auth): 添加微信 OAuth2.0 登录功能

实现了微信扫码登录的完整流程:
– 前端添加微信登录按钮和二维码弹窗
– 后端新增 /api/auth/wechat 回调接口
– 集成 wechat-sdk 处理 token 交换
– 用户首次登录自动创建账号并绑定手机号

性能方面:
– 缓存 access_token,避免重复请求微信接口
– 使用 Redis 存储会话状态,有效期 5 分钟

Closes #123
Closes #456
Co-authored-by: zhangsan <zhangsan@example.com>

fix(order): 修复订单金额计算精度丢失问题

使用 Decimal 替代 float 进行金额运算,解决浮点数精度问题。

修改前:0.1 + 0.2 = 0.30000000000000004
修改后:0.1 + 0.2 = 0.3

受影响模块:订单创建、退款、对账

Fixes #789

refactor(user): 重构用户权限校验逻辑

将散布在各 Controller 中的权限校验代码统一抽取到
@RequirePermission 注解中,通过 AOP 拦截器实现。

变更内容:
– 新增 @RequirePermission 注解
– 新增 PermissionAspect 切面
– 移除各 Controller 中重复的校验代码
– 更新相关单元测试

BREAKING CHANGE: 移除了旧的 checkPermission() 方法,
所有直接调用该方法的地方需要改为使用注解方式。

Closes #321

chore(deps): 升级 Spring Boot 到 3.2.0

升级相关依赖版本:
– Spring Boot: 2.7.18 -> 3.2.0
– Spring Security: 5.8.x -> 6.2.x
– Jakarta EE: javax.* -> jakarta.*

已通过全量回归测试,无兼容性问题。

Refs: https://spring.io/blog/2023/11/23/spring-boot-3-2-0

docs(api): 更新 REST API 文档

– 新增用户管理接口文档(/api/users)
– 更新订单接口的请求参数说明
– 补充错误码列表
– 添加 curl 调用示例

fix: 修复登录页面样式错位

调整移动端下登录表单的布局,修复小屏幕适配问题。

Before: ![before](screenshots/login-before.png)
After: ![after](screenshots/login-after.png)

Fixes #666

常见错误写法 vs 正确写法

# ❌ 错误写法
git commit -m "fix bug" # 太模糊
git commit -m "update" # 无意义
git commit -m "修改了登录功能" # 中文,未使用规范格式
git commit -m "feat: 添加登录功能。" # 结尾多了句号
git commit -m "Feat: add login" # type 首字母大写
git commit -m "FEAT(auth): ADD LOGIN" # 全大写
git commit -m "feat(auth): 添加登录功能 修复bug" # 混合了两个 type

# ✅ 正确写法
git commit -m "feat(auth): 添加微信登录功能"
git commit -m "fix(auth): 修复登录验证空指针异常"
git commit -m "style: 统一代码缩进为 4 空格"
git commit -m "docs(readme): 更新部署文档"
git commit -m "refactor(auth): 抽取权限校验到 AOP 切面"


四、分支管理

4.1 查看分支

# 查看本地分支
git branch

# 查看所有分支(本地 + 远程)
git branch -a

# 查看远程分支
git branch -r

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

# 查看本地分支及其与远程分支的对应关系
git branch -vv

# 查看已合并到当前分支的分支
git branch –merged

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

4.2 创建分支

# 创建新分支(但不切换到新分支)
git branch feature/login

# 基于指定提交创建分支
git branch feature/login abc1234

# 基于远程分支创建本地分支
git branch feature/login origin/feature/login

# 创建孤儿分支(没有历史的空分支,常用于 gh-pages)
git branch –orphan gh-pages

4.3 切换分支

# 切换到已有分支
git checkout develop

# 创建并切换到新分支(常用)
git checkout -b feature/login

# 基于远程分支创建并切换
git checkout -b feature/login origin/feature/login

# 切换到上一个分支(快速切换)
git checkout –

# 新命令(Git 2.23+):切换分支
git switch main

# 新命令:创建并切换到新分支
git switch -c feature/login

# 新命令:切换到上一个分支
git switch –

4.4 重命名分支

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

# 重命名指定分支
git branch -m old-name new-name

# 强制重命名(目标分支已存在时)
git branch -M new-name

4.5 删除分支

# 删除已合并的本地分支
git branch -d feature/login

# 强制删除本地分支(未合并也删除)
git branch -D feature/login

# 删除远程分支
git push origin –delete feature/login

# 另一种删除远程分支的写法
git push origin :feature/login

# 批量删除已合并的本地分支(保留 main 和当前分支)
git branch –merged | grep -v "main" | grep -v "^\\*" | xargs git branch -d

4.6 分支工作流示例

# === 功能开发流程 ===

# 1. 从 main 创建功能分支
git checkout main
git pull origin main
git checkout -b feature/user-profile

# 2. 在功能分支上开发并提交
git add .
git commit -m "feat(profile): 添加用户资料页面"

# 3. 推送功能分支到远程
git push origin feature/user-profile

# 4. 创建 Pull Request / Merge Request

# 5. 合并后清理分支
git checkout main
git pull origin main
git branch -d feature/user-profile
git push origin –delete feature/user-profile


五、查看历史与状态

5.1 查看提交历史

# 查看完整提交历史
git log

# 简洁模式(一行显示)
git log –oneline

# 图形化显示分支合并历史
git log –graph –oneline –all

# 带颜色的图形化显示
git log –graph –pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' –abbrev-commit

# 查看最近 N 次提交
git log -5

# 查看某个文件的修改历史
git log filename.txt

# 查看某个文件的修改历史,显示每次修改的具体内容
git log -p filename.txt

# 查看某个目录的修改历史
git log src/

# 搜索提交信息
git log –grep="登录"

# 搜索引入了特定内容的提交(搜索代码变更)
git log -S "function_name" # 查找添加或删除了 "function_name" 的提交

# 使用正则搜索代码变更
git log -G "regex_pattern"

# 查看某个作者的提交
git log –author="John"

# 查看指定日期之后的提交
git log –since="2024-01-01"

# 查看指定日期之前的提交
git log –until="2024-12-31"

# 查看指定日期范围内的提交
git log –since="2024-01-01" –until="2024-06-30"

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

# 查看不在 feature/login 中但在 main 中的提交
git log feature/login..main

# 显示每次提交的统计信息(修改了哪些文件,各修改了多少行)
git log –stat

# 显示每次提交的简要统计
git log –shortstat

# 只显示合并提交
git log –merges

# 不显示合并提交
git log –no-merges

5.2 查看差异

# 查看工作区与暂存区的差异(未 add 的修改)
git diff

# 查看暂存区与上次提交的差异(已 add 但未 commit 的修改)
git diff –staged
git diff –cached # 同上,两种写法都可以

# 查看工作区与上次提交的差异(所有修改)
git diff HEAD

# 比较两个分支
git diff main..feature/login

# 比较两个分支,只显示文件名
git diff main..feature/login –name-only

# 比较两个分支,显示文件名和状态(增删改)
git diff main..feature/login –name-status

# 比较两个分支,显示统计信息
git diff main..feature/login –stat

# 查看某个文件在工作区与暂存区的差异
git diff filename.txt

# 查看某个文件在暂存区与上次提交的差异
git diff –staged filename.txt

# 比较两个提交之间的差异
git diff abc1234 def5678

# 比较两个提交,只显示文件名
git diff abc1234 def5678 –name-only

# 查看某个文件在两个提交之间的差异
git diff abc1234 def5678 — filename.txt

# 比较两个标签
git diff v1.0.0 v2.0.0

# 忽略空白字符差异
git diff -w
git diff –ignore-all-space

# 只显示修改的文件名(不看具体差异)
git diff –name-only
git diff –name-status # 显示状态字母 A(新增) M(修改) D(删除)

5.3 查看具体提交

# 查看某个提交的详细信息
git show abc1234

# 查看某个提交的修改内容
git show abc1234 –stat # 显示修改统计
git show abc1234 — filename.txt # 只看某个文件的修改

# 查看最新提交
git show HEAD

# 查看上一次提交
git show HEAD~1

# 查看 HEAD 前 N 次提交
git show HEAD~N

# 只看某个提交的提交信息
git log -1 –format="%B" abc1234

# 查看某个提交中的某个文件内容
git show abc1234:src/main.py

5.4 搜索代码

# 在所有已跟踪文件中搜索文本
git grep "search_term"

# 搜索并显示行号
git grep -n "search_term"

# 不区分大小写搜索
git grep -i "search_term"

# 搜索并显示上下文
git grep -C 3 "search_term" # 前后各 3 行

# 在特定版本中搜索
git grep "search_term" abc1234

# 在所有提交中搜索(bisect 的替代方案)
git log -S "search_term" –oneline

# 使用正则表达式搜索
git grep -E "regex_pattern"

5.5 文件追溯(Blame)

# 查看文件每一行最后修改的提交和作者
git blame filename.txt

# 查看文件特定行范围的修改历史
git blame -L 10,20 filename.txt # 第 10 到 20 行

# 查看文件特定行开始的 N 行
git blame -L 10,+5 filename.txt # 从第 10 行开始的 5 行

# 忽略空白字符修改
git blame -w filename.txt

# 显示完整的提交哈希
git blame –abbrev=40 filename.txt

# 追溯某个特定提交时的文件内容
git blame abc1234 — filename.txt


六、撤销与回退

6.1 撤销工作区修改

# 撤销单个文件的修改(恢复到暂存区或上次提交的状态)
git checkout — filename.txt

# 新命令(Git 2.23+)
git restore filename.txt

# 撤销所有工作区修改
git checkout — .

# 新命令
git restore .

# 撤销工作区对某文件的修改,恢复到指定提交的状态
git checkout abc1234 — filename.txt

6.2 撤销暂存(unstage)

# 将文件从暂存区移回工作区
git reset HEAD filename.txt

# 新命令(Git 2.23+)
git restore –staged filename.txt

# 撤销所有暂存
git reset HEAD

# 新命令
git restore –staged .

6.3 回退提交

# 回退到某个提交,保留修改在工作区(软回退)
git reset –soft HEAD~1

# 回退到某个提交,保留修改在暂存区(混合回退,默认模式)
git reset HEAD~1
git reset –mixed HEAD~1

# 回退到某个提交,丢弃所有修改(硬回退,危险!)
git reset –hard HEAD~1

# 回退到某个指定提交
git reset –hard abc1234

# === 区别说明 ===
# –soft: 回退提交,保留暂存区和工作区的修改
# –mixed: 回退提交和暂存区,保留工作区的修改(默认)
# –hard: 回退提交、暂存区和工作区,所有修改全部丢失

6.4 反转提交(安全的撤销方式)

# 创建一个新提交来撤销指定提交的修改(推荐用于已推送的提交)
git revert abc1234

# 反转提交但不自动提交(可以继续修改后再提交)
git revert –no-commit abc1234

# 反转最近 3 次提交
git revert HEAD~2..HEAD

# 反转合并提交(需要指定保留哪个父提交)
git revert -m 1 <merge-commit-hash>
# -m 1 表示保留第一个父提交(通常是主分支)的内容

6.5 恢复已删除的内容

# 恢复已删除的文件
git checkout HEAD — filename.txt

# 如果文件已经被提交删除了,从历史中恢复
git log –diff-filter=D –summary # 找到删除文件的提交
git checkout abc1234~1 — filename.txt # 从删除前的提交恢复

# 恢复到指定提交的完整状态(创建新提交)
git revert HEAD

# 使用 reflog 找到丢失的提交
git reflog
# 找到丢失提交的哈希后
git checkout abc1234
# 或创建新分支指向它
git branch recover-branch abc1234

6.6 暂存工作区(带冲突时的处理)

# 当需要回退但有冲突时
git stash # 先暂存当前修改
git reset –hard HEAD~1 # 回退提交
git stash pop # 恢复暂存的修改
# 如果 pop 时有冲突,手动解决后
git add .
git stash drop # 删除已应用的 stash


七、远程仓库操作

7.1 查看远程仓库

# 查看远程仓库列表
git remote

# 查看远程仓库详细信息(URL 和跟踪信息)
git remote -v

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

7.2 添加远程仓库

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

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

# 使用 SSH 添加
git remote add origin git@github.com:user/repo.git

7.3 修改远程仓库

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

# 修改远程仓库 URL 为 SSH
git remote set-url origin git@github.com:user/repo.git

# 重命名远程仓库
git remote rename origin upstream

# 删除远程仓库引用
git remote remove upstream

7.4 推送

# 推送到远程仓库(首次推送并设置上游分支)
git push -u origin main

# 推送到远程仓库(已设置上游分支后)
git push

# 推送指定分支
git push origin feature/login

# 推送所有本地分支
git push –all origin

# 推送标签
git push origin v1.0.0

# 推送所有标签
git push origin –tags

# 强制推送(危险!会覆盖远程历史)
git push –force origin main
git push -f origin main

# 安全的强制推送(如果远程分支有新提交会拒绝)
git push –force-with-lease origin main

# 删除远程分支
git push origin –delete feature/login

# 推送并设置上游分支
git push -u origin feature/login

7.5 拉取与获取

# 获取远程更新(不合并)
git fetch origin

# 获取所有远程仓库的更新
git fetch –all

# 获取远程分支并创建对应的本地分支
git fetch origin feature/login:feature/login

# 拉取远程更新并合并(= fetch + merge)
git pull origin main

# 拉取并变基(= fetch + rebase)
git pull –rebase origin main

# 设置默认拉取行为为变基
git config –global pull.rebase true

# 拉取并自动储藏本地修改
git pull –autostash

# 获取并修剪已删除的远程分支引用
git fetch –prune
git fetch -p # 简写

7.6 跟踪远程分支

# 查看本地分支跟踪的远程分支
git branch -vv

# 设置本地分支跟踪远程分支
git branch –set-upstream-to=origin/main main

# 简写
git branch -u origin/main main

# 取消跟踪
git branch –unset-upstream

# 创建本地分支并跟踪远程分支
git checkout –track origin/feature/login
# 等同于
git checkout -b feature/login origin/feature/login

7.7 多远程仓库操作

# 典型场景:fork 后同步上游仓库

# 1. 添加上游仓库
git remote add upstream https://github.com/original/repo.git

# 2. 获取上游更新
git fetch upstream

# 3. 合并上游的 main 分支
git checkout main
git merge upstream/main

# 4. 推送到自己的 fork
git push origin main

# 查看所有远程仓库
git remote -v

# 从指定远程仓库拉取
git pull upstream main


八、标签管理

8.1 查看标签

# 查看所有标签
git tag

# 搜索特定模式的标签
git tag -l "v1.*"

# 查看标签及其提交信息
git tag -n

# 查看标签详情(指向的提交、创建时间等)
git show v1.0.0

8.2 创建标签

# 创建轻量标签(lightweight tag,只是一个指针)
git tag v1.0.0

# 创建附注标签(annotated tag,包含标签信息,推荐)
git tag -a v1.0.0 -m "版本 1.0.0 发布"

# 对指定提交打标签
git tag -a v1.0.0 abc1234 -m "版本 1.0.0"

# 对上一个提交打标签
git tag -a v1.0.0 HEAD~1 -m "版本 1.0.0"

# 创建签名标签(GPG 签名)
git tag -s v1.0.0 -m "签名的标签"

8.3 操作标签

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

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

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

# 推送所有本地标签到远程
git push origin –tags

# 重命名标签(先删除后创建)
git tag -d v1.0.0
git tag -a v1.0.1 -m "原来叫 v1.0.0,已重命名"
git push origin v1.0.1

# 检出标签(进入 detached HEAD 状态)
git checkout v1.0.0

# 基于标签创建分支
git checkout -b hotfix/v1.0.1 v1.0.0


九、储藏(Stash)

9.1 基本储藏操作

# 储藏当前修改(已跟踪文件)
git stash

# 储藏并添加描述信息
git stash push -m "正在开发的功能,需要临时切换分支"

# 储藏包括未跟踪的新文件
git stash -u
git stash –include-untracked

# 储藏包括忽略的文件
git stash -a
git stash –all

# 只储藏指定文件
git stash push -m "只储藏这个文件" — filename.txt

# 只储藏指定目录的文件
git stash push -m "只储藏 src 目录" — src/

# 交互式选择要储藏的内容
git stash push -p

9.2 查看储藏

# 查看储藏列表
git stash list

# 查看储藏的修改内容
git stash show # 最新储藏的统计
git stash show -p # 最新储藏的完整差异
git stash show stash@{0} # 指定储藏的统计
git stash show -p stash@{2} # 指定储藏的完整差异

# 查看储藏的内容概要
git stash list –stat

9.3 恢复储藏

# 恢复最新储藏并删除(应用并移除)
git stash pop

# 恢复指定储藏并删除
git stash pop stash@{2}

# 恢复最新储藏但不删除(可以多次应用)
git stash apply

# 恢复指定储藏但不删除
git stash apply stash@{2}

# 从储藏创建新分支
git stash branch new-branch-name

# 从指定储藏创建新分支
git stash branch new-branch-name stash@{2}

9.4 删除储藏

# 删除最新储藏
git stash drop

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

# 清除所有储藏
git stash clear

9.5 储藏使用场景

# 场景:正在开发 feature,突然需要修 bug

# 1. 储藏当前工作
git stash push -m "feature: 用户头像上传功能开发中"

# 2. 切换到 bugfix 分支
git checkout -b hotfix/login-bug main

# 3. 修复 bug 并提交
git add .
git commit -m "fix: 修复登录验证漏洞"

# 4. 切换回 feature 分支
git checkout feature/user-avatar

# 5. 恢复之前的工作
git stash pop


十、合并与变基

10.1 合并(Merge)

# 将指定分支合并到当前分支
git merge feature/login

# 合并并创建合并提交(即使可以快进合并)
git merge –no-ff feature/login

# 只允许快进合并(如果不能快进则失败)
git merge –ff-only feature/login

# 合并但不自动提交(可以继续修改后再提交)
git merge –no-commit feature/login

# 合并后放弃合并
git merge –abort

# 压缩合并(将指定分支的所有提交压缩为一个提交)
git merge –squash feature/login
git commit -m "feat: 添加登录功能(压缩合并)"

10.2 变基(Rebase)

# 将当前分支变基到指定分支(将当前分支的提交"移动"到指定分支之后)
git rebase main

# 变基到指定提交
git rebase abc1234

# 交互式变基(修改、合并、重新排序提交)
git rebase -i HEAD~3 # 对最近 3 次提交进行交互式变基

# 交互式变基的选项说明:
# pick – 使用该提交
# reword – 使用该提交,但修改提交信息
# edit – 使用该提交,但暂停以便修改
# squash – 使用该提交,但合并到前一个提交
# fixup – 同 squash,但丢弃该提交的信息
# drop – 删除该提交

# 变基过程中遇到冲突时
git rebase –continue # 解决冲突后继续变基
git rebase –skip # 跳过当前冲突的提交
git rebase –abort # 放弃变基,回到变基前的状态

# 变基到指定分支的特定提交
git rebase –onto main abc1234 feature/login
# 将 feature/login 中 abc1234 之后的提交变基到 main 上

10.3 合并 vs 变基

# 合并(Merge):
# – 保留完整的分支历史
# – 创建合并提交
# – 历史图有分叉
# – 安全,不修改已有提交
# – 适合多人协作的公共分支

# 变基(Rebase):
# – 创建线性历史,更整洁
# – 不创建合并提交
# – "移动"提交到目标分支之后
# – 修改提交哈希(实际上是创建新提交)
# – 适合个人功能分支,保持历史清晰
# – 注意:不要对已推送到远程的公共分支进行变基!

10.4 合并与变基的推荐工作流

# 方式一:功能分支使用变基保持最新
git checkout feature/login
git rebase main # 将功能分支变基到最新的 main
git checkout main
git merge –no-ff feature/login # 合并功能分支到 main

# 方式二:使用 –no-ff 合并(保留分支信息)
git checkout main
git merge –no-ff feature/login
# 这会创建一个合并提交,保留功能分支的完整历史


十一、冲突解决

11.1 冲突标记说明

<<<<<<< HEAD
这里是当前分支的内容
=======
这里是被合并分支的内容
>>>>>>> feature/login

# 说明:
# <<<<<<< HEAD 到 ======= 之间是当前分支的内容
# ======= 到 >>>>>>> feature/login 之间是被合并分支的内容

11.2 解决冲突

# 1. 合并或变基时遇到冲突
git merge feature/login
# 输出:CONFLICT (content): Merge conflict in filename.txt

# 2. 查看冲突文件
git status # 会显示 "both modified: filename.txt"

# 3. 手动编辑冲突文件,删除冲突标记,保留正确内容

# 4. 使用工具解决冲突
git mergetool

# 5. 标记冲突已解决
git add filename.txt

# 6. 继续合并或变基
git commit # 合并时
git rebase –continue # 变基时

# 或者放弃合并/变基
git merge –abort # 放弃合并
git rebase –abort # 放弃变基

11.3 冲突解决策略

# 使用当前分支的版本
git checkout –ours filename.txt

# 使用被合并分支的版本
git checkout –theirs filename.txt

# 使用当前分支的版本(变基时语义相反)
git checkout –ours filename.txt # 变基时:ours = 目标分支
git checkout –theirs filename.txt # 变基时:theirs = 当前分支

# 删除冲突文件
git rm filename.txt

# 标记为已解决(不修改文件,使用当前版本)
git add filename.txt


十二、Git 高级技巧

12.1 Cherry-pick(摘取提交)

# 将指定提交应用到当前分支
git cherry-pick abc1234

# 摘取多个提交
git cherry-pick abc1234 def5678

# 摘取一个范围的提交(不包含起始提交)
git cherry-pick abc1234..def5678

# 摘取一个范围的提交(包含起始提交)
git cherry-pick abc1234^..def5678

# 摘取但不自动提交
git cherry-pick –no-commit abc1234

# 摘取合并提交(需要指定保留哪个父提交)
git cherry-pick -m 1 <merge-commit-hash>

# 摘取遇到冲突时
git cherry-pick –continue # 解决冲突后继续
git cherry-pick –skip # 跳过当前提交
git cherry-pick –abort # 放弃整个操作

12.2 二分查找(Bisect)

# 开始二分查找(用于定位引入 bug 的提交)
git bisect start

# 标记当前版本为有 bug
git bisect bad

# 标记某个版本为无 bug
git bisect good v1.0.0

# Git 会自动 checkout 到中间的提交,你测试后继续标记
git bisect good # 当前版本没有 bug
git bisect bad # 当前版本有 bug

# 自动二分查找(使用脚本自动测试)
git bisect start HEAD v1.0.0
git bisect run ./test-script.sh
# 脚本返回 0 表示 good,非 0 表示 bad

# 结束二分查找
git bisect reset

# 查看当前二分查找状态
git bisect log

# 跳过某个无法测试的提交
git bisect skip

12.3 Reflog(引用日志)

# 查看所有操作历史(包括已删除的提交)
git reflog

# 查看指定引用的操作历史
git reflog show main

# 查看 HEAD 的操作历史
git reflog show HEAD

# 恢复已删除的提交
git reflog
# 找到目标提交的哈希
git checkout abc1234
# 或创建新分支
git branch recover abc1234

# 恢复已重置的分支
git reflog main
# 找到重置前的哈希
git reset –hard abc1234

12.4 重写历史

# 修改最近一次提交
git commit –amend

# 修改最近一次提交的信息
git commit –amend -m "新的提交信息"

# 交互式变基(重写最近 N 次提交)
git rebase -i HEAD~N

# 使用 filter-branch 重写所有提交的作者信息
git filter-branch –env-filter '
if [ "$GIT_AUTHOR_EMAIL" = "old@email.com" ]; then
export GIT_AUTHOR_EMAIL="new@email.com"
fi
'
–all

# 推荐使用 git-filter-repo(更安全、更快速)
# 安装: pip install git-filter-repo
git filter-repo –mailmap mailmap.txt

# 从所有提交中删除某个文件
git filter-branch –force –index-filter \\
'git rm –cached –ignore-unmatch path/to/file' \\
–prune-empty — –all

12.5 工作树(Worktree)

# 添加新工作树(可以在不切换分支的情况下同时在多个分支上工作)
git worktree add ../hotfix-branch hotfix/v1.0.1

# 添加新工作树并创建新分支
git worktree add -b new-feature ../feature-workspace

# 查看所有工作树
git worktree list

# 删除工作树
git worktree remove ../hotfix-branch

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

12.6 清理

# 预览将被删除的未跟踪文件
git clean -n

# 删除未跟踪的文件
git clean -f

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

# 删除未跟踪和被忽略的文件
git clean -fdx

# 交互式清理
git clean -i

12.7 归档

# 将仓库打包为 zip
git archive –format=zip HEAD > project.zip

# 将仓库打包为 tar.gz
git archive –format=tar.gz HEAD > project.tar.gz

# 只打包指定目录
git archive –format=zip HEAD src/ > src.zip

# 打包指定标签或分支
git archive –format=zip v1.0.0 > v1.0.0.zip


十三、Git 子模块

13.1 基本操作

# 添加子模块
git submodule add https://github.com/user/library.git libs/library

# 添加子模块到指定目录
git submodule add https://github.com/user/library.git path/to/library

# 添加指定分支的子模块
git submodule add -b main https://github.com/user/library.git libs/library

# 初始化子模块(克隆后首次使用)
git submodule init

# 更新子模块
git submodule update

# 初始化并更新子模块(常用)
git submodule update –init

# 递归初始化和更新所有子模块(包括嵌套子模块)
git submodule update –init –recursive

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

# 克隆后初始化子模块
git clone https://github.com/user/repo.git
cd repo
git submodule update –init –recursive

13.2 子模块管理

# 查看子模块状态
git submodule status

# 查看子模块的修改
git diff –submodule

# 进入子模块目录并切换到指定分支
cd libs/library
git checkout main

# 更新子模块到最新提交
git submodule update –remote

# 更新指定子模块
git submodule update –remote libs/library

# 对所有子模块执行命令
git submodule foreach 'git pull origin main'

# 对所有子模块执行复杂命令
git submodule foreach '
git checkout main
git pull origin main
'

# 删除子模块
git submodule deinit libs/library # 取消注册
git rm libs/library # 从 .gitmodules 和暂存区删除
rm -rf .git/modules/libs/library # 删除子模块的 git 数据

13.3 子模块配置文件

# .gitmodules 文件示例
[submodule "libs/library"]
path = libs/library # 子模块在主仓库中的路径
url = https://github.com/user/library.git # 子模块的远程地址
branch = main # 跟踪的分支(可选)


十四、Git Hooks(钩子)

14.1 钩子概述

# 钩子位于 .git/hooks/ 目录下
# 钩子是可执行的脚本文件,在特定 Git 操作时自动执行

# 查看所有可用钩子
ls .git/hooks/

14.2 常用钩子

# === 客户端钩子 ===

# pre-commit – 在执行 git commit 之前运行
# 用途:代码检查、格式化、测试等
# 返回非 0 值会取消提交

# prepare-commit-msg – 在打开编辑器之前运行
# 用途:自定义默认提交信息

# commit-msg – 在提交信息写入后运行
# 用途:验证提交信息格式

# pre-push – 在执行 git push 之前运行
# 用途:运行测试、检查代码等

# === 服务端钩子 ===

# pre-receive – 在处理推送之前运行
# update – 在每次推送的每个分支之前运行
# post-receive – 在推送处理完成后运行

14.3 钩子示例

# .git/hooks/pre-commit 示例(确保代码格式化)
#!/bin/sh
# 检查是否有未解决的冲突标记
if git diff –cached –name-only | xargs grep -l '<<<<<<' 2>/dev/null; then
echo "错误:发现冲突标记,请先解决冲突"
exit 1
fi

# 运行代码检查
npm run lint
if [ $? -ne 0 ]; then
echo "代码检查失败,请修复后重新提交"
exit 1
fi

exit 0

# .git/hooks/commit-msg 示例(验证提交信息格式)
#!/bin/sh
# 验证提交信息是否符合 Conventional Commits 格式
commit_msg=$(cat "$1")
if ! echo "$commit_msg" | grep -qE '^(feat|fix|docs|style|refactor|perf|test|chore|ci|revert)(\\(.+\\))?: .+'; then
echo "提交信息格式错误!请使用:type(scope): description"
echo "示例:feat(auth): 添加微信登录功能"
exit 1
fi

exit 0

14.4 使用 Husky 管理钩子(Node.js 项目)

# 安装 husky
npm install husky –save-dev

# 初始化 husky
npx husky init

# 添加 pre-commit 钩子
echo 'npm run lint' > .husky/pre-commit

# 添加 commit-msg 钩子
echo 'npx commitlint –edit $1' > .husky/commit-msg

# package.json 中的配置
{
"scripts": {
"prepare": "husky"
}
}


十五、Git 工作流模型

15.1 集中式工作流

# 所有人在同一分支(通常是 main)上工作
# 适合小型团队

git checkout main
git pull origin main
# … 修改代码 …
git add .
git commit -m "修改描述"
git push origin main

15.2 功能分支工作流

# 每个功能一个分支,通过 Pull Request 合并
# 适合中小型团队

# 1. 从 main 创建功能分支
git checkout -b feature/xxx main

# 2. 在功能分支上开发
git add .
git commit -m "feat: xxx"

# 3. 推送功能分支
git push origin feature/xxx

# 4. 创建 Pull Request

# 5. 代码审查后合并到 main

# 6. 删除功能分支

15.3 Git Flow 工作流

# 分支角色:
# main – 生产环境代码
# develop – 开发主线
# feature/* – 功能分支
# release/* – 发布分支
# hotfix/* – 紧急修复分支

# 开发新功能
git checkout -b feature/login develop
# … 开发 …
git checkout develop
git merge –no-ff feature/login

# 准备发布
git checkout -b release/1.0 develop
# … 修复小 bug …
git checkout main
git merge –no-ff release/1.0
git tag -a v1.0.0
git checkout develop
git merge –no-ff release/1.0

# 紧急修复
git checkout -b hotfix/1.0.1 main
# … 修复 …
git checkout main
git merge –no-ff hotfix/1.0.1
git tag -a v1.0.1
git checkout develop
git merge –no-ff hotfix/1.0.1

15.4 GitHub Flow 工作流

# 简化的工作流,持续部署
# main 分支始终可部署

# 1. 从 main 创建功能分支
git checkout -b feature-branch

# 2. 开发并提交
git add .
git commit -m "描述"

# 3. 推送并创建 Pull Request
git push origin feature-branch

# 4. 讨论和代码审查

# 5. 合并到 main 并部署

# 6. 删除功能分支

15.5 Trunk-Based Development(主干开发)

# 所有人直接向 main 提交(或使用短生命周期的功能分支)
# 需要完善的 CI/CD 和测试覆盖

# 短功能分支方式
git checkout -b feature/small-change
# … 小改动 …
git push origin feature/small-change
# 快速合并(几小时内)


十六、常见问题排查

16.1 撤销已推送的提交

# 方式一:使用 revert(推荐,安全)
git revert abc1234
git push origin main

# 方式二:使用 reset + force push(危险!不推荐用于公共分支)
git reset –hard HEAD~1
git push –force origin main
# 注意:这会改写历史,影响其他协作者!

16.2 修复错误的合并

# 如果合并后还没有推送
git reset –hard HEAD~1 # 回退到合并前

# 如果已经推送了
git revert -m 1 <merge-commit-hash>
# -m 1 表示保留第一个父提交(通常是主分支)的内容

16.3 处理大文件

# 如果不小心提交了大文件
# 使用 BFG Repo-Cleaner 清理
# 下载:https://rtyley.github.io/bfg-repo-cleaner/

# 删除大于 100MB 的文件
java -jar bfg.jar –strip-blobs-bigger-than 100M repo.git

# 删除特定文件
java -jar bfg.jar –delete-files filename.zip repo.git

# 使用 git-filter-repo
git filter-repo –strip-blobs-bigger-than 10M

# 配置 Git LFS(大文件存储)
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes

16.4 修复损坏的仓库

# 检查仓库完整性
git fsck

# 修复损坏的对象
git fsck –full

# 从损坏中恢复
git fetch origin
git reset –hard origin/main

16.5 解决 “detached HEAD” 状态

# 当你在某个提交上而不是分支上时
# 查看当前状态
git status

# 创建新分支来保留你的修改
git checkout -b new-branch-name

# 或者切换回已有分支
git checkout main

16.6 处理行尾符问题

# 配置行尾符处理
# Windows
git config –global core.autocrlf true
# Linux/Mac
git config –global core.autocrlf input

# 创建 .gitattributes 文件
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.py text eol=lf
*.js text eol=lf
*.java text eol=lf

# 修复已提交文件的行尾符
git add –renormalize .
git commit -m "fix: 统一行尾符"

16.7 找回丢失的提交

# 使用 reflog 查找
git reflog

# 找到目标提交后
git checkout abc1234
# 或
git branch recover-branch abc1234

# 使用 fsck 查找不可达的提交
git fsck –unreachable
git fsck –lost-found


十七、Git 别名配置

# 常用别名配置
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.df diff
git config –global alias.dfc "diff –cached"
git config –global alias.lg "log –oneline –graph –all –decorate"
git config –global alias.last "log -1 HEAD"
git config –global alias.unstage "reset HEAD –"
git config –global alias.visual "log –graph –oneline –all –decorate"
git config –global alias.amend "commit –amend –no-edit"
git config –global alias.pushf "push –force-with-lease"
git config –global alias.undo "reset –soft HEAD~1"
git config –global alias.stash-all "stash push –include-untracked"
git config –global alias.contributors "shortlog -sn –no-merges"

# 使用示例
git st # git status
git co main # git checkout main
git br # git branch
git ci -m "msg" # git commit -m "msg"
git lg # 图形化日志
git amend # 修改最近一次提交
git undo # 撤销最近一次提交(保留修改)


十八、.gitignore 详解

18.1 基本语法

# 忽略所有 .log 文件
*.log

# 忽略 build 目录
build/

# 忽略根目录下的 TODO 文件(不包括子目录)
/TODO

# 忽略 doc 目录下的所有 .pdf 文件
doc/**/*.pdf

# 不忽略 important.log(取反规则)
!important.log

# 忽略所有 .pyc 文件
*.pyc

# 忽略所有 __pycache__ 目录
__pycache__/

# 忽略 .env 文件
.env

# 忽略 .DS_Store(macOS)
.DS_Store

# 忽略 Thumbs.db(Windows)
Thumbs.db

# 忽略 IDE 配置
.idea/
.vscode/
*.swp
*.swo

# 忽略 node_modules
node_modules/

# 忽略依赖目录
vendor/

18.2 通配符说明

# * 匹配任意字符(不包括 /)
# ** 匹配任意目录层级
# ? 匹配单个字符(不包括 /)
# [abc] 匹配方括号中的任一字符
# [0-9] 匹配范围内的任一字符

# 示例:
# *.txt 匹配所有 .txt 文件
# **/*.txt 匹配任意深度的 .txt 文件
# doc/**/*.pdf 匹配 doc 目录下所有 .pdf 文件
# build/*/output 匹配 build/x/output 但不匹配 build/x/y/output

18.3 常用模板

# === Python ===
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
*.egg-info/
dist/
build/
.eggs/
*.egg
.mypy_cache/
.pytest_cache/
.coverage
htmlcov/

# === Node.js ===
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.npm
.eslintcache
dist/
build/

# === Java ===
*.class
*.jar
*.war
*.ear
target/
.gradle/
*.log

# === Go ===
*.exe
*.exe~
*.dll
*.so
*.dylib
*.test
*.out
vendor/

# === Rust ===
/target/
**/*.rs.bk
Cargo.lock

# === IDE ===
.idea/
.vscode/
*.swp
*.swo
*~
.project
.classpath
.settings/

# === OS ===
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Thumbs.db
ehthumbs.db
Desktop.ini

# === 环境变量和密钥 ===
.env
.env.local
.env.*.local
*.pem
*.key

18.4 全局 .gitignore

# 设置全局 gitignore 文件
git config –global core.excludesFile ~/.gitignore_global

# 创建全局 gitignore
echo ".DS_Store" >> ~/.gitignore_global
echo "Thumbs.db" >> ~/.gitignore_global
echo ".idea/" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global

18.5 清理已跟踪的被忽略文件

# 如果某些文件之前被提交了,现在想加入 .gitignore

# 1. 从跟踪中移除(不删除本地文件)
git rm –cached filename.txt
git rm -r –cached directory/

# 2. 更新 .gitignore 文件
echo "filename.txt" >> .gitignore

# 3. 提交
git add .gitignore
git commit -m "chore: 更新 .gitignore,移除已跟踪的忽略文件"


附录:常用命令速查表

操作命令
初始化仓库 git init
克隆仓库 git clone <url>
查看状态 git status
添加到暂存区 git add .
提交 git commit -m "msg"
推送 git push origin <branch>
拉取 git pull origin <branch>
创建分支 git branch <name>
切换分支 git switch <name>
合并分支 git merge <branch>
查看日志 git log –oneline –graph
查看差异 git diff
储藏修改 git stash
恢复储藏 git stash pop
撤销修改 git restore <file>
回退提交 git reset –soft HEAD~1
反转提交 git revert <commit>
创建标签 git tag -a v1.0 -m "msg"
查看标签 git tag
暂存工作 git stash push -m "msg"
Cherry-pick git cherry-pick <commit>
交互式变基 git rebase -i HEAD~N

最后更新:2026-07-26

赞(0)
未经允许不得转载:网硕互联帮助中心 » Git 操作大全
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!