为什么需要版本控制:U盘问题
Source: Dev.to
抱歉,我无法直接访问外部链接获取文章内容。请您把需要翻译的文本粘贴在这里,我会帮您翻译成简体中文,并保持原有的格式、Markdown 语法和技术术语不变。
Source: …
Introduction
在 Git 成为现代软件开发的支柱之前,协作是脆弱的、手动的,甚至出奇地原始。
开发者并不克隆仓库或推送提交。他们传递 pendrives(U 盘)。
每个 U 盘里都有同一项目的略有不同的版本。没人知道哪个是正确的,谁改了什么,或者 bug 是何时引入的。一次错误的覆盖可能会抹去数天的工作。
这并不是偶尔的不便——它是一个结构性问题,使得团队合作缓慢、风险高且难以扩展。
这种日常的痛点最终迫使开发者重新思考代码应如何共享、跟踪和信任。正是在这种混乱中诞生了一个永远改变软件开发的系统:Git。
在本文中,我们将探讨 Git 为什么被创建、它出现之前存在哪些问题,以及开发者在现代版本控制系统出现前是如何管理代码的。
在理解 版本控制为何存在 之前,先明确一下版本控制到底是什么。
根据互联网的定义,版本控制(也称为修订控制、源代码控制或源码管理)是跟踪和管理计算机文件——主要是源代码——更改的软工程实践。
这个定义听起来很技术化,但其核心思想很简单。
版本控制是一种跟踪代码更改的方式,让你能够看到何时、何处发生了改变,并在出现问题时回滚到早期版本。
换句话说,它为你的代码提供了 记忆。
所以真正的问题是:最初为什么需要它?
U 盘时代
让我们回到过去,想象一个没有 Git 的世界。
你是一名开发者,正在进行一个项目。某天你需要帮助来实现一个新功能,于是请你的朋友 Abdul 合作。他同意了并索要代码。
为了共享代码,你把项目压缩后复制到 U 盘,并把它寄给他。Abdul 实现了该功能后,又把更新后的项目压缩并把 U 盘寄回。
当你解压项目时,首先出现的问题很明显:代码量很大,而你根本不知道 哪部分是由谁编写的。既然功能可以运行,你便忽略了这个问题,继续前进。
几天后,你发现 Abdul 编写的功能中有一个 bug。于是你把整个项目再次放进 U 盘寄回给他。他修复了 bug 并把 U 盘返回。
现在你知道代码已经改变——但你不知道 具体改了什么、改在哪里。要了解这些修改,你必须坐下来逐行对比,这非常耗时。
另一个重大问题随之而来:在 Abdul 工作期间,你自己无法安全地对代码进行修改。如果你也动手,两人最终会得到同一项目的不同版本——导致 冲突和重复劳动。
随着代码库的增长以及开发者数量的增加,这些问题会变得更加痛苦。想象一下第三位开发者 Chitra 加入了这个项目。三个人根本没有办法实时协作,同时保证代码 不会不同步。
还有一个更进一步的问题是,无法看到 何时被更新、谁更新了它,以及整个变更的时间线。随着时间的推移,旧的版本会丢失,你只能面对一个完全出错的代码库,且没有办法回退到已知的良好状态。
简单示例:
- Abdul 正在修复一个功能中的 bug,修改了代码后把 U 盘交给 Chitra,因为她的功能也出现了问题。
- Chitra 进一步修改了代码。
- 当 U 盘最终回到你手中时,你对项目发生了什么一无所知。
版本控制系统之前面临的问题
- 被覆盖的代码 – 最后保存的人常常会擦除他人的工作。
- 丢失的更改 – 由于使用过时的副本,数小时的工作可能会消失。
- 没有协作历史 – 没有可靠的方法来追踪谁更改了什么以及原因。
- 浪费时间 – 同时只能有一名开发者安全地工作。
- 持续的困惑 – 团队难以确定哪个代码版本是正确的。
Source: …
如何通过版本控制解决 U 盘问题
现在让我们思考如何解决这些问题。
第一个挑战是追踪 谁做了哪些更改。为了解决这个问题,想象创建一个软件系统,它:
- 跟踪代码更改。
- 记录每次更改的作者。
- 显示旧代码和新代码之间的差异。
- 保留完整的版本历史。
这个方案可以解决前两个问题:追踪更改 和 识别贡献者。
于是出现了一个简单的想法:构建一个工具,在每次提交更改时记录作者、时间戳和上下文说明。我们把它称为 CCT(代码更改追踪器)。在 U 盘上部署 CCT,……问题解决了吗?
部分解决。 虽然 CCT 能提供谁在何时改了什么的日志,但它仍然依赖于手动分发 U 盘,核心的同步、冲突解决以及集中式历史记录问题仍未解决。
接下来的步骤是把追踪系统迁移到共享的、网络可访问的仓库,加入分支和合并功能,并自动化更改的分发。这一演进催生了现代的版本控制系统——最终诞生了 Git。
# From Pendrives to Distributed Version Control
Developers used to **copy code onto a pendrive**, hand it to a teammate, and hope the changes didn’t get lost.
If something went wrong, the only way to recover was to **re‑create the history manually**.
Now we can **see the history and revert**, which was not possible before.

