第55章:Git 基础

第五十五章:Git 基础

55.1 Git 简介

什么是 Git?

想象一下:你写了一篇论文,每天改一点,改了30天。终于有一天,电脑蓝屏了,论文没了,只剩下一个礼拜前的版本。

或者这样:你和同事一起写代码,他把你写的代码覆盖了,还没法恢复。

惨案现场.jpg

这时候,Git 就是你的"时光机"和"后悔药"!

graph LR
    A[最初版本] --> B[第1次修改]
    B --> C[第2次修改]
    C --> D[第3次修改]
    D --> E[...]
    E --> F[当前版本]
    
    G[Git仓库] -.->|记录每个版本| A
    G -.-> B
    G -.-> C
    G -.-> D

Git 的诞生

Git 是 Linux 之父林纳斯·托瓦兹(Linus Torvalds)在 2005 年创造的。

当时,商业版本控制系统 BitKeeper 不再免费开源了,林纳斯一怒之下,花了两周时间写出了 Git。

“我是个自大狂,所以我决定自己写一个版本控制系统。” —— 林纳斯·托瓦兹

结果 Git 成为了世界上最流行的版本控制系统,没有之一。

Git 能做什么?

功能说明类比
版本控制记录每个版本的修改游戏的"存档"功能
多人协作多人同时开发,合并代码多人联机游戏
分支管理创建独立开发线看电影时的"平行世界"
追溯历史查看谁在什么时候改了什么视频回放
备份恢复代码不会丢失云端存档

Git vs 其他版本控制系统

特性GitSVNCVS
类型分布式集中式集中式
离线可用✅ 完全可用❌ 需要服务器❌ 需要服务器
分支轻量级快速笨重不支持
速度超快
安全性难以篡改一般一般

Git 的核心概念

graph LR
    subgraph 工作区
        A[工作目录]
    end
    
    subgraph 暂存区
        B[暂存区<br/>Stage / Index]
    end
    
    subgraph 本地仓库
        C[Git仓库<br/>Repository]
    end
    
    subgraph 远程仓库
        D[远程仓库<br/>Remote]
    end
    
    A -->|git add| B
    B -->|git commit| C
    C -->|git push| D
    D -->|git pull| A
    C -->|git checkout| A

工作区 (Working Directory):你正在编辑文件的地方 暂存区 (Stage/Index):准备提交的区域 本地仓库 (Repository):本地的 Git 数据库 远程仓库 (Remote):GitHub、GitLab 等服务器上的仓库

55.2 Git 安装与配置

安装 Git

Ubuntu/Debian:

1
2
sudo apt update
sudo apt install git

CentOS/RHEL:

1
sudo yum install git

macOS:

1
2
3
4
5
# 方法一:使用 Homebrew
brew install git

# 方法二:安装 Xcode Command Line Tools
xcode-select --install

Windows:

1
2
3
4
5
# 使用 Chocolatey
choco install git

# 或下载安装包
# https://git-scm.com/download/win

验证安装

1
2
$ git --version
git version 2.34.1

首次配置

Git 安装后需要设置用户名和邮箱,这是你每次提交的"签名":

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 设置全局用户名(所有仓库都用这个)
git config --global user.name "你的名字"

# 设置全局邮箱
git config --global user.email "your.email@example.com"

# 查看所有配置
git config --list

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

配置文件

Git 配置有三个级别,按优先级排序:

级别文件位置范围
系统级/etc/gitconfig所有用户的所有仓库
用户级~/.gitconfig~/.config/git/config当前用户的所有仓库
仓库级.git/config当前仓库
1
2
3
4
5
6
7
8
# 系统级配置(需要管理员权限)
git config --system core.editor vim

# 用户级配置
git config --global core.editor vim

# 仓库级配置(当前仓库)
git config core.editor vim

常用配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 设置默认分支名
git config --global init.defaultBranch main

# 设置克隆默认采用 SSH
git config --global url."git@github.com:".insteadOf "https://github.com/"

# 设置别名(简化命令)
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'

# 启用彩色输出
git config --global color.ui auto

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

# 设置提交模板
git config --global commit.template ~/.gitmessage.txt

创建提交模板

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ~/.gitmessage.txt
# ====================
#
# 标题(必填,不超过50字)
#
# 详细内容(可选)
#
# 类型:
#   feat: 新功能
#   fix: 修复bug
#   docs: 文档变更
#   style: 代码格式
#   refactor: 重构
#   test: 测试
#   chore: 构建/工具
#
# ====================

55.3 仓库创建与克隆

创建新仓库

方式一:在当前目录初始化

1
2
3
4
5
6
7
8
# 进入项目目录
cd my-project

# 初始化 Git 仓库
git init

