Git详细教程

Git详细教程
空空Git 详细教程
目录
- 什么是 Git
- 核心概念
- 安装与配置
- 创建仓库
- 工作流基础
- 查看历史
- 撤销操作
- 分支与合并
- 远程仓库
- 储藏 (Stash)
- 标签 (Tag)
- 变基 (Rebase)
- 拣选 (Cherry-pick)
- 二分查找 (Bisect)
- Git 工作流
- 常用命令速查表
- 相关工具
- 附录:实战练习
1. 什么是 Git
1.1 版本控制系统
版本控制系统 (VCS) 是一种记录文件变化,以便将来可以查阅特定版本的系统。
1 | 传统做法(无版本控制): |
1.2 Git 的特点
- 分布式:每个开发者都有完整的仓库副本,不依赖中央服务器
- 快照而非差异:Git 把数据看作对小型文件系统的一系列快照
- 本地操作:绝大多数操作只需要本地文件和资源
- 完整性:Git 中所有数据在存储前都计算校验和(SHA-1 哈希),以哈希引用
1.3 Git 的三种状态
Git 有三种主要状态,你的文件可能处于其中之一:
| 状态 | 说明 |
|---|---|
| 已修改 (Modified) | 文件已更改,但尚未存入数据库 |
| 已暂存 (Staged) | 对当前修改的文件做了标记,使之包含在下次提交中 |
| 已提交 (Committed) | 数据已安全地保存在本地数据库中 |
2. 核心概念
2.1 快照 (Snapshot)
每次提交 (commit),Git 会对整个项目文件制作一个快照,并存储这个快照的引用。
1 | 提交历史示意(每个圆圈是一次 commit): |
2.2 SHA-1 哈希
Git 中一切都是用哈希值来索引的,每个提交、文件、目录都有一个 40 位的 SHA-1 哈希:
1 | e83c5163316f89bfbde7d9ab23b2e8e1a9e8e9f3 |
实际使用中,通常取前 7 位即可唯一标识:
1 | e83c516 |
2.3 HEAD、工作树、索引
- HEAD:指向当前所在分支(或某次特定提交)的指针
- 工作树/工作目录:你电脑上实际看到的文件
- 索引/暂存区:下次提交的”蓝图”
2.4 Git 对象模型
Git 是一个内容寻址文件系统,核心是四种对象:
四种 Git 核心底层对象详解
blob(二进制大对象)
- 存储单个文件完整内容,不存文件名、路径,只存文件原始文本 / 二进制数据
- 多个同名文件、不同目录,只要内容完全一样,会共用同一个 blob,实现去重存储
tree(树对象)
- 代表一层目录结构,相当于文件夹快照
- 内部记录:文件名 / 子目录名 + 对应 blob 哈希 / 子 tree 哈希 + 文件权限
- 根 tree 就是一次 commit 对应的项目完整目录
commit(提交对象)
绑定一次完整版本快照,保存版本元数据:
根 tree 哈希、父 commit、作者、提交人、时间、提交备注
每一次
git commit都会生成一个全新 commit 对象
tag(标签对象)
- 轻量 tag 仅存指向 commit 的哈希;
- 附注 tag(annotated tag)是独立对象,可附带版本说明、签名,用于标记发布版本(v1.0、v2.1)
简单来说就是底下这个意思:
blob = 文件内容本体
tree = 文件夹清单(目录结构图,一层文件夹就一个 tree)
commit = 打包一整套目录结构(根 tree)+ 提交备注、作者信息
3. 安装与配置
3.1 安装 Git
Windows:下载 git-scm.com 的安装程序
macOS:
1 | # Homebrew |
**Linux (Debian/Ubuntu)**:
1 | sudo apt-get install git |
**Linux (CentOS/RHEL)**:
1 | sudo yum install git |
3.2 初始配置
安装完成后需要配置用户信息,这些信息会出现在每次提交中:
1 | # 配置用户名 |
配置的三个级别:
4. 创建仓库
4.1 初始化新仓库
1 | # 创建一个新目录并初始化 |
初始化后,Git 会在项目根目录创建一个 .git 隐藏文件夹,包含所有版本控制所需的数据:
1 | my-project/ |
4.2 克隆已有仓库
1 | # 克隆远程仓库到本地 |
5. 工作流基础
5.1 文件生命周期
注:git checkout 在旧版本中同时负责切换分支和恢复文件,
Git 2.23+ 引入了 git switch(切换分支)和 git restore(恢复文件),语义更清晰。
5.2 检查状态
1 | git status |
5.3 添加文件到暂存区
1 | # 添加单个文件 |
git add --patch 交互模式示例:
1 | $ git add -p index.html |
5.4 提交更改
1 | # 提交并指定消息 |
好的提交信息规范:
1 | feat: 添加用户登录功能 |
5.5 移除文件
1 | # 从工作目录和暂存区中删除 |
5.6 移动/重命名文件
1 | # 重命名文件:重命名变更直接进入暂存,不用手动 git add |
6. 查看历史
6.1 git log
1 | # 查看提交历史 |
实用别名配置(给 Git 设置一个全局别名 lg,以后输入 git lg 等价于一长串彩色图形化提交日志,清晰看分支、提交时间、作者):
1 | git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" |
效果类似:
1 | * a1b2c3d - (HEAD -> main) 添加登录页面 (2 days ago) <张三> |
6.2 git diff
1 | # 查看工作目录与暂存区的差异 |
diff 输出解读:
1 | diff --git a/app.js b/app.js |
6.3 查看某次提交
1 | # 查看某次提交的详细信息 |
6.4 追溯文件修改历史
1 | # 查看文件的每一行是谁、在什么时候修改的 |
7. 撤销操作
7.1 撤销场景总览
git restore --staged:仓库覆盖暂存区(把文件从待提交列表移出,修改依旧留在本地,只是取消暂存)
git restore:暂存区覆盖工作目录,撤销本地修改(彻底删掉你还没 add 的所有修改,文件变回上次 add 后的样子)
reset 三种模式区别:
--soft:只移动分支指针,修改保存在暂存区--mixed(默认):指针回退,暂存清空,修改放回工作目录--hard:仓库版本覆盖暂存 + 工作目录,未提交改动全部清除,不可恢复
7.2 撤销工作目录的修改
1 | # 丢弃工作目录中对某个文件的修改(恢复到暂存区或 HEAD 的状态) |
7.3 撤销暂存区的文件
1 | # 将文件从暂存区移出(取消暂存) |
7.4 git reset 详解
1 | # --soft: 只移动 HEAD,保留暂存区和工作目录 |
HEAD~n 语法:
1 | HEAD = 当前提交 |
7.5 git revert
与 reset 不同,revert 通过创建一个新的提交来撤销更改,不会改变历史:
1 | # 撤销某次提交的更改(创建新的提交) |
reset vs revert:
1 | reset(历史被改写): revert(历史保留): |
8. 分支与合并
8.1 什么是分支
分支就是一个指向某次提交的可移动指针:
1 | feature-login(分支) |
8.2 创建和切换分支
1 | # 创建分支 |
8.3 合并分支
1 | # 将 feature-login 合并到当前分支 |
快进合并 (Fast-forward)
当目标分支没有新提交时,Git 只是移动指针:
1 | 合并前: 合并后: |
1 | # 即使可以快进也创建合并提交 |
三方合并 (Three-way merge)
当两个分支都有新提交时,Git 会创建一个新的合并提交:
1 | 合并前: 合并后: |
8.4 合并冲突
当两个分支修改了同一文件的同一部分时,就会产生冲突:
1 | $ git merge feature-login |
冲突文件的内容:
1 | <<<<<<< HEAD |
解决冲突的步骤:
1 | # 1. 查看哪些文件有冲突 |
8.5 删除分支
1 | # 删除已合并的本地分支:Git 会做校验:feature-login 的所有提交已经全部合并到当前所在分支(比如 main),分支没有遗留未合并的代码,才允许删除。 |
8.6 分支策略示例
1 | main 分支(稳定,用于发布) |
9. 远程仓库
9.1 远程仓库概念
远程仓库是托管在互联网或网络上的项目版本库。
9.2 管理远程仓库
1 | # 查看远程仓库 |
9.3 拉取与推送
1 | # 推送本地分支到远程 |
fetch vs pull:
1 | git fetch(安全,只下载不合并): |
fetch + merge(pull) vs fetch + rebase:
操作前:
1 | 远程 origin/main:A ← B ← E |
fetch + merge 效果
1 | 远程 origin/main:A ← B ← E |
特点:历史分叉,多出一条合并提交 M,原有 C/D 提交哈希不变
fetch + rebase 效果
1 | 远程 origin/main:A ← B ← E |
特点:无分叉、无合并提交,C、D 被重生成全新提交 C’、D’,提交哈希改变,历史是一条直线
每次将代码提交到远程前需要先拉取一下解决冲突后再提交,具体是使用merge还是rebase看项目需要。
本地个人分支拉最新代码:用 rebase(保持历史干净)
功能分支合并到公共主干 main/develop:用 merge(团队安全、可追溯)
9.4 推送到远程的完整示例
1 | # 1. 初始化本地仓库 |
10. 储藏 (Stash)
暂存当前工作进度,让你可以切换到其他工作而不必提交:
1 | 正常工作到一半,突然需要切换到其他分支修复 bug: |
常用命令
1 | # 储藏当前修改(包括已暂存的文件) |
11. 标签 (Tag)
标签用于标记特定版本(如发布版本 v1.0.0):
11.1 两种标签
11.2 常用命令
1 | # 创建轻量标签 |
12. 变基 (Rebase)
变基(Rebase)是将一系列提交按照原有次序应用到另一个分支上,产生更整洁的提交历史。
12.1 rebase vs merge
1 | 场景:feature 分支从 main 的 C2 分出,main 已经推进到 C4 |
12.2 交互式变基 (Interactive Rebase)
1 | # 变基到另一个分支(把你当前所在分支的所有提交,从原来分叉的位置拆下来,粘贴到 main 分支最新提交的后面,让提交历史变成一条直线) |
squash 示例——将多个小提交合并为一个:
1 | 编辑前: |
12.3 变基冲突
1 | # 变基过程中遇到冲突 |
12.4 黄金法则
1 | ⚠️ 不要在公共分支(已推送到远程且有其他人基于此工作的分支)上使用 rebase! |
13. 拣选 (Cherry-pick)
将某个提交单独应用到当前分支:
1 | # 拣选单个提交 |
使用场景:
1 | main: ○ ← ○ ← ○ ← ●(修复了关键bug) |
14. 二分查找 (Bisect)
场景:
现在代码有 Bug,但项目已经几十上百次提交,你根本不知道是哪一次改错导致的。
一个个手动回退测试太慢,
bisect用二分法不断折半缩小范围,最快几次就能锁定出问题的那一个提交。
用二分查找法定位引入 bug 的提交:
1 | # 开始二分查找 |
自动化 bisect:
1 | # 使用脚本自动测试 |
15. Git 工作流
15.1 集中式工作流
最简单的模式,所有人直接在 main 分支上工作:
1 | main: ○ ← ○ ← ○ ← ● ← ● ← ● |
适用场景:个人项目或小型团队,但容易产生冲突。
15.2 功能分支工作流 (GitHub Flow)
每个新功能/修复在单独的分支上开发,完成后通过 Pull Request 合并:
1 | main: |
步骤:
1 | # 1. 从 main 创建功能分支 |
15.3 Git Flow
更严格的分支模型,适合有明确发布周期的项目:
- main:生产就绪的代码,每次提交都是一个发布版本
- develop:集成分支,最新的开发成果
- **feature/***:从 develop 分出,完成后合并回 develop
- **release/***:从 develop 分出,准备发布,修 bug 后合并到 main 和 develop
- **hotfix/***:从 main 分出,紧急修复,合并到 main 和 develop
上面这套是标准 GitFlow 工作流,我按从上到下顺序,讲清每个分支怎么创建、从哪切、什么时候合并。
先梳理层级关系:
main:线上稳定发布分支,永远可上线develop:开发主分支,所有新功能汇总于此feature/*:单独需求功能分支,从 develop 分出release/v1.0:版本预发布分支,从 develop 分出hotfix/*:线上紧急 bug 修复分支,从 main 分出
一、develop 开发分支(初始化只做一次)
首次仓库只有 main,创建 develop:
1 | # 切到main |
二、feature/xxx 功能分支(做新需求时创建)
创建规则:从 develop 分支切出来
1 | # 1. 先切回开发主分支,保证代码最新 |
功能完成后合并流程
- 提 PR/MR 合并进
develop - 合并完成,删除本地 + 远程 feature 分支
1 | # 删本地 |
三、release/v1.0 版本发布分支(开发完毕准备上线)
创建规则:从 develop 分出
当 develop 上所有本次迭代功能都开发完成,准备打包上线时新建 release 分支:
1 | # 1. 更新develop |
release 分支作用
只改版本号、修复小 bug,不新增大功能;测试修复完后:
- 合并到
main(打上版本标签,正式上线) - 同时合并回
develop(把修复的 bug 同步给开发分支) - 双分支合并完成后,删除 release 分支
四、hotfix/critical-bug 热修复分支(线上紧急故障)
创建规则:从 main 稳定分支切出来
线上 main 出现严重 bug,不能等下一轮迭代,立刻从线上 main 拉出修复分支:
1 | # 1. 切换到线上稳定分支main |
bug 修复完成后合并流程
- 修复代码提交,合并进
main,重新上线并打版本 tag - 必须同步合并进
develop,避免下一轮开发又出现这个 bug - 两边全部合并完成后,删除 hotfix 分支
核心区分总结
| 分支类型 | 从哪个分支创建 | 合并目标分支 | 使用场景 |
|---|---|---|---|
| feature/xxx | develop | develop | 日常新功能开发 |
| release/vx.x | develop | main、develop | 迭代版本整体测试、发布 |
| hotfix/xxx | main | main、develop | 线上紧急 bug 快速修复 |
| main | 初始仓库 | 仅接收 release/hotfix 合并 | 线上稳定代码,生产环境 |
| develop | main(仅一次) | 汇总所有 feature、接收 release/hotfix 修复 | 日常开发汇总 |
15.4 分支策略比较
| 工作流 | 分支数 | 复杂度 | 适用场景 |
|---|---|---|---|
| 集中式 | 1 | 低 | 个人项目 |
| GitHub Flow | 2+ | 中 | 持续部署的 Web 项目 |
| Git Flow | 5+ | 高 | 有明确版本发布周期的项目 |
| GitLab Flow | 3+ | 中 | 需要环境分支(staging/production)的项目 |
16. 常用命令速查表
16.1 基础操作
| 命令 | 说明 |
|---|---|
git init |
初始化仓库 |
git clone <url> |
克隆仓库 |
git status |
查看状态 |
git add <file> |
暂存文件 |
git add . |
暂存所有文件 |
git commit -m "msg" |
提交 |
git commit --amend |
修改上次提交 |
git log |
查看历史 |
git diff |
查看差异 |
16.2 分支操作
| 命令 | 说明 |
|---|---|
git branch |
查看分支 |
git branch <name> |
创建分支 |
git switch <name> |
切换分支 |
git switch -c <name> |
创建并切换 |
git merge <branch> |
合并分支 |
git branch -d <name> |
删除分支 |
git branch -D <name> |
强制删除分支 |
16.3 远程操作
| 命令 | 说明 |
|---|---|
git remote -v |
查看远程仓库 |
git remote add <name> <url> |
添加远程仓库 |
git fetch |
拉取数据 |
git pull |
拉取并合并 |
git push |
推送 |
git push -u origin main |
推送并设置上游 |
git push origin --delete <branch> |
删除远程分支 |
16.4 撤销操作
| 命令 | 说明 |
|---|---|
git restore <file> |
撤销工作区修改 |
git restore --staged <file> |
取消暂存 |
git reset --soft HEAD~1 |
撤销提交,保留暂存 |
git reset --mixed HEAD~1 |
撤销提交和暂存 |
git reset --hard HEAD~1 |
完全撤销提交 |
git revert <commit> |
安全撤销(创建新提交) |
16.5 高级操作
| 命令 | 说明 |
|---|---|
git stash |
储藏修改 |
git stash pop |
恢复储藏 |
git rebase <branch> |
变基 |
git rebase -i HEAD~3 |
交互式变基 |
git cherry-pick <commit> |
拣选提交 |
git tag -a v1.0 -m "msg" |
创建附注标签 |
git bisect start |
二分查找 |
git blame <file> |
查看文件修改历史 |
16.6 .gitignore 常用模板
1 | # 依赖 |
17.相关工具
我们也可以用一些git可视化工具或者直接在idea里操作git,下面是我看过的一些还行的教程:
git小乌龟使用教程:
git可视化工具小乌龟安装&使用_git小乌龟-CSDN博客
TortoiseGit-使用教程(图文详细版) - 吴川华仔 - 博客园
idea操作git:
附录:实战练习
练习 1:基本工作流
1 | # 1. 创建项目 |
练习 2:分支操作
1 | # 1. 创建并切换到新分支 |
练习 3:交互式变基
1 | # 1. 创建几个"脏"提交 |
提示:学习 Git 最好的方式就是多动手。建议创建一个测试仓库,把本文档中的命令都亲自执行一遍,观察每一步的输出和变化。