实时协作问题
即使有了完善的版本追踪,每个开发者仍然拥有 自己本地的项目副本。
每个人都有历史记录——但不一定是 相同的历史。
核心问题从:
- “谁改了这个?”
- “改了什么?”
转变为:
- “大家应该基于哪个版本进行工作?”
这不再只是版本管理的问题——它是一个 协作与协调问题,因为在代码仍然位于单一物理位置时,同一时间只能有一个开发者工作。
第一次尝试:中央服务器
开发者搭建了一个云服务器来存放代码,称之为 CCTS(代码更改追踪器服务器),并在其上部署了 CCT。
此时似乎 U 盘时代已经结束:
- 一个追踪更改的系统
- 一个存放代码的服务器
- 多个开发者共同协作
然而,早期的集中式版本控制系统仍有一个关键弱点:一切都依赖于中央服务器。
- 服务器宕机,开发停止。
- 服务器丢失数据,项目历史消失。
- 开发者必须持续访问那台机器,无法自由工作。
换句话说,协作是可能的——但非常脆弱。
让 Git 与众不同的架构转变
Git 完全颠覆了模型。它不是让中央服务器保存完整历史,而是 每个开发者都获得代码库的完整副本以及全部历史。
这使得开发者能够:
- 离线工作
- 安全地进行实验
- 从故障中恢复
- 在没有单点故障的情况下协作
服务器变成了 共享的协调点,而不是依赖的对象。
核心洞见
- CCT(代码更改追踪器) 代表 Git —— 分布式版本控制系统。
- CCTS(代码更改追踪器服务器) 代表 GitHub 等平台 —— 它们让协作更容易,但并非 Git 工作的必需条件。
Git 的诞生
Git 由 Linus Torvalds 创建,用来管理他的主要项目:Linux。随着 Linux 的发展,跟踪更改变得极其困难。开发者们尝试使用 BitKeeper——一种专有的 VCS,速度快、效率高,适合大型分布式团队。BitKeeper 为 Linux 社区提供了免费许可证,于是他们采用了它。
然而,社区的一位成员试图 逆向工程 BitKeeper,这激怒了其创作者。信任被破坏,BitKeeper 的免费访问被撤销。
在失去这一关键工具后,Linus 发誓再也不依赖专有软件。他决定自行构建一套 分布式版本控制系统——免费、开源、且完全独立。
于是,Git 诞生了。
Git(版本控制系统)的替代方案
- SCCS(源代码控制系统)
- RCS(修订控制系统)
- CVS(并发版本系统)
- Mercurial
- Apache Subversion
- Fossil
- AWS CodeCommit
GitHub 替代方案(托管平台)
- Bitbucket
- GitLab
- Gitea
- Codeberg
结论
版本控制并非源于理论或最佳实践——它源于痛苦。
U 盘时代展示了在没有可靠的变更追踪方式、没有共享历史、也没有可扩展协作模型时会发生什么。代码被覆盖,错误难以追踪,团队协作根本无法扩展。
- Git 通过将每一次更改记录为历史,解决了 跟踪问题。
- 类似 GitHub、GitLab 和 Bitbucket 的平台通过为团队提供共享的协作空间,解决了 协作问题。
这就是为什么版本控制不再是可选的——它是现代软件开发的基石。
如果你曾经推送过提交、解决过合并冲突或回滚过错误,你正受益于那些源自于像传递 U 盘这样简单且痛苦的经历的解决方案。
了解这段历史不仅让你成为更好的 Git 使用者,它还能让你成为更好的工程师。
关注以获取更多面向初学者的核心软件工程概念拆解。

