跳转至

Git基础

🎯 学习目标

  • 理解版本控制的概念及集中式与分布式的区别
  • 掌握 Git 的核心概念:三棵树模型
  • 完成 Git 安装与配置(包括 SSH Key)
  • 熟练使用 Git 基础命令进行日常开发
  • 掌握 .gitignore 配置方法

1. 版本控制概念

1.1 什么是版本控制

版本控制(Version Control)是一种记录文件内容变化的系统,让你可以在未来查阅特定版本的修订情况。对于软件开发而言,版本控制是管理源代码变更的核心工具。

没有版本控制时的痛点:

Text Only
项目_v1.zip
项目_v2.zip
项目_v2_最终版.zip
项目_v2_最终版_改了bug.zip
项目_v2_最终版_改了bug_真的最终版.zip   ← 你是不是经历过?

1.2 集中式 vs 分布式版本控制

集中式版本控制(SVN、CVS)

Text Only
        ┌─────────────┐
        │  中央服务器   │
        │  (唯一仓库)   │
        └──────┬──────┘
         ┌─────┼─────┐
         ▼     ▼     ▼
       开发者A 开发者B 开发者C
     (工作副本)(工作副本)(工作副本)
  • 所有版本数据存储在中央服务器
  • 必须联网才能提交代码
  • 中央服务器故障 = 全部瘫痪

分布式版本控制(Git、Mercurial)

Text Only
  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │  开发者A  │    │  开发者B  │    │  开发者C  │
  │ 完整仓库  │◄──►│ 完整仓库   │◄──►│ 完整仓库  │
  │ 工作副本  │    │ 工作副本   │    │ 工作副本  │
  └─────┬────┘    └────┬─────┘    └────┬─────┘
        │              │              │
        └──────────────┼──────────────┘
              ┌──────────────┐
              │  远程仓库     │
              │ (GitHub等)   │
              └──────────────┘
  • 每个开发者都拥有完整的版本历史
  • 离线也能提交代码、查看历史
  • 任意一台电脑都是完整备份
  • 支持多种协作方式

💡 总结:Git 是分布式版本控制系统,每个开发者的电脑上都有一个完整的代码仓库。


2. Git 核心概念——三棵树模型

理解 Git 的三棵树模型是掌握 Git 的关键。

Text Only
  ┌─────────────┐    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 文件的四种状态

Git File States

Text Only
  未跟踪(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:

Bash
# 方式一:下载安装包
# 访问 https://git-scm.com/download/win 下载安装

# 方式二:使用 winget
winget install Git.Git

# 方式三:使用 scoop
scoop install git

macOS:

Bash
# 方式一:Xcode Command Line Tools(推荐)
xcode-select --install

# 方式二:Homebrew
brew install git

Linux(Ubuntu/Debian):

Bash
sudo apt update
sudo apt install git

验证安装:

Bash
git --version
# git version 2.43.0

3.2 基本配置(git config)

Git 配置分为三个级别:

级别 参数 配置文件位置 作用范围
系统级 --system /etc/gitconfig 所有用户
用户级 --global ~/.gitconfig 当前用户所有仓库
仓库级 --local .git/config 当前仓库

必须配置(用户信息):

Bash
# 设置用户名和邮箱(每次提交都会记录)
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# 查看配置
git config --list
git config user.name

推荐配置:

Bash
# 设置默认分支名为 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)通信的安全方式,配置后无需每次输入用户名密码。

Bash
# 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

Bash
# 初始化一个新仓库
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

Bash
# 查看当前状态(一定要养成习惯!)
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 输出解读:

Text Only
 M file1.txt     # 已修改,未暂存
M  file2.txt     # 已修改,已暂存
MM file3.txt     # 暂存后又修改了
A  file4.txt     # 新追踪的文件
?? file5.txt     # 未跟踪的文件
 D file6.txt     # 已删除,未暂存

4.3 git commit(提交规范)

Bash
# 基本提交
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 提交规范:

Text Only
<type>(<scope>): <subject>

<body>

<footer>
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(查看历史)

Bash
# 基本查看
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 是最容易误用的命令之一,必须理解三种模式的区别:

Text Only
                    HEAD        暂存区      工作区
git reset --soft     ✅ 移动     ❌ 不变     ❌ 不变
git reset --mixed    ✅ 移动     ✅ 重置     ❌ 不变   ← 默认模式
git reset --hard     ✅ 移动     ✅ 重置     ✅ 重置   ← ⚠️ 危险!
Bash
# --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 通过创建一个新的提交来撤销某个历史提交,不会修改历史。

Bash
# 撤销指定提交
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 就是你的救星。

Bash
# 暂存当前工作进度
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 语法规则

Text Only
# 这是注释

# 忽略指定文件
secret.txt

# 忽略指定类型
*.log
*.tmp
*.pyc

# 忽略目录
node_modules/
__pycache__/
dist/
build/

# 使用通配符
doc/**/*.pdf     # 忽略 doc 下所有 pdf
**/logs          # 忽略所有 logs 目录

# 取反(不忽略)
!important.log   # 即使上面忽略了 *.log,这个文件也要保留

# 只忽略当前目录的文件(不递归)
/config.local

5.2 常见模板

Python 项目:

Text Only
# 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 项目:

Text Only
# 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 项目:

Text Only
# 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

Bash
# 创建全局忽略文件
git config --global core.excludesfile ~/.gitignore_global
Text Only
# ~/.gitignore_global
.DS_Store
Thumbs.db
*.swp
*~
.idea/
.vscode/

5.4 忽略已跟踪的文件

Bash
# .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. 完整工作流程图解

日常开发流程

Text Only
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

流程图

Text Only
  编辑文件 ──► git add ──► git commit ──► git push
     │                         │              │
     │        工作区→暂存区  暂存区→版本库  本地→远程
     ├── git status  (任何时候查看状态)
     ├── git diff    (查看具体改了什么)
     └── git stash   (临时保存,切换分支)

✏️ 练习题

基础练习

  1. 在本地创建一个新的 Git 仓库,完成以下操作:
  2. 创建 README.md 文件并提交
  3. 修改文件后查看 git diff 的输出
  4. 使用 git log --oneline 查看提交历史

  5. 练习 git reset 三种模式:

  6. 创建三次提交
  7. 分别尝试 --soft--mixed--hard 模式回退
  8. 观察工作区和暂存区的变化

  9. 练习 git stash

  10. 在修改了文件但未提交时使用 git stash
  11. 查看 git stash list
  12. 恢复修改并继续工作

  13. 为一个 Python 项目编写 .gitignore 文件。

进阶练习

  1. 尝试使用 git add -p 交互式添加,将一个文件的两处修改分别放入两次提交。

  2. 配置 SSH Key 并成功连接 GitHub。

  3. 使用 Conventional Commits 规范提交至少 5 条不同类型的提交信息。


📋 面试要点

  • Git 是分布式版本控制,每个本地仓库都包含完整历史
  • 三棵树模型:工作区 → 暂存区 → 版本库
  • git reset --soft/mixed/hard 的区别是高频面试题
  • git reset vs git revert:reset 改写历史,revert 新增撤销提交
  • .gitignore 只对未跟踪文件生效,已跟踪文件需 git rm --cached
  • Conventional Commits 提交规范是团队协作的基础

← 上一章:学习指南 | 下一章:分支管理 →