# 输出:
# Initialized empty Git repository in /path/to/my-project/.git/

方式二:创建新目录并初始化

1
2
git init my-new-project
cd my-new-project

.git 目录

git init 会在当前目录创建一个 .git 目录,这是 Git 的"数据库":

1
2
3
4
5
6
7
8
9
ls -la .git/
# .git/
# ├── HEAD          # 指向当前分支
# ├── config        # 仓库配置
# ├── description   # 仓库描述
# ├── hooks/        # 钩子脚本
# ├── info/         # 信息
# ├── objects/      # 对象存储(核心数据库)
# └── refs/         # 引用(分支、标签)

克隆远程仓库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 克隆整个仓库
git clone https://github.com/user/repo.git

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

# 克隆特定分支
git clone -b develop https://github.com/user/repo.git

# 浅克隆(只下载最新版本,省时间)
git clone --depth 1 https://github.com/user/repo.git

常见协议

协议格式说明
HTTPShttps://github.com/user/repo.git需要输入用户名密码(可用 token)
SSHgit@github.com:user/repo.git需要配置 SSH Key,更安全
Gitgit://github.com/user/repo.git只读,防火墙常用

SSH Key 配置(推荐)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 1. 检查是否已有 SSH Key
ls ~/.ssh/

# 2. 生成新的 SSH Key
ssh-keygen -t ed25519 -C "your.email@example.com"

# 3. 一路回车(使用默认位置,空密码)
# Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):

# 4. 查看公钥
cat ~/.ssh/id_ed25519.pub

# 5. 复制公钥到 GitHub/GitLab
# GitHub: Settings -> SSH and GPG keys -> New SSH key

55.4 文件状态

Git 文件生命周期

graph TD
    subgraph 工作区
        A[未跟踪文件<br/>Untracked]
    end
    
    subgraph 暂存区
        B[已暂存<br/>Staged]
    end
    
    subgraph 仓库
        C[未修改<br/>Committed]
        D[已修改<br/>Modified]
    end
    
    A -->|git add| B
    B -->|git commit| C
    C -->|编辑文件| D
    D -->|git add| B
    C -->|git rm| A

四种文件状态

状态说明例子
UntrackedGit 未跟踪的新文件新创建的 readme.txt
Modified已跟踪文件被修改修改了 app.py
Staged暂存区中的文件git add 后的文件
Committed已提交到仓库git commit 后的文件

查看状态

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
git status

# 输出示例:
# On branch main
# 
# Changes not staged for commit:
#   modified:   app.py
#
# Untracked files:
#   newfile.txt
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#   modified:   readme.md

简化输出

1
2
3
4
5
6
7
8
9
# 简洁模式
git status -s

# 输出示例:
# M app.py           # M = Modified(工作区修改)
# A newfile.txt      # A = Added(新增,已暂存)
# D deleted.txt      # D = Deleted(删除)
# R renamed.txt      # R = Renamed(重命名)
# ?? readme.txt      # ?? = Untracked(未跟踪)

55.5 git add

git add 把文件从工作区放入暂存区,准备提交。

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 添加单个文件
git add readme.txt

# 添加多个文件
git add readme.txt app.py

# 添加所有文件
git add .

# 添加所有修改和删除,不包含未跟踪文件
git add -u

# 查看将要添加的内容(不实际添加)
git add -n .

交互式添加

1
2
3
4
5
6
7
8
9
# 交互式添加
git add -i

# 输出:
# *** Commands ***
#   1: status      2: update      3: revert
#   4: add untracked  5: patch      6: diff
#   7: quit      8: help
# What now>

部分添加

1
2
3
4
5
6
7
8
9
# 只添加文件的部分修改(patch 模式)
git add -p

# 选项:
# y - stage this hunk
# n - skip this hunk
# s - split into smaller hunks
# e - manually edit the hunk
# q - quit

55.6 git commit

git commit 把暂存区的内容提交到仓库,创建一个快照。

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 提交暂存区内容
git commit

# 提交并添加说明(推荐!)
git commit -m "提交说明"

# 提交所有已跟踪文件的修改(跳过 git add)
git commit -am "提交说明"

# 修改最后一次提交(还没 push)
git commit --amend

提交规范

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 格式:<类型>: <描述>

# 新功能
git commit -m "feat: 添加用户注册功能"

# 修复bug
git commit -m "fix: 修复登录页面无法跳转的问题"

# 文档更新
git commit -m "docs: 更新 README 使用说明"

# 代码格式
git commit -m "style: 格式化代码风格"

# 重构
git commit -m "refactor: 重构用户认证模块"

# 测试
git commit -m "test: 添加单元测试"

# 构建/工具
git commit -m "chore: 升级依赖包版本"

空提交

