参考资料
版本控制是什么
概念
版本控制最主要的功能就是追踪文件的变更。它将什么时候、什么人更改了文件的什么内容等信息忠实地了记录下来。每一次文件的改变,文件的版本号都将增加。除了记录版本变更外,版本控制的另一个重要功能是并行开发。软件开发往往是多人协同作业,版本控制可以有效地解决版本的同步以及不同开发者之间的开发通信问题,提高协同开发的效率。并行开发中最常见的不同版本软件的错误(Bug)修正问题也可以通过版本控制中分支与合并的方法有效地解决。
论必要性
- 单人单功能开发 -- 至少你需要在开发在发现思路错误时快速退回到上一个正确的还原点
- 单人多功能并行 + Bug fix -- 需要灵活的在多个功能点分支和Bug解决分支间切换
- 多人多功能点 -- 需要多人间同步最新工作成果
- 多人多功能点多版本多基线 -- 需要使用不同分支和Tag标识开发版本和里程碑,并且通过配置管理员将新的Feather和Bug Fix配置到不同的版本。
基础功能
- 检入(Checkin)检出(Checkout)控制
- 分支合并
- 历史记录
常见工具
- CVS -- Dick Grune在1984年~1985年基于RCS开发的一个客户一服务器架构的版本控制软件,长久以来一直是免费版本控制软件的主要选择。
- SVN -- SVN是一个比较好的开源版本控制工具
- Git -- 今天的主题
Git的历史
引用:廖雪峰的资料
很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。 Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢? 事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码! 你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。 不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。 安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图【破】【解】BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。 Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的: Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。 Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。 历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。
安装
Linux
sudo apt-get install git
Mac
首先安装homebrew,然后通过homebrew安装Git,具体方法请参考homebrew的文档:brew.sh/。
brew install
Windows
首先安装Liunx子系统,然后参考Linux安装指南
本地版本
创建本地仓库
创建仓库的过程其实就是将一个普通的文件夹升级为一个具备版本控制能力的文件夹
# 创建文件夹 mkdir hello-git # 改变工作目录到hello-git cd hello-git # 初始化Git相当将文件夹升级为仓库 git init
实际上git命令会在文件夹下创建一个.git文件夹所有后面神奇的版本控制功能都是通过这个文件夹里面的这些神奇的文件实现的。 我们可以通过事先仰望一下后面用到了会给大家一一解析
tree -a
将文件添加到版本库
首先我们创建一个文件
# 创建一个文件 echo 'Step01 Create File' >> README.md
然后我们查看一下版本哭的状态
git status
我们会发现Git会提示我们这个文件属于未跟踪文件 如果在Vscode中
文件也会用绿色表示
其实Git的版本控制的要求也就是说即使处于版本库文件夹内的文件你也要明确的声明需要版本控制功能git才会跟踪他的版本变化。这样的白名单做法是为了防止多一些诸如编译结果文件,日志文件,开发工具本地配置等完全没有必要进行版本控制的文件进行了跟踪占用没必要的系统资源。
将文件添加到版本库
git add README.md
添加完成后我么你发现这个时候文件状态变为要提交状态。 这是因为相对于旧的版本记录Git发现新添加了一个文件。我们试用git status就可以看到这样的提示。
从暂存中恢复文件
一旦文件被提交到版本库实际上Git就会将README文件的快照已经缓存了一份到暂存盘,如果有需要你还可以将这个镜像取出来。不信的话我们可以做一个小实验。
# 删除文件 rm -f README.md # 从缓存区检出文件 git checkout README.md # 查看文件 cat README.md
另外如果你想一次添加多个和放弃跟踪可以参考下面的方法
添加多个文件跟踪
# 添加本目录下文件具备递归文件夹功能 git add .
取消跟踪
# 取消添加 git rm --cached README.md
忽略文件.gitignore
如果你希望在使用 add .的时候忽略某一个文件可以在目录下创建一个 .gitignore文件
#.gitignore # 忽略dist.js dist.js
这个时候就可以让git文件放弃对此文件的关注。 当然如果你曾经将忽略的文件天交到git的跟踪列表中的话,即使你你在ignore文件中声明了git也不会主动放弃跟踪
提交代码commit
提交代码是指已经完成了某一阶段的代码开发比如你完成了某一个代码功能(features)或者修改了某一个代码缺陷(fix),你就可以创建一次代码提交。
git commit -m 'add README.js'
提交的本质是讲原有工作区的代码提交到本地仓库中,我们看一下提交前后的对比。
保存临时工作成果Stash
在你需要并行做好几件事的时候,比如你正在开发一个功能程序开发到一半,有一个紧急的bug需要处理又或者你突然对另外一个新特性来了思路,但是你现有的代码还在一个中间状态甚至编译都有问题。你需要可定需要一个功能保存现在的工作现场,然后去干另外一件事。这个时候stash功能就可以帮助你解决。
# 建立一个临时的工作成果 echo 'TEMP xxxx' >> README.md # 保存工作现场到栈 git stash # 从栈中弹出工作现场 git stash pop
放弃修改
git restore .
回退到上一个提交
首先我们修改一下文件,再做一次提交
echo 'STEP02 ADD FUN01' >> README.md # 参数-a 是先添加到缓冲区再提交的意思 git commit -am 'README ADD STEP02'
这个时候我们会有两个提交记录 我们可以用git log检查一下
git log git log –-oneline # 简短日志 git reflog # 操作记录 包括回退记录也会被显示
# 只是版本回退 不更新工作区 git reset HEAD^ # 不但版本回退 也会更新工作区(文件目录)的文件到上一个版本 git reset --hard HEAD^
工作区(Working Directory)、缓存区(Stage)、版本库(Repository)小结
- 工作区 --- 就是文件目录因为你的开发工作就是对文件的修改所以叫做工作区
- 缓存区 --- 没有提交前也就是没有完成完成工作结果代码保存的地方
- 版本库 --- 每一个工作结果的时间带会被按照不同的提交记录保存起来