从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • 计算机简史

  • 数字电路

  • 计算机组成原理

  • 操作系统

  • Linux

  • 计算机网络

  • 数据库

  • 编程工具

    • Git

      • 版本控制
        • 在版本管理工具出现之前……
        • 集中式和分布式的概念
        • patch 命令
      • 安装和配置 Git
      • 初识版本库
      • 版本管理
      • 工作区、暂存区和修改
      • 远程仓库
      • 解决 GitHub 访问失败的办法
      • 关于 GitHub 的奇技淫巧
      • 分支管理
      • GitStash
      • 远程仓库和分支
      • 标签管理
      • 自定义 Git
      • 使用可视化工具
      • Github Action
      • 常用 Git 命令
      • Git 帮助文档
      • GitHub 个人主页美化教程
      • 其他 GitHub 技巧
      • 在 commit 里使用 emoji~
      • 逆天,CSDN 批量搬运 GitHub 项目
    • 终端

  • 装机

  • 计算机基础
  • 编程工具
  • Git
2023-01-16
目录

版本控制

# 10.版本控制

本文简单介绍下什么是版本控制,以及常见的版本控制工具

在学习之前,希望读者有一点点编程经验,并且对一些常见的 Linux 命令有所了解,这样能更好理解。

本系列主要是参考廖雪峰老师的 Git 教程 (opens new window)和《Git 权威指南》,以及自己的使用经验来撰写。 ‍

# 在版本管理工具出现之前……

举个笔者的例子。笔者在写毕业论文的时候,由于篇幅非常多,经常需要修改;但有时候可能会用到之前的版本,因此笔者会先备份之前的 Word 文档,然后再修改。这就造成了文档非常非常多……(写过毕设或其他长篇大论的文案的人应该都能体会到)。

​​

此时,我们是手工管理版本的。对于每个文件,你可能几天内都记得每个版本的区别;但如果过了一周、过了一个月呢?除非有特别记录,相信大家都记不清了,只能一个个文件打开来,认真比对 🧐,非常麻烦。

如果是多个人共同编写一个文档,更麻烦。例如,笔者所在的公司是内网,没有腾讯文档或者石墨文档之类的在线工具,如果要填表(并且是经常需要填表),都是各自填好后,发邮件交由专门的人来合并…… 特别麻烦。 ‍ 为此,我们需要这样一个软件:

  1. 能帮我们记录每次文件的改动
  2. 能够方便的查看之前的改动
  3. 让同事或朋友协作编辑,而不是手工传来传去,手工合并

这样的软件就叫版本控制工具,有了它,我们就脱离了手工管理版本的“史前时代”,进入到了版本控制的 20 世纪。作为程序猿,我们主要是需要版本控制工具来管理我们的一个项目的代码(当然,你也可以用它来管理其他文件的版本),并且一个大型项目经常是需要多人协作的,纯靠手工来管理代码版本不太实际。

我们依次来简单介绍以下几个工具(大部分笔者都曾在工作中用过):

  1. diff 和 patch 命令
  2. CVS:全称 Concurrent Versions System,第一个被广泛使用的版本管理工具
  3. SVN:修正了 CVS 的一些稳定性问题,是目前用得最多的集中式版本库控制系统
  4. Git:目前世界上最先进的分布式版本控制系统(没有之一),必学
  5. 其他版本控制工具

存储版本的地方,我们称之为版本库。例如我们要在磁盘上存储东西,肯定是以文件的方式存储:

  • Git 是用一个目录来存储各个版本和差异的文件,目录名字为 .git​;
  • SVN 同理,用 .svn​ 目录来存储的
  • CVS 同理,用 .csv​ 目录来存储的

一般情况下这几个目录是隐藏的(防止被随意的删除和修改等),在 Windows 上可以通过显示隐藏文件夹来查看,Linux 下可以用 ls -ah​ 命令查看

# 集中式和分布式的概念

在介绍版本控制工具之前,我们还有必要介绍一下集中式版本控制系统,和分布式版本控制系统的概念。

集中式:版本库是放在一个中央服务器上的,干活的时候,需要联网才能从服务器下载最新版本到自己电脑上(因为大多数时候我们都是在自己电脑上开发),开发完后再上传到服务器上。如果网速慢……那就有的等了。好比一个图书馆,要看书得先从图书馆里借书,用完了后要还回去,需要来来回回跑图书馆。