1
2
# 创建一个空提交(用于触发 CI/CD)
git commit --allow-empty -m "trigger CI/CD"

多提交操作

1
2
3
4
5
6
7
8
# 提交所有已跟踪的修改
git commit -am "快速提交"

# 提交时显示 diff
git commit -v

# 提交时强制签署(需要配置 GPG)
git commit -S -m "signed commit"

55.7 git status

git status 显示工作区和暂存区的状态。

完整输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
git status

# 详解:
# On branch main          # 当前分支
# 
# Changes to be committed: # 暂存区(即将提交)
#   modified:   file1.txt
# 
# Changes not staged for commit: # 工作区修改(未暂存)
#   modified:   file2.txt
# 
# Untracked files:         # 未跟踪文件(Git 不认识)
#   newfile.txt

简短输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
git status -s
git status --short

# 状态码:
# M  = Modified(修改)
# A  = Added(新增)
# D  = Deleted(删除)
# R  = Renamed(重命名)
# C  = Copied(复制)
# ?? = Untracked(未跟踪)
# !! = Ignored(忽略)

# 示例:
# M  app.py           # 暂存区的修改
#  M readme.txt       # 工作区的修改
# ?? newfile.txt      # 未跟踪文件

忽略文件

创建 .gitignore 文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# .gitignore 示例

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

# 编译产物
*.o
*.so
*.class

# 依赖目录
node_modules/
venv/
__pycache__/

# 日志文件
*.log

# 敏感信息
.env
*.pem

# IDE 配置
.vscode/
.idea/

# 构建目录
dist/
build/

55.8 git log

git log 显示提交历史。

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看提交历史
git log

# 简洁输出
git log --oneline

# 图形化显示分支
git log --graph

# 显示最近 N 条
git log -n 5

# 显示文件修改
git log --stat

高级选项

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 显示每次提交的文件变化
git log --name-status

# 显示每次提交的差异
git log -p

# 显示每个提交者的提交次数
git shortlog

# 显示贡献者统计
git shortlog -sn

# 按日期范围查询
git log --since="2024-01-01"
git log --until="2024-12-31"

# 按作者查询
git log --author="John"

# 按提交信息关键词查询
git log --grep="fix"

# 显示某个文件的历史
git log --follow file.txt

美化输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 格式化输出
git log --pretty=format:"%h %an %s"

# 常用占位符:
# %H  完整 commit hash
# %h  简短 commit hash
# %an 作者名字
# %ae 作者邮箱
# %s  提交说明
# %b  提交详情
# %cr 相对时间
# %ci ISO 格式时间

# 美化样式
git log --pretty=format:"%C(yellow)%h%Creset - %C(bold)%s%Creset %C(dim)(%cr)%Creset" --graph

55.9 git diff

git diff 显示文件差异。

基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 查看工作区 vs 暂存区
git diff

# 查看暂存区 vs 仓库
git diff --staged
git diff --cached

# 查看工作区 vs 仓库(当前分支最新提交)
git diff HEAD

# 查看两个提交之间的差异
git diff abc123..def456

比较特定文件

1
2
git diff -- readme.txt
git diff HEAD -- readme.txt

高级选项

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 统计变化
git diff --stat

# 忽略空白变化
git diff --ignore-space-change

# 显示函数级别的差异
git diff -U 10

# 显示为统一的 diff 格式
git diff -U 1

# 简短 diff
git diff --shortstat

分支比较

1
2
3
4
5
6
7
8
# 比较两个分支
git diff main..develop

# 比较当前分支和 main
git diff main

# 查看未提交的合并
git diff --cached --staged

图形化工具

1
2
3
4
5
6
7
8
9
# 使用 vimdiff
git difftool

# 设置默认工具
git config --global diff.tool vimdiff
git config --global difftool.prompt false

# 使用 Beyond Compare
git config --global diff.tool bc3

本章小结

本章我们学习了 Git 的基础知识:

命令说明
git init初始化仓库
git clone克隆仓库
git add添加到暂存区
git commit提交到仓库
git status查看状态
git log查看历史
git diff查看差异

Git 的核心工作流程:

graph LR
    A[工作区] -->|git add| B[暂存区]
    B -->|git commit| C[本地仓库]
    C -->|git push| D[远程仓库]
    D -->|git pull| A
    D -->|git clone| A

💡 温馨提示: Git 是程序员的"时光机"。养成勤提交的好习惯,每次提交只做一件事,提交信息写清楚。将来回溯历史时,你会感谢现在的自己!


下一章预告:第五十六章我们将学习 Git 进阶,包括分支管理、标签、远程协作、Git Flow 工作流、CI/CD 等内容。敬请期待! 🚀

最后修改 March 24, 2026: 新增JavaScript教程 (37305c4)