Git 速成指南:从入门到撤销、分支协作与故障恢复

欢迎你来读这篇博客。本文是一份面向日常开发的 Git 速成指南与命令速查表,覆盖仓库初始化、提交、分支、合并、变基、远程协作、撤销误操作、文件忽略、历史恢复和常见工程实践。

阅读完本文,你应该能够快速判断:

  • 文件现在位于工作区、暂存区,还是已经提交;
  • 修改错了、提交错了、推送错了,分别该用什么命令;
  • resetrestorerevertcheckout 到底有什么区别;
  • 如何正确使用分支、合并、变基和远程仓库;
  • 如何把已经被 Git 跟踪的文件移出索引,但保留本地文件。

序言

Git 最难的地方通常不是命令多,而是同一个“撤销”动作,在不同阶段需要使用完全不同的命令。

先记住 Git 的四个核心区域:

  1. 工作区(Working Tree):你正在编辑的文件。
  2. 暂存区(Index / Staging Area):下一次提交准备包含的内容。
  3. 本地仓库(Local Repository):已经通过 commit 保存的历史。
  4. 远程仓库(Remote Repository):GitHub、GitLab、Gitee 等服务器上的仓库。
flowchart LR
    A[工作区<br/>Working Tree] -->|git add| B[暂存区<br/>Index]
    B -->|git commit| C[本地仓库<br/>Local Repository]
    C -->|git push| D[远程仓库<br/>Remote Repository]

    B -->|git restore --staged| A
    C -->|git reset| B
    D -->|git fetch / git pull| C

Git 操作的本质,就是让文件和提交在这些区域之间移动。


正文

1. Git 基础配置

1.1 查看 Git 版本

1
git --version

1.2 配置用户名和邮箱

全局配置:

1
2
git config --global user.name "SuperMario"
git config --global user.email "your-email@example.com"

仅配置当前仓库:

1
2
git config user.name "SuperMario"
git config user.email "your-email@example.com"

1.3 查看配置

查看全部配置:

1
git config --list

查看配置来源:

1
git config --list --show-origin

查看单项配置:

1
2
git config user.name
git config user.email

1.4 设置默认分支名称

1
git config --global init.defaultBranch main

1.5 设置默认编辑器

使用 Vim:

1
git config --global core.editor "vim"

使用 VS Code:

1
git config --global core.editor "code --wait"

1.6 常用别名

1
2
3
4
5
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 --decorate --all"

以后可以直接执行:

1
2
git st
git lg

2. 创建和获取仓库

2.1 初始化仓库

1
2
3
mkdir demo-project
cd demo-project
git init

指定默认分支:

1
git init -b main

2.2 克隆远程仓库

1
git clone https://github.com/user/repository.git

指定本地目录:

1
git clone https://github.com/user/repository.git local-directory

克隆指定分支:

1
git clone -b develop https://github.com/user/repository.git

浅克隆,只获取最近一次历史:

1
git clone --depth 1 https://github.com/user/repository.git

3. Git 日常操作流程

最常见的开发流程:

1
2
3
4
5
git status
git add .
git commit -m "feat: add user login"
git pull --rebase
git push
flowchart TD
    A[拉取最新代码] --> B[创建或切换功能分支]
    B --> C[修改代码]
    C --> D[git status / git diff]
    D --> E[git add]
    E --> F[git commit]
    F --> G[git pull --rebase]
    G --> H[解决可能的冲突]
    H --> I[git push]
    I --> J[创建 Pull Request]

3.1 查看仓库状态

1
git status

精简输出:

1
git status -s

常见状态标记:

标记 含义
?? 未跟踪文件
A 新增并已暂存
M 文件已修改
D 文件已删除
R 文件被重命名
左侧 M 暂存区有修改
右侧 M 工作区有修改

3.2 查看修改内容

查看工作区与暂存区的差异:

1
git diff

查看暂存区与最后一次提交的差异:

1
git diff --staged

也可以写成:

1
git diff --cached

查看某个文件:

1
git diff src/main/java/Demo.java

查看两个提交之间的差异:

1
git diff commitA commitB

查看两个分支之间的差异:

1
git diff main..feature/login

3.3 添加文件到暂存区

添加指定文件:

1
git add README.md

添加多个文件:

1
git add README.md pom.xml

添加当前目录全部变化:

1
git add .

添加整个仓库全部变化:

1
git add -A

只添加已被跟踪文件的修改和删除,不添加新文件:

1
git add -u

交互式选择部分修改:

1
git add -p

git add -p 非常适合把一个大修改拆成多个逻辑清晰的提交。

3.4 提交修改

普通提交:

1
git commit -m "feat: add login API"

打开编辑器填写详细提交信息:

1
git commit

提交所有已被跟踪文件的修改:

1
git commit -am "fix: correct order amount"

注意:-a 不会自动添加未跟踪的新文件。

修改最近一次提交:

1
git commit --amend

修改最近一次提交信息:

1
git commit --amend -m "fix: correct order calculation"

只修改提交信息,不改提交内容:

1
git commit --amend --no-edit

准确地说,--no-edit 是保留原提交信息并重新生成提交,常用于补加漏掉的文件:

1
2
git add forgotten-file.txt
git commit --amend --no-edit

如果提交已经推送到共享分支,谨慎使用 --amend,因为它会重写提交历史。


4. 提交信息规范

推荐使用 Conventional Commits 风格:

1
<type>(<scope>): <description>

常见类型:

类型 含义
feat 新功能
fix Bug 修复
docs 文档修改
style 格式调整,不影响逻辑
refactor 重构
perf 性能优化
test 测试相关
build 构建系统或依赖
ci CI/CD 配置
chore 其他维护工作
revert 回滚提交

示例:

1
2
3
4
git commit -m "feat(order): add settlement query API"
git commit -m "fix(payment): prevent duplicate callback"
git commit -m "refactor(user): extract permission service"
git commit -m "docs: update deployment guide"

好的提交应该满足:

  • 一次提交只解决一个相对独立的问题;
  • 提交信息说明“为什么改”和“改了什么”;
  • 避免使用 updatemodifyfix bug 这种信息量过低的描述;
  • 不要把格式化、重构、新功能和 Bug 修复混在同一次提交里。

5. 文件删除、移动与重命名

5.1 删除文件

同时删除本地文件和 Git 索引:

1
git rm file.txt

删除目录:

1
git rm -r directory/

提交删除操作:

1
git commit -m "chore: remove obsolete files"

5.2 从 Git 索引移除,但保留本地文件

这是已经提交或已被 Git 跟踪的文件,不再希望 Git 管理时最常用的命令。

1
git rm --cached file.txt

目录:

1
git rm -r --cached directory/

然后将文件加入 .gitignore

1
2
3
application-local.yml
.idea/
logs/

最后提交索引变化:

1
2
git add .gitignore
git commit -m "chore: stop tracking local files"

注意:只写入 .gitignore,不能自动解除已经被 Git 跟踪文件的状态。必须先执行 git rm --cached

5.3 根据 .gitignore 重新构建索引

当仓库中误提交了大量本应忽略的文件时,可以执行:

1
2
3
git rm -r --cached .
git add .
git commit -m "chore: refresh gitignore rules"

这不会删除本地文件,但会重新计算哪些文件应该被 Git 跟踪。

5.4 移动或重命名文件

1
git mv old-name.txt new-name.txt

移动到目录:

1
git mv Demo.java src/main/java/

Git 实际上是根据内容相似度识别重命名,因此手动执行系统的 mv 后再 git add -A,通常也能被识别。


6. .gitignore 使用指南

6.1 常见规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 忽略单个文件
application-local.yml

# 忽略目录
.idea/
target/
logs/

# 忽略所有日志
*.log

# 忽略所有临时文件
*.tmp
*.swp

# 忽略任意目录下的指定文件
**/application-local.yml

