Chapter 01

版本控制概念与 Git 简介

从混乱的手动备份到优雅的分布式版本控制——理解 Git 的诞生背景与设计哲学

为什么需要版本控制

想象你正在写一份重要的项目报告。随着内容不断修改,你的桌面逐渐变成这样:

report_v1.doc
report_v2.doc
report_v2_final.doc
report_v2_final_REALLY_FINAL.doc
report_v2_final_boss_review.doc
report_v3_after_meeting.doc

这就是没有版本控制时的典型困境。问题显而易见:

软件开发中这个问题更加严峻。一个现代项目可能有数十万行代码、数百个文件、数十名开发者同时工作——没有版本控制系统(VCS),这一切将是一场灾难。

版本控制系统(VCS)能做什么?记录每一次文件变更、追踪是谁在何时做了什么修改、支持多人并行开发、随时回退到任意历史版本、对比任意两个版本的差异。

版本控制系统的演进

第一代:本地版本控制

最早的解决方案是在本地磁盘上管理版本。RCS(Revision Control System)是这一时代的代表,它通过存储文件的补丁集(patch set)来节省空间,可以重放这些补丁来重建任意历史版本。

问题是显而易见的:数据只在一台机器上,一旦硬盘损坏,所有历史都消失了;多人协作基本不可能实现。

第二代:集中式版本控制(CVCS)

CVSSubversion(SVN)Perforce 代表了这一阶段。核心思想是:所有版本历史存储在一台中央服务器上,团队成员从服务器检出(checkout)文件。

中央服务器(所有历史)
│ ────── checkout ──────▶ 开发者 A
│ ────── checkout ──────▶ 开发者 B
└ ────── checkout ──────▶ 开发者 C

这解决了多人协作的问题,但引入了新问题:

第三代:分布式版本控制(DVCS)

GitMercurialBazaar 代表了这一阶段的突破。核心思想是:每个开发者本地都有一份完整的仓库副本(包括全部历史)。

开发者 A(完整历史) ←──push/pull──→ 远程仓库(共享) ←──push/pull──→ 开发者 B(完整历史)

优势显著:

Git 的诞生

2005 年之前,Linux 内核开发团队使用 BitKeeper(一个商业 DVCS)。这一年,由于许可协议纠纷,BitKeeper 撤回了对 Linux 社区的免费授权。

Linux 创始人 Linus Torvalds 决定亲自动手,写一个新的版本控制系统。他的目标明确:

令人震惊的是,Linus 在 2005 年 4 月用大约两周时间写出了 Git 的第一个版本,并在同年 6 月将 Linux 内核的版本管理迁移到了 Git 上。

Git 这个名字据说来自 Linus 的自嘲——英国俚语中 "git" 意为"令人讨厌的人"。Linus 说:"我用自己的名字命名了第一个项目(Linux),现在用一个骂人的词命名第二个。"

Git 的设计哲学

分布式优先

Git 从设计之初就假设没有"唯一权威"的中心服务器。所谓的远程仓库(如 GitHub)只是另一个 Git 仓库,地位与本地仓库完全平等。

数据完整性(SHA 哈希)

Git 中的每个对象(文件、目录、提交)都通过其内容计算出一个 SHA-1 哈希(40位十六进制字符串,现代 Git 也支持 SHA-256)。这个哈希就是该对象的唯一标识符。

e69de29bb2d1d6434b8b29ae775ad8c2e48c5391  # 这是一个空文件的 SHA-1 哈希
a94a8fe5ccb19ba61c4c0873d391e987982fbbd3  # "test" 的 SHA-1 哈希

只要内容不变,哈希就不会变。任何数据损坏都会导致哈希不匹配,Git 立即能发现。这被称为内容寻址存储(Content-Addressable Storage)

性能优先

Git 中绝大多数操作(提交、分支切换、查看历史)都在本地完成,不需要网络请求,速度极快。分支的创建只是写一个 41 字节的文件,近乎零成本。

Git 的四个区域(核心概念!)

理解 Git 的四个区域是掌握 Git 的关键。很多初学者混乱的根源就是不清楚文件处于哪个区域。

工作区 ──git add──▶ 暂存区 ──git commit──▶ 本地仓库 ──git push──▶ 远程仓库
(Working Dir) (Staging/Index) (Local Repo) (Remote Repo)

远程仓库 ──git pull──▶ 工作区
远程仓库 ──git fetch──▶ 本地仓库(不更新工作区)

初学者常见误区git add 不是"上传",只是"登记到暂存区"。git commit 不是"保存到 GitHub",只是"保存到本地仓库"。只有 git push 才会与远程交互。

安装 Git

macOS

推荐使用 Homebrew 安装,可获得最新版本:

# 安装 Homebrew(如果没有)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 安装 Git
brew install git

# 验证安装
git --version

Windows

访问 git-scm.com 下载安装包。安装时推荐选择:

Linux

# Ubuntu / Debian
sudo apt update && sudo apt install git

# CentOS / RHEL / Fedora
sudo yum install git
# 或
sudo dnf install git

初始化配置

安装 Git 后,第一件事是告诉 Git 你是谁。每次提交都会记录这些信息。

# 设置用户名(显示在提交记录中)
git config --global user.name "张三"

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

# 设置默认分支名为 main(现代惯例)
git config --global init.defaultBranch main

# 设置默认编辑器为 VS Code
git config --global core.editor "code --wait"

配置的三个级别

Git 配置有三个层级,优先级从高到低:

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

高优先级的配置会覆盖低优先级的同名配置。例如,你可以在 --global 中设置个人邮箱,在某个工作仓库的 --local 中设置公司邮箱。

查看配置

# 查看所有配置及来源
git config --list --show-origin

# 查看某个具体配置
git config user.email

# 查看全局配置文件内容
cat ~/.gitconfig

配置 SSH 密钥(简述)

与 GitHub 等远程仓库交互时,推荐使用 SSH 密钥认证而非密码:

# 生成 ED25519 密钥对(推荐)
ssh-keygen -t ed25519 -C "your@email.com"

# 查看公钥内容,复制到 GitHub Settings → SSH Keys
cat ~/.ssh/id_ed25519.pub

# 测试连接
ssh -T git@github.com

HTTPS vs SSH:HTTPS 使用用户名+密码(或 Personal Access Token),适合偶尔贡献的场景;SSH 配置一次后无需每次输入凭据,更适合日常开发。