而且集中式容易出现单点故障的问题。万一服务器坏了,那么就完了…… 因此得额外对服务器进行备份。

​集中式​

图片来自 集中式 vs 分布式 - 廖雪峰的官方网站 (opens new window)

分布式:每个人自己的电脑上就有一个完整的版本库,获取版本的时候不需要联网。等需要合并文件的时候,再将各自的修改上传到中央服务器上。就好比每个人都有一个完整的图书馆,如果要合并文件,每个人都将自己的修改放到中央图书馆里,相当于只用去一次图书馆;合并完后,每个人再从中央图书馆里更新。

一句话,集中式和分布式的区别是:你的本地是否有完整的版本库历史。每个人都是本地版本库的主人,对版本库的操作,包括查看提交日志、提交、创建里程碑和分支、合并分支、回退等所有操作都直接在本地完成而不需要网络连接。

假设 SVN 服务器没了,那就丢掉了所有历史信息,因为你的本地只有当前版本以及部分历史信息。

比特币的区块链设计就类似 git,人手一份全账本,只是用 p2p 全网同步,而 git 通常搞个中心化服务来同步

svn 像银行,完整账本只有银行有,作为终端节点可以向银行查询账本,但如果某一天银行没了,整个完整账本就没了

分布式的核心设计是同步,而不是主从。软件架构,核心思想其实是非常简单的。

diff 意指 difference。diff 是命令行工具,可以通过他们来比较两个文件的差异,后续我们学习 Git 的时候,也经常用 diff 命令来查看文件的差异,diff 可以说是版本控制的基础工具。

我们来看个例子(推荐读者一起来实践)。该命令需要在 Linux 下运行,如果没有 Linux 环境,读者可以先参考下一篇博客安装好 Git 后,然后在 Git Bash 里可以运行。

首先创建两个文件,并写入以下内容:



-- 此时文件内容如下
$cat hello.txt 
This is hello file
Welcome to diff


‍
然后我们就可以用 diff 命令,来比较两个文件的差异了。我们将差异结果输出到一个文件:

```bash
$diff -u hello.txt world.txt > diff.txt
1
2
3
4
5
6
7
8
9
10
11
12
13

-u 参数很重要,它使得差异带有上下文。 ‍ 我们查看下 diff.txt 的内容:

$cat diff.txt 
--- hello.txt	2023-01-10 21:56:47.050201742 +0800
+++ world.txt	2023-01-10 22:08:41.473521836 +0800
@@ -1,2 +1,2 @@
-This is hello file
+This is world file
 Welcome to diff
1
2
3
4
5
6
7

我们来说明下这个文件的内容:

  • 文件的第 1 行和第 2 行分别记录了原始文件和目标文件的文件名及时间戳。以三个减号(---)开始的行标识的是原始文件,以三个加号(+++)开始的行标识的是目标文件。
  • 文件的第 5,6,7 行,以减号(-)开始的行是只出现在原始文件中的行,以加号(+)开始的行是只出现在目标文件中的行,以空格开始的行,是在原始文件和目标文件中都出现的行, ‍ 第 4~7 行,是一个差异小节(就是两个文件之间的一个差异):
@@ -1,2 +1,2 @@
-This is hello file
+This is world file
1
2
3

‍ 每个差异小节以一行差异定位语句开始,其前后分别用两个 @ 进行标识。其中:

  • -1,2 的含义:本差异小节的内容相当于是原始文件从第 1 行开始的 2 行
  • +1,2 的含义:本差异小节的内容相当于是目标文件从第 1 行开始的 2 行

因为命令 diff 是用于行比较的,所以即使一个字不同,也显示为一整行的修改(Git 对 diff 进行了扩展,并且还提供一种逐词比较的差异比较方法)。

除了-u,diff 还有以下选项,就不一一演示了:

  • -b:忽略空格
  • -B:忽略空行
  • -i:忽略大小写
  • -c:显示文件所有内容并标识不同
  • -r:对比目录 ‍

# patch 命令

patch 相当于 diff 的反向操作。有了原始文件和 diff 文件,就可以还原出目标文件。我们来实践下:

$cat world.txt This is hello file Welcome to diff



然后用 patch 命令来还原目标文件:可以看到 world 文件回来了。

```bash
$patch world.txt < diff.txt 
patching file world.txt


$cat world.txt 
This is world file
Welcome to diff
1
2
3
4
5
6
7
8
9
10
11
12

