Skip to content

第一阶段:Git 基础入门


一、Git 概念与安装

1.1 什么是版本控制?

版本控制(Version Control)是一种记录文件内容变化,以便将来查阅特定版本的系统。

为什么需要版本控制?

  • 追踪每一次修改的内容、时间、作者
  • 随时回退到任意历史版本
  • 多人协作时避免互相覆盖
  • 并行开发不同功能而互不干扰

没有版本控制时的痛点:

项目_v1.zip
项目_v2_最终版.zip
项目_v2_最终版_改改改.zip
项目_v2_最终版_老板说再改改.zip    ← 是不是很熟悉?

1.2 Git 与 SVN 的区别

特性Git(分布式)SVN(集中式)
架构每个开发者都有完整仓库副本只有一个中央服务器
离线工作支持,几乎所有操作都在本地完成不支持,大部分操作需联网
速度极快(本地操作)较慢(依赖网络)
分支轻量级,创建/切换/合并都非常快重量级,分支是目录拷贝
数据安全每个副本都是完整备份中央服务器故障可能丢失数据
存储方式快照(snapshot)差异(delta)

核心区别一句话总结: Git 是分布式的,每个人本地都有完整历史;SVN 是集中式的,所有人依赖同一台服务器。

1.3 Git 的三个区域(核心概念)

这是理解 Git 最关键的概念,务必牢记。

┌──────────────┐     git add     ┌──────────────┐    git commit    ┌──────────────┐
│              │  ──────────────> │              │  ──────────────> │              │
│   工作区      │                 │   暂存区      │                  │   本地仓库    │
│ Working Dir  │                 │ Staging Area │                  │  Repository  │
│              │  <────────────  │              │  <────────────   │              │
│  (你编辑的   │   git restore   │ (准备提交的   │   git reset      │ (已提交的    │
│   文件目录)  │                 │   修改快照)   │                  │   历史记录)  │
└──────────────┘                 └──────────────┘                  └──────────────┘

                                                                    git push


                                                                  ┌──────────────┐
                                                                  │   远程仓库    │
                                                                  │    Remote    │
                                                                  └──────────────┘

三个区域详解:

