- 我是一个线程(修订版)
- 我是一个 Java class
- Javascript:一个屌丝的逆袭
- Java : 一个帝国的诞生
- JSP 一个装配工的没落
- TCP/IP 之 大明王朝邮差
- TCP/IP 之大明内阁
- TCP/IP 之蓟辽督师
- CPU 阿甘
- CPU 阿甘之烦恼
- CPU 阿甘:函数调用的秘密
- 我是一个网卡
- 我是一个路由器
- 我是一个进程
- 我是一块硬盘(上)
- 我是一块硬盘(下)
- 我是一个键盘
- 张大胖的 socket
- 张大胖学递归
- 学习面向对象的令狐冲
- 张大胖学数据库
- 数据库村的旺财和小强
- 小李的数据库之旅(上)
- 小李的数据库之旅(下)
- 漫画:什么是机器学习?
- 那些烦人的同步和互斥问题
- IE 为什么把火狐和 Chrome 给打伤了?
- 对浏览器村的第二次采访
- 节约标兵 IE 的自述
- EMail 诞生记
- Email 诞生记(下)
- Http 历险记(上)
- Http 历险记(下)-- Struts 的秘密
- 动物王国的面向对象
- 冯·诺伊曼计算机的诞生
- Http Server : 一个差生的逆袭
- 张大胖的加法器
- 从 1 加到 100:一道简单的数学题挑战下你的大脑
- 编程语言
- Javascript:一个屌丝的逆袭
- 计算机语言之战
- 我和编程语言的爱恨情仇(上)
- 我和编程语言的爱恨情仇(下)
- Android 为什么选择了 Java
- iOS 为什么选择了 Object-C?
- Basic : 一个老兵的自述
- Node.js : 我只需要一个店小二
- 命令式编程 vs 声明式编程
- 编译还是解释?
- 程序人生
- “架构师"小赵
- 师兄说
- 师姐说
- 小王的架构师之路
- 小李的版本管理系统
- 小超穿越记
- 小李的 Build 之路(上)
- 小李的 Build 之路(下)
- 张大胖改 Bug
- 我的编程之路--大学趣事
- 码农小王的一天
- 小李在外企
- 张大胖的需求估算
- 从厨师到码农
- 聊一聊那些神一样的程序员们(上)
- 聊一聊那些神一样的程序员们(中)
- 聊一聊那些神一样的程序员们(下)
- 谁是互联网之父?
- 一个价值百万的创业教训
- 让自己与众不同 - 提升工作的价值
- 看看你的“易燃性”
- 从无聊的工作中寻找价值
- 什么样的学生适合报考计算机?
- 谈谈程序员的职业方向(上)
- 谈谈程序员的职业方向(中)
- 谈谈程序员的职业方向(下)
- 谈谈培训班的作用
- 码农需要知道的“潜规则”
- 学习编程的加速度
- 码农在工作中的必备能力
- 码农和英语
- 老司机经验
- 假如时光能够倒流, 我会这么学习 Java
- 假如我是计算机系老师
- 学会编程, 而不是学会 Java
- 从增删改查中突围
- 抽象:程序员必备的能力
- 懒就一个字
- 编程的自学方法
- 小王买房记
- 从一道面试题谈谈一线码农应该具备的基本素质
- 想写框架的看过来
- 苹果手机变砖头以后
- 如何快速的学习一门技术?
- 唯一不变的是变化: 谈谈微信应用号
- 什么是企业应用?
- 勿以浮沙筑高台
- 为什么敏捷开发难于成功?
- localhost vs 127.0.0.1
- GitHub/Stackoverflow 找工作时有什么用?
- 动词 or 名词 :这是一个问题
- 如何选择入行语言
- 有时候,沉默是金
- 零 Bug 的代码是怎么炼成的?
- 浮点数为什么不精确?
- 文章错误大全
- Open Source--不要为了开源而开源
- 一不留神,代码就腐化了
- 先做个“键盘侠”, 再来写程序
- 不加断点调试的程序员是好程序员
- 码农必备技能:烂代码的处理之道(上)
- 码农必备技能:烂代码的处理之道(下)
- 学习数据结构有用吗?
- 从现在开始,丰富你的简历
- 那些永不过时的书,你看过几本吗?
- 学好编程必备的一个品质你知道吗?
- 你最爱的 Java
- 搞懂了这几点,你就学会了 Web 编程
- Spring 的本质系列(1) -- 依赖注入
- Spring 本质系列(2)-AOP
- 三层架构和 MVC 那点事儿
- Java 帝国之拨云见日识回调
- 小张的 Duck Typing
- JDBC 的诞生
- JDBC 后传
- 一个不安分的 JDBC 驱动
- Java 帝国之 Java bean (上)
- Java 帝国之 Java bean(下)
- Java 帝国之函数式编程
- Java 帝国之函数式编程(下)
- 关于 Java 初学者需要知道的 10 件事
- JUnit 你不知道的那些事儿
- 圣诞礼物:Java EE 的历史
- Java EE 读书指南
- 给小白的 Java EE 指南
- 给小白的 Java EE 指南(2)
- 给小白的 Java EE 生存指南(3) : XML
- 给小白的 Java EE 生存指南(4) : 一只叫 Tom 的猫
- 给小白的 Java EE 指南(5) : AJAX
- 给小白的 Java EE 生存指南(6) :Java 反射
- 闲聊
- "饿了么"初体验
- 来自大脑的控诉
- 一个高中生是怎么玩自媒体的?
- 尝试 分答
- 到底应不应该上培训班?
- 自学编程中遇到问题怎么办?
- 据说 99%的初级程序员看完后都不迷茫了
- 一行代码引发的“血案”
- 对一个死锁问题的思考
- 通过外包进入名企
- 请开往十年前的今天
- 为什么自学中最好有个师傅指导一下?
- 这个网站值得你花时间投入
- 为什么你无法坚持自学编程?
小李的版本管理系统
前言:这篇文章应读者要求所写,主要聊聊版本管理系统(Version Control System,简称 VCS), 这篇文章不能让你学会一门技术, 但是希望能帮你理解版本管理的原理。 “人肉” 版本管理 小李在大学里很上进,把专业课学好之余还经常跟着老师做点项目, 这些项目都不大, 小李经常一个人就能完成。
在电脑上写代码的时候,小李也有烦恼: 修改了一个 Java 类, 写了一堆代码之后,突然想尝试另外一个方案, 但是又不想放弃辛辛苦苦写的这些代码 -- 万一新方案行不通呢?
怎么办? 那就另存为一个新文件吧,这是每个软件都提供的标准功能。
于是小李的电脑上就出现了这样的情况: Person.java Person_2015_10_12_还有希望.java
Person_2015_10_15_这个算法也不错.java
Person_2015_10_18_老师喜欢这个方案.java
(这其实就是一种版本管理系统, 只不过是“人肉”版的, 我在大学时也这么干过,小微项目没必要搞那么复杂。) 锁定文件:避免互相覆盖 后来老师给小李介绍了一个大一点的项目:在线商城, 类似京东的缩水版,即便如此, 一个人搞不定了。
小李叫来好基友小梁, 两个人意气风发,坚决要把这个项目如期拿下。
两人把工作分了一下,小李负责订单模块, 小梁负责产品模块,还有个公用的部分,谁都可以改。
项目也相应的分了这么几个大目录:Order,Product, Common
两人约定各自闷头开发,每周把代码合并一次测试, 合并的方法就是小梁把所有代码都复制给小李。
第一周相安无事。 第二周相安无事。 第三周两个人就打起来了。
因为小李把小梁的代码复制到自己电脑以后, 发现出了大问题:自己对 Common 目录下的 public.js 做了大改, 代码改动了好几百行,可是这些改动竟然被小梁的 public.js 覆盖掉了, 这一周的改动都丢失了 !
两人吵了半天,最后还得寻求解决办法, 有室友推荐了个软件 BeyondCompare , 可以清晰的比较两个人的代码目录和文件,改动一目了然。 小李和小梁试用了一下,BeyondCompare 很好很强大, 只是改动多了,手工工作量还是挺大的。
干脆一不做,二不休, 开发一个版本控制系统(Version Control System)得了, 彻底解决文件被覆盖的问题。
这个 VCS 有这样的功能: (1) 支持把代码放到一个服务器上, 这样就是本地电脑出了问题也不怕
(2) 任何人如果想对一个文件进行修改, 需要先对该文件做一个操作: checkout , 这会把文件锁住,其他人无法修改
(3) 修改完以后, 需要做一个 checkin 操作, 修改会被发到服务器端保存, 形成新的版本, 并且释放文件锁
(4) 可以支持回退的功能,也就是说,可以回退到之前的版本去。
注: 微软的 Visual SourceSafe 就是这种风格的:文件被一个人独占式的锁住进行修改,如下图,标记为红色的文件就是被特定用户锁住了。 这个 VCS 包括服务器端,主要用来存放代码,进行版本管理。 还有一个客户端,主要用来和服务器端打交道,checkout/check in 代码。 允许冲突:退一步海阔天空 有了这个 VCS , 小李和小梁如虎添翼, 再也不怕合作期间文件互相覆盖的问题了。
只是原定半年要完成的项目,毫无悬念的要延迟了。
老师又给小李和小梁介绍了三个师弟,进来帮助加快进度。
小师弟们对 VCS 不太熟, 经常性的把自己根本不用修改的文件也都 checkout 出来, 并且迟迟不 checkin , 搞的其想修改代码的人根本没法修改。
不止是小师弟们, 连小李和小梁也经常犯类似的错误, 让大家工作起来非常的不爽。
怎么办呢? 小李去找小梁商量: “要不咱把锁文件的功能去掉? “
小梁说: “可是两个人,甚至多个人改了同一个文件怎么办?怎么提交? 以谁的为准?”
举个例子,小李修改了 Person.java , 并且成功的提交到了服务器的 VCS 中。 与此同时,小梁也修改了 Person.java , 提交的时候,系统就会提示: “对不起, 小李已经修改了, 请下载最新版本。”
这时候小梁有两个选择: (1) 把自己的修改先择出来, 放到其他文件中暂存, 然后把服务器端的最新版本(包含小李的修改)下载到本机, 然后在把自己的修改加上去,最后提交到服务器。
(2) 把 VCS 客户端 扩展一下,自动的去取服务器端的最新版本,然后自己本地的 Person.java 做一个 Merge 。
这时候又会出现两种情况: A 小梁和小李的修改位于不同的地方, 没有冲突,这时候就可以自动的 Merge 了,Merge 后向服务器端提交即可
B 小梁和小李对同一行进行的修改,出现了冲突, 这时候只好人工来确定到底用谁的代码了, 人工 Merge 后再想服务器端提交。
鉴于同时改动一个地方的可能性虽然是有的,但是不常见,所以小李和小梁决定:
放弃文件锁, 提供一个 Merge 的功能就可以了。
(注:开源的版本管理系统 CVS, SVN 都是采用的这种方式) 分支:多版本并行 电子商城项目在师弟的帮助下,花了 10 个月才推向市场, 没想到大受欢迎, 高兴之余,也带来了新问题: (1) 已经上市的老版本有不少 Bug 需要修改
(2) 用户提了一大批新功能,有些新功能还需要修改老代码, 有的不需要。
很明显,这就不能在一个代码库中进行修改了, 如果这么做, 那修正了老版本的 Bug 以后就没法发布了,因为也包含新功能的代码,可能还没测试完成。 小李决定, 再次扩展现有的 VCS, 支持分支的功能!
以刚刚发布的产品为基准, 创建一个新的分支 V2.0 , 原来的分支叫 V1.0
由两拨人分别在两个分支上做开发, 这样两者互不冲突, V1.0 的 Bug 修改以后就可以发布, 不用考虑 V2.0
到了某一个时间点,例如 V2.0 开发完成,即将进入测试的时候, 需要把 V1.0 分支的代码修改 Merge 到 V2.0 中来, 为什么要这么做呢?
如果不 Merge 过来, 那 V2.0 岂不还是有老版本遗留的 Bug ?
当然 Merge 的时候有很大的可能会出现“冲突”,需要自动或者人工小心的处理掉。
如果在 V2.0 开发过程中,又有了新的需求, 还可以创建新的分支, 只要选择好基于哪个出发点来创建就行了。 分布式管理:给程序员放权 随着电子商务越来越火,越来越多的人也想用小李和小梁的这套软件搭建独立的一个电子商城系统。
小李决定把源代码开放出去,让网络上的程序员都参与进来开发, 让电子商城系统发展壮大!
互联网的力量远远超出小李的想象, 参与到这个电子商城系统开发的竟然高达几百人。人多了,原来的版本管理系统有点力不从心了, 出现了各种新情况。
首先有些喜欢“小步提交”人感到特别不爽, 因为版本管理系统的服务器是集中式的, 不太稳定,时不时停机, 导致他们无法提交代码。
其次出现了“多人一起竞争”的情况, 多个人都对同一个文件进行了修改,为了获得最新版本,非常麻烦,有时候以为自己拿到了最新版本,可是提交的时候发现还是被别人捷足先登,先提交了,只好再取一次最新版本来合并。
还有些人,喜欢两个人之间先交流一下代码, 然后再提交到服务器上, 由于现在没有合适的技术,只好通过 Email 把文件发来发去的方式来做。
但这些都不是最重要的, 最重要的是有些程序员的代码没有经过好好测试就提交进入了主要的代码库, 惹了不少乱子。
如果在代码提交之前有人做一下代码审查就好了, 这样能够保证代码质量。
之前的代码仓库是集中共享的, 这样是无法解决现在遇到的问题的: 工作之前先把服务器端的代码全部取到本地, 喜欢小步提交的人在本机想怎么折腾就怎么折腾, 没有网络也能玩起来, 只有在必要的时候再提交到集中式的服务器中去。
这么做依然解决不了提交代码时进行评审的需求。
如果心胸再开阔一点,干脆让每个程序员的代码仓库都独立得了, 搞成这样: Linux 创始人 Linus Torvalds
小李决定把这个 Web 版本的源码管理系统叫做 HitHub 。
程序员们在 HitHub 上玩的不亦乐乎,关注他人, 参加开源项目,合作,分享。慢慢的开源世界的主要项目都搬家到 HitHub 上来了。
连一些著名企业在招聘的时候,都要问应聘者的 HitHub 账号,看看他在上面的活动情况。
HitHub 火了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论