注意:经测试,如果 diff 和 patch 的文件中的换行符不是 Linux 环境下的 LF 换行符,那么 patch 就会失败,报错如下:

$ patch world2.txt < diff.txt
patching file world2.txt
Hunk #1 FAILED at 1 (different line endings).


## diff 和 patch 小结

严格来说 diff 和 patch 命令不是版本控制工具,而是比较差异的工具。

diff 和 patch 命令存在一个局限,就是不能对二进制文件进行处理。对二进制文件的修改或添加会在差异文件中缺失,进而丢失对二进制文件的改动或添加。

实际上,大部分版本控制工具都不能很好的管理二进制文件,虽然也能由版本控制工具来管理 ,但是不能比较两者有什么差异(一堆 0 和 1 的比较,看不出来改了什么内容的)。Git 对差异文件格式提供了扩展支持,支持二进制文件的比较,解决了这个问题。

在没有版本控制系统的情况下,可以用这 diff 和 patch 记录并保存改动前后的差异,还可以将差异文件注入版本控制系统(如果有)。

Linus 在 1991~2002 年,就是用 diff 和 patch 维护 Linux 不同版本间差异的。感兴趣的读者可以看看 Linus Torvalds 于 2007 年 5 月 3 日在 Google 的演讲:[Tech Talk: Linus Torvalds on git - YouTube](https://www.youtube.com/watch?v=4XpnKHJAok8)。


CVS 的历史:CVS(Concurrent Versions System)诞生于 1985 年,是由荷兰阿姆斯特丹 VU 大学的 Dick Grune 教授实现的。当时 Dick Grune 和两个学生共同开发一个项目,但是三个人的工作时间无法协调到一起,迫切需要一个记录和协同开发的工具软件。于是 Dick Grune 开发出有史以来第一个被大规模使用的版本控制工具。

可以看到,CVS 是被逼出来的,用人工管理版本太麻烦了,没办法才开发出来。

CVS 的特点:

* 最早被广泛使用,到现在也有不少人用;
* 开源且免费
* 集中式版本控制系统
‍
使用 CVS 管理版本的时候,每个目录下面都有一个目录叫做 CVS(这样实现起来简单),单独拿一个目录出来就可以当作版本库。但 CVS 也有缺点:

* 不能对重命名进行版本控制
* 缺乏对原子提交的支持,如果有网络中断或其他不可控因素,会导致客户端向服务器端提交不完整的数据(这设计就很不合理了,最基本的功能有这样的缺陷)
* 随着文件的变多,效率会越来越慢

CVS 的成功导致了版本控制系统的大爆发,各式各样的版本控制系统如雨后春笋般诞生了,并且 CVS 的不少理念都成为了后续版本控制的标准。

新的版本控制系统或多或少地解决了 CVS 版本控制系统存在的问题。在这些版本控制系统中,最典型的就是 Subversion(SVN)。
‍
## SVN

​![](https://image.peterjxl.com/blog/image-20230111201113-edssncw.png)​

[Subversion](http://subversion.apache.org/),由于其命令行工具名为 svn,因此通常被简称为 SVN。SVN 由 CollabNet 公司于 2000 年资助并开发,目的是创建一个更好用的版本控制系统以取代 CVS。

SVN 的前期开发使用 CVS 做版本控制,到了 2001 年,SVN 已经可以用于自己的版本控制了

SVN 实现了原子提交的功能,不会像 CVS 那样出现文件的部分内容被提交而其余的内容没有被提交的情况。

SVN 还有一个创举,就是在工作区跟踪目录下(.svn 目录)为当前目录中的每一个文件都保存一份冗余的原始拷贝。这样做的好处是部分命令不再需要网络连接,例如文件修改的差异比较,以及错误更改的回退等。

SVN 还有不少闪亮的功能特性,使得 SVN 在 CVS 之后诞生的诸多版本控制系统中脱颖而出,成为开源社区一时的新宠,也成为当时各个企业进行版本控制的最佳选择之一。

但是,SVN 在本质上并没有突破,都属于集中式版本控制系统,在查看日志和提交的时候,如果网速慢,就很让人抓狂。

对于 CVS 和 SVN 来说,笔者在公司内局域网内用过,网速还是可以的。但是论起好用,还得是 Git😁


## Git

​(https://image.peterjxl.com/blog/image-20230111201130-8wqt3b6.png)​

书接上文,我们来继续介绍 Git。

在 Git 出现之前,Linux 之父 Linus 坚决反对使用集中式版本控制工具,在 1991-2002 这十余年间,Linus 宁可以手工修补文件的方式维护 Linux 的代码。

经过十余年的发展,Linux 的代码库已经变的非常大了,还用手工维护非常不方便,Linux 社区意见也很大。因此在 2002~2005 年期间,Linus 选择了一个商业版本控制系统 BitKeeper 作为 Linux 内核的代码管理工具,BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统。

2005 年发生的一件事最终导致了 Git 的诞生。在 2005 年 4 月,Andrew Tridgell(即大名鼎鼎的 Samba 的作者)试图对 BitKeeper 进行反向工程(类似通过反编译等方式获得 BitKeeper 的源码),以开发一个能与 BitKeeper 交互的开源工具。这激怒了 BitKeeper 软件的所有者 BitMover 公司,要求收回对 Linux 社区免费使用 BitKeeper 的授权。

Linus 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们,但实际上 Linus 会受这气?直接花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!几个月之内,Linux 系统的源码已经由 Git 管理了!大家可以体会下什么叫 🐂🍺

以下是 Git 诞生过程中的大事记(来自[维基百科](https://en.wikipedia.org/wiki/Git#History)):

* 2005 年 4 月 3 日,开始开发 Git。
* 2005 年 4 月 6 日,项目发布。
* 2005 年 4 月 7 日,Git 就可以作为自身的版本控制工具了。
* 2005 年 4 月 18 日,发生第一个多分支合并。
* 2005 年 4 月 29 日,Git 的性能就已经达到了 Linus 的预期。
* 2005 年 6 月 16 日,Linux 内核 2.6.12 发布,那时 Git 已经在维护 Linux 核心的源代码了。


## 其他版本控制工具


* 采用黑盒子式的版本库设计。大部分商用产品,是不会给使用者源码的(给了谁还买啊),因此让人捉摸不透其内部是怎么实现的,也加大了将代码迁移到其他版本库的成本(笔者推测这使得企业只能一直用这个产品,然后继续付费)
* 商业版本控制工具很难定制化需求,因为公司需要赚钱,总不能免费帮忙开发需求。
* 商业版本控制工具注定是小众软件,专门提供给企业使用,培训新员工也很麻烦。

简单说说笔者知道的一些商用工具。
‍
### ClearCase

Rational 公司(该公司后面被 IBM 收购了)出品过 ClearCase 版本控制工具,但据说很难用,搜索到的评价如下:

* [为什么有些大公司技术弱爆了? - 知乎](https://www.zhihu.com/question/32039226/answer/1739380593):毕业第一年在腾讯工作,做 QQ 游戏大厅,当时用的 IDE 是 VC2006,用的版本控制工具,叫 ClearCase(估计用过的人不多),IBM 开发的。特点是极其严谨、非常强大,但流程极为繁琐,用起来简直让人抓狂,这还是腾讯花了 3000 万找 IBM 买的。
* [集中式 vs 分布式 - 廖雪峰的官方网站](https://www.liaoxuefeng.com/wiki/896043488029600/896202780297248):特点是安装比 Windows 还大,运行比蜗牛还慢,能用 ClearCase 的一般是世界 500 强,他们有个共同的特点是财大气粗,或者人傻钱多。

笔者也没用过,暂且不表。
‍
### VSS

微软公司出品的,搜索到的相关平均如下:


  VSS 虽然是微软公司的产品,但微软内部却很少使用它。微软内部使用一个名为 SLM 的版本控制系统,直至 1999 年。之后,微软内部改以使用修改自 Perforce 的 SourceDepot。
‍
## 小结

本文主要介绍了如下内容:

1. 为什么我们需要版本控制
2. 集中式和分布式的概念
3. 常见的版本控制工具介绍
4. 简单演示了下 diff 和 patch 命令
5. 简单介绍了版本控制工具的历史

在可以选择的情况下,强烈推荐使用 Git 作为版本控制管理工具。
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
上次更新: 2025/5/5 17:15:09
编码类型
安装和配置 Git

← 编码类型 安装和配置 Git→

最近更新
01
语雀文档一键下载至本地教程
07-04
02
要成功,就不要低估环境对你的影响
07-03
03
血泪教训:电子设备要定期开机
07-02
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式