# 忽略目录中的全部内容
cache/*

# 重新包含某个文件
!cache/.gitkeep

6.2 Java / Maven 项目示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
release.properties

# IntelliJ IDEA
.idea/
*.iml
*.ipr
*.iws

# VS Code
.vscode/

# Logs
logs/
*.log

# OS
.DS_Store
Thumbs.db

# Local configuration
application-local.yml
application-dev-local.yml
.env

6.3 检查文件为什么被忽略

1
git check-ignore -v file.txt

输出会显示是哪条规则忽略了该文件。

6.4 强制添加被忽略文件

1
git add -f file.txt

除非你明确知道原因,否则不要随意强制添加敏感配置、构建产物或 IDE 文件。


7. 分支操作

7.1 查看分支

查看本地分支:

1
git branch

查看远程分支:

1
git branch -r

查看全部分支:

1
git branch -a

查看分支与上游关系:

1
git branch -vv

7.2 创建分支

1
git branch feature/login

创建并切换:

1
git switch -c feature/login

传统写法:

1
git checkout -b feature/login

推荐新项目优先使用语义更清楚的 git switchgit restore

7.3 切换分支

1
git switch main

切换到上一个分支:

1
git switch -

传统写法:

1
git checkout main

7.4 重命名分支

重命名当前分支:

1
git branch -m new-name

重命名指定分支:

1
git branch -m old-name new-name

7.5 删除分支

安全删除已经合并的本地分支:

1
git branch -d feature/login

强制删除未合并分支:

1
git branch -D feature/login

删除远程分支:

1
git push origin --delete feature/login

7.6 设置上游分支

首次推送新分支:

1
git push -u origin feature/login

之后可以直接:

1
2
git push
git pull

手动设置上游:

1
git branch --set-upstream-to=origin/feature/login

8. 合并分支:merge

假设要把 feature/login 合并到 main

1
2
3
git switch main
git pull
git merge feature/login

8.1 快进合并

如果 main 没有产生新的提交,Git 可以直接移动分支指针。

gitGraph
   commit id: "A"
   commit id: "B"
   branch feature
   checkout feature
   commit id: "C"
   commit id: "D"
   checkout main
   merge feature id: "Fast-forward"

8.2 创建合并提交

强制保留合并节点:

1
git merge --no-ff feature/login

适合希望明确保留功能分支边界的团队。

8.3 取消正在进行的合并

1
git merge --abort

9. 变基:rebase

将当前分支的提交重新应用到目标分支最新提交之后:

1
2
git switch feature/login
git rebase main
gitGraph
   commit id: "A"
   commit id: "B"
   branch feature
   checkout feature
   commit id: "C"
   commit id: "D"
   checkout main
   commit id: "E"
   commit id: "F"
   checkout feature
   commit id: "C-prime"
   commit id: "D-prime"

上图是逻辑示意。实际执行 rebase 后,旧的 CD 会被新的提交对象替代。

9.1 rebase 解决冲突

发生冲突后:

1
git status

编辑冲突文件,然后:

1
2
git add conflicted-file.txt
git rebase --continue

跳过当前提交:

1
git rebase --skip

取消整个变基:

1
git rebase --abort

9.2 交互式变基

整理最近 5 个提交:

1
git rebase -i HEAD~5

常见操作:

指令 含义
pick 保留提交
reword 修改提交信息
edit 暂停并修改提交
squash 合并到前一个提交,保留信息
fixup 合并到前一个提交,丢弃当前信息
drop 删除提交

9.3 merge 和 rebase 如何选择

场景 推荐
公共分支、共享历史 merge
个人功能分支同步主分支 rebase
需要保留完整分支轨迹 merge --no-ff
希望提交历史线性整洁 rebase
已经推送且多人基于该分支开发 避免重写历史

核心原则:

不要随意 rebase 已经公开且被其他人使用的提交历史。


10. 远程仓库操作

10.1 查看远程仓库

1
2
git remote
git remote -v

10.2 添加远程仓库

1
git remote add origin https://github.com/user/repository.git

10.3 修改远程地址

1
git remote set-url origin git@github.com:user/repository.git

10.4 重命名远程仓库

1
git remote rename origin upstream

10.5 删除远程仓库

1
git remote remove origin

10.6 获取远程更新

只下载远程信息,不自动合并:

1
git fetch

获取指定远程:

1
git fetch origin

获取并清理远程已删除分支:

1
git fetch --prune

全局开启自动清理:

1
git config --global fetch.prune true

10.7 拉取代码

1
git pull

git pull 通常相当于:

1
2
git fetch
git merge

使用变基方式拉取:

1
git pull --rebase

全局设置默认使用 rebase:

1
git config --global pull.rebase true

10.8 推送代码

推送当前分支:

1
git push

首次推送并建立上游:

1
git push -u origin feature/login

推送指定分支:

1
git push origin main

推送标签:

1
git push origin v1.0.0

推送全部标签:

1
git push origin --tags

11. 冲突处理

Git 冲突通常长这样:

1
2
3
4
5
<<<<<<< HEAD
当前分支的内容
=======
被合并分支的内容
>>>>>>> feature/login

处理步骤:

  1. 打开冲突文件;
  2. 决定保留哪部分内容;
  3. 删除冲突标记;
  4. 测试代码;
  5. 将文件重新加入暂存区;
  6. 继续合并或变基。

合并冲突:

1
2
git add conflicted-file.txt
git commit

变基冲突:

1
2
git add conflicted-file.txt
git rebase --continue

查看冲突文件:

1
git diff --name-only --diff-filter=U

使用当前分支版本:

1
git checkout --ours conflicted-file.txt

使用对方分支版本:

1
git checkout --theirs conflicted-file.txt

注意:在 rebase 场景中,ourstheirs 的语义容易让人产生误解,执行前务必先检查结果。


12. 撤销操作总览

撤销操作首先要判断修改处于哪个阶段。

flowchart TD
    A{修改在哪个阶段?}
    A -->|仅工作区| B[git restore file]
    A -->|已 add 未 commit| C[git restore --staged file]
    A -->|已 commit 未 push| D[git reset]
    A -->|已 push 到共享分支| E[git revert]
    A -->|误删提交或 reset| F[git reflog]

12.1 撤销工作区修改

恢复单个文件到暂存区或最后一次提交的状态:

1
git restore file.txt

恢复全部工作区修改:

1
git restore .

危险:未保存的修改会丢失。

传统写法:

1
git checkout -- file.txt

12.2 取消暂存,但保留工作区修改

1
git restore --staged file.txt

取消全部暂存:

1
git restore --staged .

传统写法:

1
git reset HEAD file.txt

12.3 撤销最近一次提交,但保留暂存状态

1
git reset --soft HEAD~1

效果:

  • 提交被撤销;
  • 修改仍在暂存区;
  • 适合重新组织提交或修改提交信息。

12.4 撤销最近一次提交,保留工作区修改

1
git reset HEAD~1

等价于:

1
git reset --mixed HEAD~1

效果:

  • 提交被撤销;
  • 暂存状态被取消;
  • 文件修改仍然保留在工作区。

这通常就是 IDE 中 Undo Commit 接近的行为。

12.5 撤销提交并丢弃所有修改

1
git reset --hard HEAD~1

效果:

  • 删除最近一次提交;
  • 丢弃暂存区修改;
  • 丢弃工作区修改。

这是高风险命令,执行前建议先创建临时分支或查看 git status

12.6 reset 三种模式对比

命令 移动 HEAD 重置暂存区 重置工作区
git reset --soft
git reset --mixed
git reset --hard

12.7 安全撤销已推送提交

对共享分支,推荐创建一个反向提交:

1
git revert <commit-id>

撤销最近一次提交:

1
git revert HEAD

撤销多个提交:

1
git revert oldest-commit^..newest-commit

只生成修改,不立即提交:

1
git revert --no-commit <commit-id>

revert 不会删除历史,而是增加一个新提交,所以更适合已经推送的公共分支。

12.8 撤销合并提交

首先查看父提交:

1
git show --summary <merge-commit-id>

通常保留第一个父提交:

1
git revert -m 1 <merge-commit-id>

-m 1 表示以第一个父提交作为主线。不要在没理解父提交关系时盲目执行。


13. resetrestorerevert 区别

命令 主要作用 是否重写历史 典型场景
git restore 恢复文件、取消暂存 撤销工作区或暂存区修改
git reset 移动分支指针、重置索引和工作区 撤销本地未公开提交
git revert 创建反向提交 安全撤销已推送提交
git checkout 历史命令,兼顾切分支和恢复文件 视操作而定 兼容旧教程
git switch 创建或切换分支 分支切换

简单记忆:

  • 文件改坏了:restore
  • 本地提交错了:reset
  • 公共提交错了:revert
  • 分支切换:switch

14. 恢复误操作:reflog

git reflog 是 Git 的“后悔药记录器”,会记录本地 HEAD 和分支引用的移动。

1
git reflog

示例:

1
2
e8b1c7a HEAD@{0}: reset: moving to HEAD~2
da92f21 HEAD@{1}: commit: feat: add payment API

恢复到误操作前:

1
git reset --hard HEAD@{1}

更安全的方式是先创建恢复分支:

1
git branch recovery-branch HEAD@{1}

然后检查:

1
git switch recovery-branch

常见可恢复场景:

  • reset --hard 到错误提交;
  • 删除了本地分支;
  • rebase 后找不到原提交;
  • amend 后想找回旧提交;
  • checkout 到错误位置后丢失引用。

reflog 主要是本地记录,不等于远程仓库的永久备份。


15. 临时保存修改:stash

当工作尚未完成,但需要切换分支时:

1
git stash

带描述保存:

1
git stash push -m "WIP: settlement calculation"

包含未跟踪文件:

1
git stash -u

包含被忽略文件:

1
git stash -a

查看列表:

1
git stash list

查看某个 stash:

1
2
git stash show stash@{0}
git stash show -p stash@{0}

恢复并保留 stash:

1
git stash apply

恢复并删除 stash:

1
git stash pop

恢复指定 stash:

1
git stash apply stash@{1}

删除指定 stash:

1
git stash drop stash@{0}

清空全部 stash:

1
git stash clear

从 stash 创建分支:

1
git stash branch feature/recovery stash@{0}

这在 stash 与当前代码冲突较多时非常实用。


16. 查看提交历史

16.1 基础日志

1
git log

单行显示:

1
git log --oneline

图形化显示全部分支:

1
git log --oneline --graph --decorate --all

查看最近 10 条:

1
git log -10

查看某个文件历史:

1
git log -- path/to/file

跟踪文件重命名前后的历史:

1
git log --follow -- path/to/file

查看提交包含的修改:

1
git log -p

查看提交统计:

1
git log --stat

16.2 按作者、日期和内容搜索

按作者:

1
git log --author="Mario"

按日期:

1
git log --since="2026-07-01" --until="2026-07-16"

按提交信息:

1
git log --grep="payment"

搜索新增或删除了某段文本的提交:

1
git log -S "calculateAmount"

使用正则搜索 diff:

1
git log -G "calculate.*Amount"

16.3 查看某个提交

1
git show <commit-id>

只查看提交摘要:

1
git show --stat <commit-id>

只查看某个提交中的文件:

1
git show <commit-id>:path/to/file

17. Cherry-pick:摘取提交

把其他分支的单个提交复制到当前分支:

1
git cherry-pick <commit-id>

摘取多个连续提交:

1
git cherry-pick oldest-commit^..newest-commit

只应用修改,不立即提交:

1
git cherry-pick -n <commit-id>

发生冲突后:

1
2
git add .
git cherry-pick --continue

取消操作:

1
git cherry-pick --abort

跳过当前提交:

1
git cherry-pick --skip

常见场景:

  • 将某个 Bug 修复同步到发布分支;
  • 从错误分支中提取一个提交;
  • 将热修复同步到多个维护分支。

18. 标签:tag

18.1 查看标签

1
git tag

按模式过滤:

1
git tag -l "v1.*"

18.2 创建标签

轻量标签:

1
git tag v1.0.0

附注标签:

1
git tag -a v1.0.0 -m "Release v1.0.0"

给指定提交打标签:

1
git tag -a v1.0.0 <commit-id> -m "Release v1.0.0"

18.3 推送标签

1
git push origin v1.0.0

推送全部标签:

1
git push origin --tags

18.4 删除标签

删除本地标签:

1
git tag -d v1.0.0

删除远程标签:

1
git push origin --delete v1.0.0

推荐使用语义化版本:

1
2
主版本.次版本.修订版本
MAJOR.MINOR.PATCH

例如:

  • v1.0.0:首个稳定版本;
  • v1.1.0:兼容的新功能;
  • v1.1.1:兼容的 Bug 修复;
  • v2.0.0:不兼容变更。

19. 比较、定位与排查

19.1 查看每一行是谁修改的

1
git blame path/to/file

指定行范围:

1
git blame -L 20,50 path/to/file

19.2 二分查找引入 Bug 的提交

开始:

1
git bisect start

标记当前版本有问题:

1
git bisect bad

标记一个已知正常提交:

1
git bisect good <commit-id>

Git 会自动切换到中间提交。测试后继续标记:

1
git bisect good

或:

1
git bisect bad

找到问题提交后退出:

1
git bisect reset

结合自动化测试:

1
2
git bisect start HEAD <good-commit-id>
git bisect run ./mvnw test

19.3 查看哪些分支包含某个提交

1
git branch --contains <commit-id>

查看远程分支:

1
git branch -r --contains <commit-id>

19.4 查看分支尚未合并的提交

1
git log main..feature/login --oneline

查看两个分支各自独有的提交:

1
git log --left-right --graph main...feature/login

20. 清理未跟踪文件

预览将要删除的文件:

1
git clean -n

删除未跟踪文件:

1
git clean -f

删除未跟踪目录:

1
git clean -fd

同时删除被 .gitignore 忽略的文件:

1
git clean -fdx

交互式清理:

1
git clean -i

git clean -fdx 会删除构建产物、IDE 配置和本地环境文件,威力接近“项目格式化按钮”,执行前一定先用 -n 预览。


21. 强制推送与历史改写

普通强制推送:

1
git push --force

更安全的强制推送:

1
git push --force-with-lease

优先使用:

1
git push --force-with-lease

它会检查远程分支是否已经被其他人更新,可以降低误覆盖他人提交的风险。

常见需要强制推送的情况:

  • 已推送的个人功能分支执行了 rebase;
  • 修改了最近一次已推送提交;
  • 使用交互式 rebase 整理了提交历史。

不建议对 mainmasterdevelop 等共享分支强制推送。


22. 远程分支常见问题

22.1 远程分支已删除,本地仍然显示

1
git fetch --prune

22.2 本地删除已经不存在的远程跟踪分支

1
git remote prune origin

22.3 本地分支关联错了上游

查看:

1
git branch -vv

取消关联:

1
git branch --unset-upstream

重新关联:

1
git branch --set-upstream-to=origin/correct-branch

22.4 本地分支落后远程

1
2
git fetch origin
git rebase origin/main

或:

1
git pull --rebase

22.5 本地完全对齐远程分支

1
2
git fetch origin
git reset --hard origin/main

此操作会丢弃当前分支尚未保存的本地提交和修改,执行前务必备份。


23. Worktree:同时打开多个分支

一个 Git 仓库通常一次只能检出一个分支。git worktree 可以为同一个仓库创建多个工作目录。

创建新工作目录并检出分支:

1
git worktree add ../project-hotfix hotfix/payment

创建新分支:

1
git worktree add -b feature/report ../project-report main

查看 worktree:

1
git worktree list

移除:

1
git worktree remove ../project-hotfix

清理无效记录:

1
git worktree prune

适合场景:

  • 当前正在开发功能,突然需要修复线上 Bug;
  • 同时运行两个版本进行对比;
  • 避免频繁 stash 和切换分支。

24. Submodule:子模块

添加子模块:

1
git submodule add https://github.com/user/library.git libs/library

克隆包含子模块的仓库:

1
git clone --recurse-submodules https://github.com/user/project.git

初始化并更新:

1
git submodule update --init --recursive

更新子模块到远程最新版本:

1
git submodule update --remote --merge

子模块记录的是另一个仓库的特定提交,不是普通目录。团队协作中必须同时提交父仓库对子模块指针的变化。


25. Git LFS:管理大文件

Git 不适合直接管理频繁变化的大型二进制文件。Git LFS 会在 Git 中保存指针,在 LFS 服务中存储实际文件。

安装并初始化:

1
git lfs install

跟踪大文件:

1
2
git lfs track "*.psd"
git lfs track "*.zip"

提交规则:

1
2
3
git add .gitattributes
git add design.psd
git commit -m "chore: add design assets with Git LFS"

查看跟踪文件:

1
git lfs ls-files

26. 敏感文件误提交处理

26.1 只是在最近一次本地提交中

从索引移除:

1
git rm --cached application-secret.yml

加入 .gitignore

1
2
application-secret.yml
.env

修改最近提交:

1
2
git add .gitignore
git commit --amend --no-edit

26.2 已经推送到远程

仅执行 git rm --cached 不能删除历史中的秘密。

应立即:

  1. 吊销并轮换泄露的密码、Token、密钥;
  2. 从当前版本移除敏感文件;
  3. 使用 git filter-repo 或平台提供的历史清理方案;
  4. 强制推送清理后的历史;
  5. 通知协作者重新克隆或正确同步仓库。

示例:

1
git filter-repo --path application-secret.yml --invert-paths

然后:

1
2
git push --force --all
git push --force --tags

历史清理会影响所有协作者,必须协调执行。真正的第一优先级始终是轮换密钥,而不是只想着让提交“看不见”。


27. 常见场景速查

场景 1:文件修改错了,还没有 add

1
git restore file.txt

场景 2:文件已经 add,想取消暂存

1
git restore --staged file.txt

场景 3:刚提交,想补一个漏掉的文件

1
2
git add forgotten-file.txt
git commit --amend --no-edit

场景 4:刚提交,想修改提交信息

1
git commit --amend -m "new commit message"

场景 5:Undo Commit 后想让文件不再被 Git 管理

1
2
3
4
git rm --cached file.txt
echo "file.txt" >> .gitignore
git add .gitignore
git commit -m "chore: stop tracking file"

目录:

1
git rm -r --cached directory/

场景 6:撤销最近一次提交,但保留文件修改

1
git reset HEAD~1

场景 7:撤销最近一次提交,并保持文件已暂存

1
git reset --soft HEAD~1

场景 8:安全撤销已经推送的提交

1
2
git revert <commit-id>
git push

场景 9:误执行了 reset

1
2
git reflog
git branch recovery HEAD@{1}

场景 10:错误地提交到了 main

先创建正确分支保留提交:

1
git branch feature/correct-branch

再让 main 回退:

1
git reset --hard origin/main

最后切换到正确分支:

1
git switch feature/correct-branch

如果错误提交已经推送到共享的 main,不要直接 reset 后强推,优先使用 git revert

场景 11:想把某个提交复制到当前分支

1
git cherry-pick <commit-id>

场景 12:当前修改没完成,但需要切分支

1
2
git stash push -u -m "WIP"
git switch other-branch

回来后:

1
2
git switch original-branch
git stash pop

场景 13:本地代码不要了,完全以远程为准

1
2
3
git fetch origin
git reset --hard origin/main
git clean -fd

高风险操作:本地未提交和未跟踪内容可能被删除。

场景 14:删除远程分支

1
git push origin --delete feature/old

场景 15:修改了已经推送的个人分支历史

1
git push --force-with-lease

28. Git 命令速查表

仓库与配置

目的 命令
初始化仓库 git init
克隆仓库 git clone <url>
查看配置 git config --list
配置用户名 git config --global user.name "Name"
配置邮箱 git config --global user.email "email"
查看远程仓库 git remote -v

文件与暂存区

目的 命令
查看状态 git status
添加指定文件 git add <file>
添加全部变化 git add -A
交互式添加 git add -p
取消暂存 git restore --staged <file>
撤销工作区修改 git restore <file>
删除文件 git rm <file>
停止跟踪但保留文件 git rm --cached <file>
查看忽略规则来源 git check-ignore -v <file>

提交与历史

目的 命令
创建提交 git commit -m "message"
修改最近提交 git commit --amend
查看日志 git log --oneline --graph --all
查看提交详情 git show <commit>
查看文件每行作者 git blame <file>
查找丢失提交 git reflog

分支

目的 命令
查看分支 git branch -a
创建并切换分支 git switch -c <branch>
切换分支 git switch <branch>
删除本地分支 git branch -d <branch>
强制删除本地分支 git branch -D <branch>
删除远程分支 git push origin --delete <branch>
重命名当前分支 git branch -m <new-name>

合并与变基

目的 命令
合并分支 git merge <branch>
取消合并 git merge --abort
变基 git rebase <branch>
继续变基 git rebase --continue
取消变基 git rebase --abort
整理最近提交 git rebase -i HEAD~N
摘取提交 git cherry-pick <commit>

远程协作

目的 命令
获取远程更新 git fetch
拉取并合并 git pull
拉取并变基 git pull --rebase
首次推送分支 git push -u origin <branch>
推送当前分支 git push
安全强制推送 git push --force-with-lease
清理失效远程分支 git fetch --prune

撤销与恢复

目的 命令
撤销工作区文件 git restore <file>
取消暂存 git restore --staged <file>
撤销提交并保留暂存 git reset --soft HEAD~1
撤销提交并保留工作区 git reset HEAD~1
撤销提交并丢弃修改 git reset --hard HEAD~1
安全撤销公共提交 git revert <commit>
恢复误删提交 git reflog

临时保存与清理

目的 命令
暂存当前修改 git stash
包含未跟踪文件 git stash -u
恢复并删除 stash git stash pop
查看 stash git stash list
预览清理文件 git clean -n
删除未跟踪文件 git clean -f
删除未跟踪文件与目录 git clean -fd

29. 推荐的团队分支流程

一个轻量且实用的流程:

gitGraph
   commit id: "main-1"
   branch develop
   checkout develop
   commit id: "develop-1"
   branch feature/order
   checkout feature/order
   commit id: "feature-1"
   commit id: "feature-2"
   checkout develop
   merge feature/order id: "merge-feature"
   branch release/1.2.0
   checkout release/1.2.0
   commit id: "release-fix"
   checkout main
   merge release/1.2.0 tag: "v1.2.0"
   checkout develop
   merge main

小型团队也可以采用更简单的 GitHub Flow:

  1. main 始终保持可发布;
  2. 每个任务创建独立功能分支;
  3. 开发完成后推送并创建 Pull Request;
  4. 代码审查和 CI 通过后合并;
  5. 合并后删除功能分支。

分支命名示例:

1
2
3
4
5
6
feature/user-login
fix/payment-timeout
hotfix/order-duplicate
refactor/settlement-service
docs/deployment-guide
release/1.2.0

30. Pull Request 前检查清单

提交 PR 前建议检查:

1
2
3
4
5
6
git status
git fetch origin
git rebase origin/main
./mvnw test
git log --oneline origin/main..HEAD
git diff origin/main...HEAD

检查项:

  • 是否包含无关文件;
  • 是否误提交本地配置、密码、Token;
  • 是否存在调试日志或临时代码;
  • 提交是否可以按逻辑拆分;
  • 提交信息是否清楚;
  • 是否已经通过测试;
  • 是否已同步目标分支最新代码;
  • PR 描述是否包含背景、改动、验证方式和风险。

31. 高风险命令清单

下面这些命令不是不能用,而是执行前必须知道会丢掉什么:

1
2
3
4
5
6
7
8
9
git reset --hard
git clean -fd
git clean -fdx
git branch -D
git push --force
git checkout -- .
git restore .
git reflog expire --expire=now --all
git gc --prune=now

执行高风险命令前,推荐:

1
2
3
4
git status
git diff
git diff --staged
git branch backup-before-operation

给当前状态创建一个保险分支:

1
git branch backup/20260716

创建分支几乎不占额外空间,却可能帮你省下一场“代码考古”。


32. Git 故障排查思路

遇到问题时,不要第一反应就 reset --hard。推荐按以下顺序判断:

flowchart TD
    A[Git 出现问题] --> B[执行 git status]
    B --> C[确认当前分支]
    C --> D[查看 git diff]
    D --> E[查看 git diff --staged]
    E --> F[查看 git log --oneline --graph --all]
    F --> G{提交是否丢失?}
    G -->|是| H[查看 git reflog]
    G -->|否| I{是否正在 merge/rebase/cherry-pick?}
    I -->|是| J[continue / abort]
    I -->|否| K[根据工作区、暂存区、提交历史选择 restore/reset/revert]

建议优先执行这些只读命令:

1
2
3
4
5
6
7
git status
git branch -vv
git remote -v
git log --oneline --graph --decorate --all
git reflog
git diff
git diff --staged

先观察,再修改。Git 很少真的把提交立刻销毁,很多事故只是“分支指针走丢了”。


参考资料

  • Git 官方文档:git help <command>
  • Pro Git:系统学习 Git 原理和实践的经典资料
  • Git 命令帮助:
1
2
3
4
git help reset
git help restore
git help rebase
git help reflog

查看简短帮助:

1
2
git reset -h
git restore -h

遇到不熟悉的命令时,优先阅读帮助信息,不要直接复制一条看起来很勇猛的 --force 命令。


启示录

Git 的核心不是“背命令”,而是理解三个问题:

  1. 当前修改在哪个区域?
  2. 我想保留什么,丢弃什么?
  3. 这段历史是否已经被其他人使用?

只要先回答这三个问题,大多数 Git 操作都能正确选择:

  • 工作区问题用 restore
  • 暂存区问题用 restore --staged
  • 本地提交问题用 reset
  • 公共历史问题用 revert
  • 提交找不到时用 reflog
  • 想保留本地文件但停止 Git 跟踪时用 git rm --cached

富贵岂由人,时会高志须酬。

能成功于千载者,必以近察远。


Git 速成指南:从入门到撤销、分支协作与故障恢复
https://allendericdalexander.github.io/2026/07/16/scm/Git_manual/
作者
AtLuoFu
发布于
2026年7月16日
许可协议