本文结合真实命令行操作记录,深度拆解 Git 核心功能:忽略文件配置、变更暂存与对比、分支管理、冲突解决及 Stash 临时工作流,帮你建立从 “会用命令” 到 “理解原理” 的完整认知。
一、忽略文件:.gitignore 配置
1.1 为什么需要 .gitignore
?
- 排除日志文件、编译产物、临时文件、编辑器配置等无需版本控制的内容;
- 避免这些文件出现在
git status
的 “未跟踪文件” 列表,保持仓库整洁。
1.2 语法规则(必掌握)
规则类型 | 示例 | 解释 |
---|---|---|
注释 | # 忽略日志文件 |
# 开头的行被忽略 |
通配符 | *.log |
匹配所有 .log 结尾的文件 |
目录 | target/ |
忽略 target 目录(含子文件 / 目录) |
取反 | !classes/a.class |
不忽略 classes/a.class 文件 |
层级匹配 | **/foo |
匹配任意目录下的 foo (如 a/foo 、b/c/foo ) |
1.3 通用模板(以 Java 项目为例)
# 编译产物
*.class
*.war
*.ear
# 构建目录
target/
build/
# 编辑器配置(IDEA/Eclipse)
.idea/
.settings/
.project
.classpath
# 临时文件
*.log
*.tmp
.DS_Store # Mac 系统文件
Thumbs.db # Windows 系统文件
1.4 规则不生效?解决方法!
- 原因:.gitignore 只能忽略 未被 Git 跟踪 的文件(即从未
git add
或commit
的文件)。 - 解决:若文件已被跟踪,需先从仓库中移除(本地文件保留):
git rm --cached <文件名> # 如 git rm --cached Test.class
二、变更暂存:git add
的三种模式
Git 提供三种暂存策略,灵活控制新文件、修改、删除的跟踪范围:
命令 | 暂存内容 | 适用场景 |
---|---|---|
git add -A |
新文件 + 修改 + 删除(全仓库) | 提交所有变更(如版本收尾) |
git add -u |
修改 + 删除(仅已跟踪文件) | 忽略新文件,整理已有变更 |
git add . |
新文件 + 修改(当前目录) | 聚焦当前目录的新增 / 修改 |
实战示例:
# 修改 Test.txt,新建 Test1.txt,删除 Old.txt
$ git add . # 暂存 Test.txt(修改)、Test1.txt(新文件),但忽略 Old.txt(删除)
$ git add -u # 暂存 Test.txt(修改)、Old.txt(删除),但忽略 Test1.txt(新文件)
$ git add -A # 暂存所有变更(Test.txt、Test1.txt、Old.txt)
三、差异对比:git diff
看透文件变化
Git diff 可对比 工作区、暂存区、仓库 之间的差异,核心场景:
3.1 工作区 vs 暂存区
git diff <文件名>
# 示例:查看 Test.txt 在工作区的修改(未 `git add` 时,对比自身修改)
$ git diff Test.txt
3.2 暂存区 vs 仓库(最近一次提交)
git diff --cached <文件名>
# 示例:查看 Test1.txt 已 `git add` 但未 `commit` 的变化
$ git diff --cached Test1.txt
3.3 工作区 vs 仓库(指定版本)
git diff <提交ID> <文件名>
# 示例:对比工作区 Test.txt 与历史提交 `c900dca` 的差异
$ git diff c900dca Test.txt
# (`HEAD` 可替代“最近一次提交”,如 `git diff HEAD Test.txt`)
3.4 仓库间对比(任意两次提交)
git diff <提交ID1> <提交ID2>
# 示例:对比初始提交(993e44)和 Test 提交(c900dca)的差异
$ git diff 993e44 c900dca
四、分支管理:创建、合并与冲突
Git 分支是轻量级指针(指向提交对象),相比 SVN 更高效。
4.1 分支创建与切换
# 创建分支 dev(基于当前提交)
git branch dev
# 切换到 dev 分支
git checkout dev
# 一步创建并切换(推荐)
git checkout -b dev2
4.2 分支删除
# 安全删除(需分支已合并到当前分支)
git branch -d dev2
# 强制删除(忽略合并状态,慎用)
git branch -D dev2
4.3 合并策略:快进 vs 冲突
(1)快进合并(无冲突,指针直接移动)
- 条件:被合并分支(如
dev
)是当前分支(如master
)的直接后继(提交历史无分叉)。 - 命令:
git checkout master git merge dev # master 指针直接跳到 dev 的最新提交
(2)冲突合并(手动解决)
- 场景:
dev
和master
同时修改 同一文件(如 d.txt),合并时冲突。 - 步骤:
触发冲突:
git merge dev # 提示:Auto-merging d.txt CONFLICT (content): Merge conflict in d.txt
编辑冲突文件(以 d.txt 为例):
iiiiiiiiiii 22222222233 33 <<<<<<< HEAD # 当前分支(master)的修改 master123456 ======= # 分隔线 dev654321 # dev 分支的修改 >>>>>>> dev
手动合并为最终内容(如保留两者修改):
iiiiiiiiiii 22222222233 33 master123456 dev654321
标记解决并提交:
git add d.txt git commit -m "解决 d.txt 合并冲突"
4.4 分支的本质:指针与提交链
HEAD
指向当前分支(如ref: refs/heads/master
);- 每个分支指向最新提交;
- 合并时,Git 根据提交历史判断是快进(无分叉)还是冲突(有分叉)。
五、Git Stash:临时保存工作进度
5.1 应用场景
- 紧急修复 bug:当前分支开发未完成,需切换到
hotfix
分支; - 跨分支搬运工作:误在
master
开发,需转移到dev
分支。
5.2 核心命令
(1)保存工作进度
# 保存 工作区 + 暂存区(已跟踪文件)
git stash
# 保存 工作区 + 暂存区 + 未跟踪文件(如新建的 g.txt)
git stash -u
(2)查看与恢复
# 查看所有保存的进度
git stash list
# 输出示例:stash@{0}: WIP on dev: fc48778 dev05d.txt
# 恢复最近一次进度(并删除 stash)
git stash pop
# 恢复指定进度(如 stash@{1}),恢复后不删除 stash
git stash apply stash@{1}
git stash drop stash@{1} # 手动删除
实战流程:
# 1. 在 dev 分支开发,修改 a.txt(未完成),需紧急修复 bug
git stash # 保存修改(a.txt 进入 stash)
git checkout master # 切换到 master 修复 bug
# 2. 修复完成后,切回 dev 恢复工作
git checkout dev
git stash pop # 恢复 a.txt 的修改,继续开发
六、实战串联:从初始化到协作
- 初始化仓库:
git init
,提交初始文件(Hello.java、Test.txt)。 - 文件暂存:用
git add .
暂存修改,git diff
检查变化。 - 分支开发:创建
dev/dev2
,提交新文件(A.txt、B.txt),验证分支隔离性。 - 合并冲突:合并
dev
到master
,解决d.txt
冲突,理解快进与冲突合并的差异。 - 临时工作流:用
git stash
保存未完成工作,修复 bug 后恢复。