Git基础¶
🎯 学习目标¶
- 理解版本控制的概念及集中式与分布式的区别
- 掌握 Git 的核心概念:三棵树模型
- 完成 Git 安装与配置(包括 SSH Key)
- 熟练使用 Git 基础命令进行日常开发
- 掌握
.gitignore配置方法
1. 版本控制概念¶
1.1 什么是版本控制¶
版本控制(Version Control)是一种记录文件内容变化的系统,让你可以在未来查阅特定版本的修订情况。对于软件开发而言,版本控制是管理源代码变更的核心工具。
没有版本控制时的痛点:
1.2 集中式 vs 分布式版本控制¶
集中式版本控制(SVN、CVS)¶
┌─────────────┐
│ 中央服务器 │
│ (唯一仓库) │
└──────┬──────┘
┌─────┼─────┐
▼ ▼ ▼
开发者A 开发者B 开发者C
(工作副本)(工作副本)(工作副本)
- 所有版本数据存储在中央服务器
- 必须联网才能提交代码
- 中央服务器故障 = 全部瘫痪
分布式版本控制(Git、Mercurial)¶
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 开发者A │ │ 开发者B │ │ 开发者C │
│ 完整仓库 │◄──►│ 完整仓库 │◄──►│ 完整仓库 │
│ 工作副本 │ │ 工作副本 │ │ 工作副本 │
└─────┬────┘ └────┬─────┘ └────┬─────┘
│ │ │
└──────────────┼──────────────┘
▼
┌──────────────┐
│ 远程仓库 │
│ (GitHub等) │
└──────────────┘
- 每个开发者都拥有完整的版本历史
- 离线也能提交代码、查看历史
- 任意一台电脑都是完整备份
- 支持多种协作方式
💡 总结:Git 是分布式版本控制系统,每个开发者的电脑上都有一个完整的代码仓库。
2. Git 核心概念——三棵树模型¶
理解 Git 的三棵树模型是掌握 Git 的关键。
┌─────────────┐ git add ┌─────────────┐ git commit ┌─────────────┐
│ 工作区 │ ──────────► │ 暂存区 │ ──────────► │ 版本库 │
│ Working Dir │ │ Staging Area │ │ Repository │
│ │ ◄────────── │ (Index) │ ◄────────── │ (.git) │
└─────────────┘ git restore └─────────────┘ git restore └─────────────┘
--staged
💡
git restore是 Git 2.23+ 引入的新命令。旧版本中对应的命令是git checkout -- <file>(恢复工作区)和git reset HEAD <file>(取消暂存)。
2.1 工作区(Working Directory)¶
你实际编辑文件的目录,就是你在文件管理器或编辑器中看到的那些文件。
2.2 暂存区(Staging Area / Index)¶
一个中间区域,用于准备下一次提交的内容。你可以选择性地将工作区的修改添加到暂存区,这意味着你可以将一次大的修改拆分为多个小的、有意义的提交。
2.3 版本库(Repository)¶
Git 用来保存项目元数据和对象数据库的地方(.git 目录)。每次 git commit 都会在这里创建一个快照。
2.4 文件的四种状态¶
未跟踪(Untracked) ──── git add ────► 已暂存(Staged)
▲ │
│ git commit
│ │
│ ▼
已修改(Modified) ◄── 编辑文件 ──── 未修改(Unmodified)
│ ▲
└────────── git add ────────────► 已暂存(Staged) ─── git commit ──► 未修改
- Untracked(未跟踪):新创建的文件,还没有被 Git 管理
- Unmodified(未修改):已被 Git 管理,且与上次提交一致
- Modified(已修改):已被 Git 管理,但内容有变化
- Staged(已暂存):已加入暂存区,等待提交
3. 安装与配置¶
3.1 安装 Git¶
Windows:
# 方式一:下载安装包
# 访问 https://git-scm.com/download/win 下载安装
# 方式二:使用 winget
winget install Git.Git
# 方式三:使用 scoop
scoop install git
macOS:
Linux(Ubuntu/Debian):
验证安装:
3.2 基本配置(git config)¶
Git 配置分为三个级别:
| 级别 | 参数 | 配置文件位置 | 作用范围 |
|---|---|---|---|
| 系统级 | --system | /etc/gitconfig | 所有用户 |
| 用户级 | --global | ~/.gitconfig | 当前用户所有仓库 |
| 仓库级 | --local | .git/config | 当前仓库 |
必须配置(用户信息):
# 设置用户名和邮箱(每次提交都会记录)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 查看配置
git config --list
git config user.name
推荐配置:
# 设置默认分支名为 main
git config --global init.defaultBranch main
# 设置默认编辑器
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# 处理换行符(跨平台协作必备)
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # macOS/Linux
# 启用颜色显示
git config --global color.ui auto
# 设置中文文件名正确显示
git config --global core.quotepath false
3.3 SSH Key 配置¶
SSH Key 是与远程仓库(GitHub/GitLab)通信的安全方式,配置后无需每次输入用户名密码。
# 1. 生成 SSH Key
ssh-keygen -t ed25519 -C "your.email@example.com"
# 一路回车使用默认设置(或设置密码短语更安全)
# 2. 查看公钥
cat ~/.ssh/id_ed25519.pub
# 3. 将公钥添加到 GitHub
# Settings → SSH and GPG keys → New SSH key → 粘贴公钥
# 4. 测试连接
ssh -T git@github.com
# Hi username! You've successfully authenticated...
# 5. 启动 ssh-agent 并添加密钥
eval "$(ssh-agent -s)" # $()命令替换:执行命令并获取输出
ssh-add ~/.ssh/id_ed25519
4. 基础命令详解¶
4.1 git init / git clone¶
# 初始化一个新仓库
mkdir my-project
cd my-project
git init
# 输出:Initialized empty Git repository in .../my-project/.git/
# 克隆远程仓库
git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git # SSH方式(推荐)
git clone https://github.com/user/repo.git my-dir # 指定目录名
git clone --depth 1 https://github.com/user/repo.git # 浅克隆(只获取最新提交)
4.2 git add / git status / git diff¶
# 查看当前状态(一定要养成习惯!)
git status
git status -s # 简洁模式
# 添加文件到暂存区
git add file.txt # 添加指定文件
git add dir/ # 添加整个目录
git add . # 添加当前目录所有变更
git add -A # 添加所有变更(包括删除)
git add -p # 交互式添加(选择部分修改,高级用法)
# 查看差异
git diff # 工作区 vs 暂存区
git diff --staged # 暂存区 vs 最新提交(同 --cached)
git diff HEAD # 工作区 vs 最新提交
git diff branch1 branch2 # 比较两个分支
git diff commit1 commit2 # 比较两个提交
git status -s 输出解读:
M file1.txt # 已修改,未暂存
M file2.txt # 已修改,已暂存
MM file3.txt # 暂存后又修改了
A file4.txt # 新追踪的文件
?? file5.txt # 未跟踪的文件
D file6.txt # 已删除,未暂存
4.3 git commit(提交规范)¶
# 基本提交
git commit -m "提交信息"
# 打开编辑器写详细提交信息
git commit
# 跳过暂存区直接提交(仅限已跟踪的文件)
git commit -a -m "修改已跟踪文件"
# 修改最后一次提交(⚠️ 会改变历史)
git commit --amend -m "更正的提交信息"
git commit --amend --no-edit # 仅补充文件,不改提交信息
# 空提交(用于触发 CI)
git commit --allow-empty -m "trigger CI"
Conventional Commits 提交规范:
| Type | 说明 | 示例 |
|---|---|---|
feat | 新功能 | feat(auth): 添加微信登录 |
fix | Bug修复 | fix(api): 修复空指针异常 |
docs | 文档修改 | docs: 更新README |
style | 格式调整(不影响逻辑) | style: 统一缩进格式 |
refactor | 代码重构 | refactor: 提取公共方法 |
perf | 性能优化 | perf(query): 添加索引优化查询 |
test | 测试相关 | test: 添加用户模块单元测试 |
chore | 构建/工具相关 | chore: 升级依赖版本 |
ci | CI/CD相关 | ci: 添加GitHub Actions配置 |
revert | 回退 | revert: 撤回feat(auth)提交 |
💡 推荐工具:使用 commitizen 交互式生成规范提交信息。
4.4 git log(查看历史)¶
# 基本查看
git log
# 常用参数组合
git log --oneline # 单行显示
git log --oneline --graph --all # 图形化显示所有分支(最常用✨)
git log --oneline -10 # 显示最近10条
git log --author="name" # 按作者过滤
git log --since="2024-01-01" # 按日期过滤
git log --grep="fix" # 按提交信息过滤
git log -- path/to/file # 查看某文件的修改历史
git log -p # 显示每次提交的diff
git log --stat # 显示文件修改统计
# 美化输出
git log --pretty=format:"%h %an %ar : %s"
# 输出:a1b2c3d John 2 hours ago : feat: add login page
# 推荐别名
git log --oneline --graph --all --decorate
4.5 git reset(重置) ⚠️¶
git reset 是最容易误用的命令之一,必须理解三种模式的区别:
HEAD 暂存区 工作区
git reset --soft ✅ 移动 ❌ 不变 ❌ 不变
git reset --mixed ✅ 移动 ✅ 重置 ❌ 不变 ← 默认模式
git reset --hard ✅ 移动 ✅ 重置 ✅ 重置 ← ⚠️ 危险!
# --soft:只移动 HEAD 指针,暂存区和工作区不变
# 场景:想修改最近几次提交的内容
git reset --soft HEAD~1
# --mixed(默认):移动 HEAD 并重置暂存区,工作区不变
# 场景:取消 git add,但保留文件修改
git reset HEAD~1
git reset HEAD file.txt # 取消单个文件的暂存
# --hard:三者全部重置 ⚠️ 工作区修改会丢失!
# 场景:彻底放弃最近的修改
git reset --hard HEAD~1
git reset --hard origin/main # 强制与远程同步
⚠️ 警告:
git reset --hard会永久删除未提交的修改!使用前请三思。可以用git stash先保存。
4.6 git revert¶
与 reset 不同,revert 通过创建一个新的提交来撤销某个历史提交,不会修改历史。
# 撤销指定提交
git revert <commit-hash>
# 撤销最近一次提交
git revert HEAD
# 撤销多个连续提交
git revert HEAD~3..HEAD
# 撤销但不自动提交(先查看效果)
git revert --no-commit <commit-hash>
reset vs revert 对比:
| 特性 | git reset | git revert |
|---|---|---|
| 修改历史 | 是(改写历史) | 否(新增撤销提交) |
| 适用场景 | 本地未推送的提交 | 已推送到远程的提交 |
| 安全性 | 可能丢失数据 | 安全,保留完整历史 |
| 协作影响 | 可能影响他人 | 不影响他人 |
4.7 git stash(暂存工作进度)¶
当你正在开发一个功能,突然需要切换到另一个分支修复 Bug 时,git stash 就是你的救星。
# 暂存当前工作进度
git stash
git stash push -m "正在开发用户模块" # 添加描述信息(注意:旧版 git stash save 已弃用)
git stash -u # 包含未跟踪文件
git stash -a # 包含被忽略的文件
# 查看暂存列表
git stash list
# stash@{0}: On feature: 正在开发用户模块
# stash@{1}: WIP on main: a1b2c3d fix: typo
# 恢复暂存
git stash pop # 恢复最近的暂存,并删除该记录
git stash apply # 恢复最近的暂存,保留记录
git stash apply stash@{1} # 恢复指定暂存
# 删除暂存
git stash drop stash@{0} # 删除指定暂存
git stash clear # 清空所有暂存
# 从暂存创建新分支(避免恢复时冲突)
git stash branch new-branch stash@{0}
5. .gitignore 配置¶
5.1 语法规则¶
# 这是注释
# 忽略指定文件
secret.txt
# 忽略指定类型
*.log
*.tmp
*.pyc
# 忽略目录
node_modules/
__pycache__/
dist/
build/
# 使用通配符
doc/**/*.pdf # 忽略 doc 下所有 pdf
**/logs # 忽略所有 logs 目录
# 取反(不忽略)
!important.log # 即使上面忽略了 *.log,这个文件也要保留
# 只忽略当前目录的文件(不递归)
/config.local
5.2 常见模板¶
Python 项目:
# Python
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/
.eggs/
*.egg
# 虚拟环境
venv/
.venv/
env/
# IDE
.vscode/
.idea/
*.swp
# 环境变量
.env
.env.local
# 测试覆盖率
htmlcov/
.coverage
.pytest_cache/
Node.js 项目:
# Dependencies
node_modules/
# Build
dist/
build/
.next/
# Environment
.env
.env.local
.env.*.local
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# IDE
.vscode/
.idea/
Java 项目:
# Compiled
*.class
*.jar
*.war
# Build
target/
build/
out/
# IDE
.idea/
*.iml
.settings/
.classpath
.project
# Gradle
.gradle/
gradle-app.setting
# Maven
pom.xml.tag
pom.xml.releaseBackup
5.3 全局 .gitignore¶
5.4 忽略已跟踪的文件¶
# .gitignore 只对未跟踪的文件生效
# 如果文件已被跟踪,需要先删除缓存
git rm --cached file.txt # 从跟踪中移除但保留本地文件
git rm --cached -r directory/ # 移除整个目录的跟踪
# 然后将该文件/目录添加到 .gitignore
echo "file.txt" >> .gitignore
git commit -m "chore: 更新gitignore"
💡 推荐工具:使用 gitignore.io 根据项目类型自动生成
.gitignore文件。
6. 完整工作流程图解¶
日常开发流程¶
1. 拉取最新代码
git pull origin main
2. 创建功能分支
git switch -c feature/login
3. 编写代码...
4. 查看修改状态
git status
git diff
5. 添加到暂存区
git add .
6. 提交
git commit -m "feat(auth): 实现登录页面"
7. 推送到远程
git push origin feature/login
8. 创建 Pull Request / Merge Request
9. Code Review 通过后合并
10. 删除功能分支
git branch -d feature/login
流程图¶
编辑文件 ──► git add ──► git commit ──► git push
│ │ │
│ 工作区→暂存区 暂存区→版本库 本地→远程
│
├── git status (任何时候查看状态)
├── git diff (查看具体改了什么)
└── git stash (临时保存,切换分支)
✏️ 练习题¶
基础练习¶
- 在本地创建一个新的 Git 仓库,完成以下操作:
- 创建
README.md文件并提交 - 修改文件后查看
git diff的输出 -
使用
git log --oneline查看提交历史 -
练习
git reset三种模式: - 创建三次提交
- 分别尝试
--soft、--mixed、--hard模式回退 -
观察工作区和暂存区的变化
-
练习
git stash: - 在修改了文件但未提交时使用
git stash - 查看
git stash list -
恢复修改并继续工作
-
为一个 Python 项目编写
.gitignore文件。
进阶练习¶
-
尝试使用
git add -p交互式添加,将一个文件的两处修改分别放入两次提交。 -
配置 SSH Key 并成功连接 GitHub。
-
使用 Conventional Commits 规范提交至少 5 条不同类型的提交信息。
📋 面试要点¶
- Git 是分布式版本控制,每个本地仓库都包含完整历史
- 三棵树模型:工作区 → 暂存区 → 版本库
git reset --soft/mixed/hard的区别是高频面试题git resetvsgit revert:reset 改写历史,revert 新增撤销提交.gitignore只对未跟踪文件生效,已跟踪文件需git rm --cached- Conventional Commits 提交规范是团队协作的基础