区域说明类比
工作区(Working Directory)你在电脑上实际看到和编辑的文件目录你的书桌
暂存区(Staging Area / Index)临时存放你准备提交的修改,像一个"购物车"收银台前的购物篮
本地仓库(Repository / .git存放所有已提交的历史版本数据仓库货架

为什么需要暂存区?

暂存区让你可以精细控制每次提交的内容。比如你修改了 5 个文件,但只想先提交其中 2 个,就可以只 git add 这 2 个文件。

1.4 安装与初始配置

安装 Git:

bash
# Ubuntu / Debian
sudo apt-get install git

# CentOS / RHEL
sudo yum install git

# macOS(通常自带,也可用 Homebrew)
brew install git

# 验证安装
git --version

初始配置(安装后必做):

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

# 查看当前配置
git config --list

# 查看某项配置
git config user.name

配置的三个级别:

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

优先级:仓库级 > 用户级 > 系统级(就近原则)

推荐的额外配置:

bash
# 设置默认分支名为 main(新版推荐)
git config --global init.defaultBranch main

# 设置默认编辑器
git config --global core.editor "vim"

# 开启颜色显示
git config --global color.ui auto

# 设置换行符处理(跨平台协作时很重要)
# Linux/Mac
git config --global core.autocrlf input
# Windows
git config --global core.autocrlf true

二、基本操作

2.1 git init — 初始化仓库

将当前目录变成一个 Git 仓库。

bash
# 创建一个新项目并初始化
mkdir my-project
cd my-project
git init

执行后会在当前目录下生成一个隐藏的 .git 文件夹,这就是本地仓库,所有版本信息都存储在其中。

bash
# 查看 .git 目录结构
ls -la .git/
# 主要内容:
#   HEAD        — 指向当前所在分支
#   config      — 仓库级配置
#   objects/    — 存储所有数据内容(blob、tree、commit)
#   refs/       — 存储分支和标签的指针

2.2 git clone — 克隆远程仓库

从远程获取一个完整的仓库副本。

bash
# HTTPS 方式克隆
git clone https://github.com/user/repo.git

# SSH 方式克隆(推荐,需提前配置 SSH Key)
git clone git@github.com:user/repo.git

# 克隆到指定目录
git clone https://github.com/user/repo.git my-folder

# 只克隆最近一次提交(浅克隆,适用于大型仓库)
git clone --depth 1 https://github.com/user/repo.git

2.3 git add — 将文件添加到暂存区

bash
# 添加单个文件
git add README.md

# 添加多个文件
git add file1.txt file2.txt

# 添加当前目录下所有变更
git add .

# 添加所有变更(包括删除的文件)
git add -A

# 交互式添加(按块选择要暂存的内容)
git add -p

git add . vs git add -A 的区别:

命令新文件修改的文件删除的文件
git add .✅(Git 2.x)
git add -A

在 Git 2.x 中两者几乎等价,但 git add -A 对整个仓库生效,git add . 只对当前目录及子目录生效。

2.4 git commit — 提交更改

将暂存区的内容保存为一个版本快照。

bash
# 标准提交
git commit -m "描述本次修改的内容"

# 跳过暂存区,直接提交所有已跟踪文件的修改(不包含新文件)
git commit -a -m "修改说明"

# 修改最近一次提交(注意:不要修改已推送的提交)
git commit --amend -m "新的提交信息"

# 提交空信息(不推荐)会打开编辑器让你写
git commit

好的提交信息格式:

<type>: <简短描述>

<详细说明(可选)>

# 示例:
feat: 添加用户登录功能
fix: 修复首页加载缓慢的问题
docs: 更新 README 安装说明
refactor: 重构数据库连接池逻辑

2.5 git status — 查看当前状态

bash
git status

# 精简输出
git status -s
# 输出示例:
#  M README.md       — 已修改,未暂存
# M  app.js          — 已修改,已暂存
# A  new-file.txt    — 新文件,已暂存
# ?? untracked.txt   — 未跟踪的文件
# MM both.js         — 暂存后又修改了

状态标记说明:

标记含义
??未跟踪(Untracked)
A新添加到暂存区
M(左列)已修改并暂存
M(右列)已修改但未暂存
D已删除
R重命名

2.6 git log — 查看提交历史

bash
# 默认输出
git log

# 单行简洁模式(推荐日常使用)
git log --oneline

# 带分支图的日志
git log --oneline --graph --all

# 查看最近 5 条
git log -5

# 查看某个文件的修改历史
git log -- path/to/file

# 按作者筛选
git log --author="张三"

# 按时间范围筛选
git log --since="2024-01-01" --until="2024-06-30"

# 按提交信息搜索
git log --grep="fix"

# 查看每次提交的具体改动
git log -p

# 查看统计信息
git log --stat

推荐配置一个美观的 log 别名:

bash
git config --global alias.lg "log --oneline --graph --all --decorate"
# 之后就可以用 git lg

2.7 git diff — 查看差异

bash
# 工作区 vs 暂存区(未暂存的修改)
git diff

# 暂存区 vs 最新提交(已暂存但未提交的修改)
git diff --cached
# 或
git diff --staged

# 工作区 vs 最新提交
git diff HEAD

# 比较两个提交
git diff abc1234 def5678

# 比较两个分支
git diff main feature-branch

# 只查看哪些文件有变化
git diff --name-only

# 查看某个文件的差异
git diff -- path/to/file

理解 diff 输出:

diff
diff --git a/hello.txt b/hello.txt
index 5c1b149..f2e4113 100644
--- a/hello.txt                    ← 修改前
+++ b/hello.txt                    ← 修改后
@@ -1,3 +1,4 @@                   ← 位置信息:从第1行开始,原来3行,现在4行
 Hello World                       ← 未修改的行(上下文)
-This is old line                  ← 删除的行(红色)
+This is new line                  ← 新增的行(绿色)
+Another new line                  ← 新增的行(绿色)
 Goodbye                           ← 未修改的行(上下文)

2.8 .gitignore — 忽略文件配置

在项目根目录创建 .gitignore 文件,指定哪些文件/目录不需要纳入版本管理。

gitignore
# 忽略所有 .log 文件
*.log

# 忽略 node_modules 目录
node_modules/

# 忽略构建输出
dist/
build/

# 忽略环境配置文件
.env
.env.local

# 忽略 IDE 配置
.idea/
.vscode/
*.swp

# 忽略操作系统文件
.DS_Store
Thumbs.db

# 不忽略某个特定文件(取反)
!important.log

.gitignore 规则语法:

语法说明示例
#注释# 这是注释
*匹配任意字符*.log
?匹配单个字符file?.txt
**匹配多级目录**/logs
/ 开头只匹配根目录/build
/ 结尾只匹配目录logs/
!取反(不忽略)!keep.log

注意: 已被 Git 跟踪的文件不会被 .gitignore 忽略。需要先取消跟踪:

bash
# 取消跟踪但保留文件
git rm --cached filename

# 取消跟踪整个目录
git rm -r --cached directory/

三、实践 Demo

Demo 1:从零创建一个 Git 项目

bash
# ① 创建项目目录
mkdir git-demo && cd git-demo

# ② 初始化 Git 仓库
git init

# ③ 创建文件
echo "# Git Demo Project" > README.md
echo "console.log('Hello Git!');" > app.js

# ④ 查看状态 — 此时两个文件都是 Untracked
git status

# ⑤ 添加到暂存区
git add README.md app.js

# ⑥ 查看状态 — 此时文件变为 Staged
git status

# ⑦ 提交
git commit -m "feat: 初始化项目,添加 README 和 app.js"

# ⑧ 查看提交历史
git log --oneline

Demo 2:体验修改 → 暂存 → 提交的完整流程

bash
# ① 修改文件
echo "console.log('New feature');" >> app.js

# ② 查看差异(工作区 vs 上次提交)
git diff

# ③ 添加到暂存区
git add app.js

# ④ 查看暂存区的差异
git diff --cached

# ⑤ 再次修改同一文件(注意:这次修改不在暂存区中)
echo "// TODO: add more" >> app.js

# ⑥ 查看状态 — app.js 同时出现在 staged 和 unstaged 中
git status

# ⑦ 查看未暂存的差异
git diff

# ⑧ 只提交暂存区中的内容
git commit -m "feat: 添加新功能输出"

# ⑨ 查看状态 — 还有一个未暂存的修改
git status

Demo 3:使用 .gitignore

bash
# ① 创建一些应该忽略的文件
mkdir logs node_modules
echo "error at 10:00" > logs/error.log
echo "{}" > node_modules/package.json
echo "SECRET_KEY=abc123" > .env

# ② 查看状态 — 这些文件都显示为 Untracked
git status

# ③ 创建 .gitignore
cat > .gitignore << 'EOF'
logs/
node_modules/
.env
EOF

# ④ 再次查看状态 — 被忽略的文件不再出现
git status

# ⑤ 提交 .gitignore
git add .gitignore
git commit -m "chore: 添加 .gitignore 配置"

Demo 4:查看和理解提交历史

bash
# 多做几次修改和提交,积累一些历史
echo "v1.0" > version.txt && git add . && git commit -m "feat: 添加版本文件"
echo "v1.1" > version.txt && git add . && git commit -m "fix: 更新版本号"
echo "v2.0" > version.txt && git add . && git commit -m "feat: 升级到 v2.0"

# 查看简洁历史
git log --oneline

# 查看详细历史(含每次改动)
git log -p

# 查看统计信息
git log --stat

# 查看某个文件的修改历史
git log --oneline -- version.txt

# 查看某次提交的具体内容(用上面 log 中显示的 hash)
git show <commit-hash>

四、常见问题 Q&A

Q1:git add .git add -A 有什么区别?

A: 在 Git 2.x 中几乎没有区别。微小差异是 git add . 只处理当前目录及其子目录,而 git add -A 处理整个仓库。如果你在项目根目录执行,两者完全等价。


Q2:提交后发现提交信息写错了怎么办?

A: 使用 --amend 修改最近一次提交:

bash
git commit --amend -m "正确的提交信息"

⚠️ 注意: 如果该提交已经推送到远程仓库,不要使用 --amend,否则会导致历史不一致。


Q3:已经 git add 的文件想撤回怎么办?

A: 使用 git restore --staged(推荐)或 git reset HEAD

bash
# 推荐方式(Git 2.23+)
git restore --staged filename

# 旧方式
git reset HEAD filename

文件会从暂存区移回工作区,修改内容不会丢失。


Q4:不小心修改了文件,想恢复到上次提交的状态?

A:

bash
# 推荐方式(Git 2.23+)
git restore filename

# 旧方式
git checkout -- filename

⚠️ 警告: 此操作不可逆!工作区的修改会被永久丢弃。


Q5:.gitignore 不生效,已跟踪的文件无法忽略?

A: .gitignore 只能忽略尚未被 Git 跟踪的文件。如果文件已被跟踪,需要先移除跟踪:

bash
# 取消跟踪但保留本地文件
git rm --cached filename

# 然后将其添加到 .gitignore
echo "filename" >> .gitignore

# 提交这两个变更
git add .gitignore
git commit -m "chore: 停止跟踪 filename"

Q6:git initgit clone 的区别?

A:

场景使用的命令
从零创建一个新项目git init
获取一个已存在的远程项目git clone <url>

git clone 本质上做了这些事:mkdirgit initgit remote addgit fetchgit checkout


Q7:每次提交的 hash 值是怎么来的?

A: Git 使用 SHA-1 算法对以下信息计算哈希值:

  • 提交内容(文件快照)
  • 父提交的 hash
  • 作者信息和时间
  • 提交者信息和时间
  • 提交信息

所以即使内容相同,不同时间的提交 hash 也不同。hash 值保证了数据完整性——任何篡改都会导致 hash 变化。


Q8:git diff 没有输出是怎么回事?

A: 可能的原因:

  1. 没有修改任何文件 — 工作区和暂存区一致
  2. 修改已暂存git diff 只比较工作区和暂存区,已暂存的修改用 git diff --cached 查看
  3. 文件是二进制文件 — Git 默认不显示二进制差异
bash
# 查看完整差异链路
git diff            # 工作区 vs 暂存区
git diff --cached   # 暂存区 vs 最新提交
git diff HEAD       # 工作区 vs 最新提交

Q9:git commit -a -m "msg" 为什么有时候不能提交新文件?

A: -a 参数只会自动暂存已跟踪文件的修改,不会添加未跟踪(Untracked)的新文件。新文件必须先用 git add 手动添加。


Q10:如何查看某一行代码是谁在什么时候写的?

A: 使用 git blame

bash
# 查看某文件每一行的作者和提交信息
git blame filename

# 查看指定行范围
git blame -L 10,20 filename

五、速查表

┌─────────────────────────────────────────────────────────┐
│                    Git 基础命令速查                       │
├──────────────────────┬──────────────────────────────────┤
│ git init             │ 初始化仓库                        │
│ git clone <url>      │ 克隆远程仓库                      │
│ git add <file>       │ 添加到暂存区                      │
│ git add .            │ 添加所有变更                      │
│ git commit -m "msg"  │ 提交到本地仓库                    │
│ git status           │ 查看当前状态                      │
│ git status -s        │ 精简状态输出                      │
│ git log --oneline    │ 查看简洁历史                      │
│ git diff             │ 查看未暂存的修改                   │
│ git diff --cached    │ 查看已暂存的修改                   │
│ git restore <file>   │ 撤销工作区修改                    │
│ git restore --staged │ 从暂存区撤回                      │
│ git rm --cached      │ 取消跟踪(保留文件)               │
│ git blame <file>     │ 查看每行的修改记录                 │
└──────────────────────┴──────────────────────────────────┘

六、学习检查清单

完成以下任务,确认你已掌握本阶段内容:

  • [ ] 能说出 Git 和 SVN 的 3 个核心区别
  • [ ] 能画出工作区、暂存区、本地仓库的关系图
  • [ ] 能独立完成 init → add → commit 的完整流程
  • [ ] 能使用 git status 判断文件处于哪个状态
  • [ ] 能使用 git diff 的三种形式查看不同阶段的差异
  • [ ] 能使用 git log 查看和筛选提交历史
  • [ ] 能正确编写 .gitignore 文件
  • [ ] 能处理"已跟踪文件无法被 .gitignore 忽略"的问题