-
什么是版本控制系统
- 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的文本文件,而且可以对任何类型的文件进行版本控制。
-
有哪些版本控制系统
-
VSS
-
特点
- 文件是独占式锁定,也就说一个人编辑文件,其他人就不能编辑
- 只支持Windows系统
- VSS自身安全性较差
-
功能
- VSS(Visual Source Safe)是Microsoft Visual Studio工作套件中一个软件,用来管理文件的版本,几乎可以管理任何项目,重点是他和Visual Studio集成的很好,所以说使用很方便
-
-
SVN
-
特点
- 必须联网,如果开发人员断网了,那么就只能在本地编辑文件,不能提交,也不能获取远程的代码
- 对服务器性能要求高,数据库的容量占用很高
- 由于设计的缺点,使用它在切换分支随着代码量的增高而变慢
- 不太适合开源项目的开发
-
功能
- SVN(Subversion)是一个开源的版本控制系统,如何把他和VSS相比,那么他除了基本的文件管理功能外,他还有分支功能,从而解决的独占式文件编辑,因为不同的开发人员可以在不同的分支上开发,到需要的时候在合并到主分支,这也使得开发人员的工作模式发生了很大的改变
-
-
Git
-
特点
- 适合分布式开发,因为他相对于每个用户都有一个完整的仓库
- 对服务器的压力不需要要求很高,因为大部分操作都在用户的本地发生
- 代码的保密性不太好,每个开发者都有一个仓库的拷贝版本
-
功能
- Git是一个开源的分布式控制系统,他的优点是可以非常高效,灵活的管理各种大小的项目
-
-
-
工作流程
-
SVN是集中式
- SVN有一个服务器,在服务器上面放置了一个代码仓库,工作的时候每个用户从远程服务器的代码仓库里面拉取需要的代码,工作完成后,或者需要提交的时候将代码推送到远程仓库。如果中间没有网络了,或者服务器出问题了,就不能推送或拉取了,这也是这样的版本控制系统的弊端,但也有好处,就是学习简单容易理解。
- 用户=>远程仓库
-
Git是分布式
- Git在工作的时候,每个用户都有一个本地的代码仓库,工作的时候都是先提交到本地仓库,然后在推送到远程,这样的好处是,用户没有网络,或者服务器出问题了,都可以在本地工作,并把记录提交到本地,这样记录就是完整的,等有网络了在推送到远程,同时由于每个用户都对远程的仓库有个本地仓库的拷贝,所以即使远程仓库出问题了,那么也很容易恢复,但来的问题就是相对集中式版本控制要复杂一些。
- 用户=>本地仓库=>远程仓库
-
-
理解版本库(仓库)
-
什么是版本库(仓库)
-
概念
- 版本库就是管理文件的仓库
-
版本库
-
Git版本库
- 通过git init命令创建了一个版本库,也可以称为仓库(repository),他是一个很简单的数据库,里面保存着git的数据和修改历史等信息
- 项目根目录有一个.git的隐藏文件夹,这就是一个版本库
-
-
-
版本库(仓库)结构
-
Git结构
- . ├── COMMIT_EDITMSG ├── FETCH_HEAD ├── HEAD ├── ORIG_HEAD ├── config ├── description ├── hooks │ ├── applypatch-msg.sample │ ├── commit-msg.sample │ ├── post-update.sample │ ├── pre-applypatch.sample │ ├── pre-commit.sample │ ├── pre-push.sample │ ├── pre-rebase.sample │ ├── prepare-commit-msg.sample │ └── update.sample ├── index ├── info │ └── exclude ├── logs │ ├── HEAD │ └── refs │ ├── heads │ │ └── master │ └── remotes │ └── origin │ └── master ├── objects │ ├── 08 │ │ └── 0dfceca6e3db726765939ac0ceeebb457094f9 │ ├── 13 │ │ └── cfa6725455a90ff27b6c72e7c24ab7e263f578 │ ├── 26 │ │ └── b921eb5d706ae933731f09d31a5200d830fe9c │ ├── 35 │ │ └── 41a24ce8297ef24e31c1f6470e76cb3564dd6f │ ├── 40 │ │ └── 521fe9767560ffd9de8617d2ad7ea4b47943a1 │ ├── 49 │ ├── info │ └── pack └── refs ├── heads │ └── master ├── remotes │ └── origin │ └── master └── tags └── v1.0.0
- 其中一些文件和目录很重要表示:
-
-
HEAD文件:保存当前指向的分支
config目录:仓库的配置信息就保存到这里,其中用户的名称,Email就是保存到这里
hooks目录:钩子保存目录,我们在后面的课程讲解
index文件:保存暂存区信息
objects目录:保存对象的目录,其中我们添加的文件,代码就保存到这里,其中还包括git的其他对象,比如:树对象
refs目录:保存一些引用
heads:保存本地分支的目录
remotes:保存远程仓库的目录
tags:保存tag的目录
其中要注意的是暂存相关的信息是本地仓库的,不会提交到远程仓库,提交到远程仓库的都是对象,也就是objects目录下的内容。
-
Git对象
-
什么是Git对象
- 以Git对象类型保存数据的文件
- Git对象是Git中最重要的概念,他包含了你的原始数据(你提交的代码,文件,视频等),提交历史,作者信息,日期等信息。
-
数据类型
- git中对象只有4中类型:
-
-
块:blob,二进制大对象(binary large object),是计算机中的一个专业术语,数据库中也有这个类型,自己提交的任何类型的文件对git来说都是这种类型,不包括文件名
-
目录树:tree,用来构建完整的目录结构的对象,包括目录的名字,创建日期,权限等信息,树对象指向块,表示这个树下面有哪些文件
-
提交:commit,每次对版本库更改后,创建的提交,包括,作者,提交者,日期,备注,每一个提交对象指向一个或多个目录树,表示更改了哪些树对象;大多数提交只有一个父提交,但在后面的章节会讲到多个父提交的情况;第一个提交没有父提交
-
标签:tag,他是一种简单类型,就是指向某个提交,分两种,有一种可以有备注信息,有一种没有
-
暂存区(索引)
-
什么是暂存区(索引)
- 下一次待提交的列表
-
index文件
- index文件的作用是将哪些文件标记为下一次待提交列表
- 执行git add命令就是将文件添加到暂存区(准确来说是标志,他不会将文件的真实内容保存到index文件里面)
-
-
在Git中文件的唯一标识
-
电脑中文件的唯一标识
- 我们都知道在电脑中,标识一个是靠目录和文件名,比如:
-
/Users/smile/index.html
我们不能在相同的目录中创建两个文件名一样的文件。
- Git中文件的唯一标识
- SHA1散列码
- Git中的SHA1散列码
- Git中却不是根据目录和文件名来标识文件的,而是根据内容。是计算文件内容的SHA1散列码,因此文件名相同不能说是同一个文件,只有两个文件的内容相同才可以说是同一个文件
- Git存放SHA1散列码的目录
- git目录下面的objects目录里面的文件就是SHA1散列码。
- Git如何通过SHA1散列码创建文件目录
- SHA1是一个160位,通常我们都是用40位的十六进制数来标识,比如:
080dfceca6e3db726765939ac0ceeebb457094f9,在objects目录中,Git用散列码的前两位创建一个目录,然后把剩余位数当做文件名存到该目录。
- 所以我们就看到如下结构:
08 └──0dfceca6e3db726765939ac0ceeebb457094f9
这样做的原因是有些文件系统,如果一个目录的文件特别多,打开这个目录就很慢,所以Git使用这样的方法分目录。
- 有重复的SHA1码吗
- 理论上SHA1是不可能重复的。
至于会不会重复,可以这样告诉你,比如:Linux内核这项目,目前有不小于45万对象,也只需要11字符就能保存唯一性了。
同时SHA1的重复碰撞的概率是很小了,至于有多小,举个例子:如果地球上65亿人类都在同时编程,每人每秒都产生和Linux内容相同的历史,也就是360万个对象的代码,并都提交到一个仓库中,这样持续四年,才有可能重复。你可以想象下这个概率多小。
- 简短的SHA1码
- Git十分智能,在用到SHA1码的时候,可以提供不小于4位的SHA1码,Git就可以处理了。
比如通过git show可以查看某个历史的提交信息,如下代码都是等效的:
git log 080dfceca6e3db726765939ac0ceeebb457094f9 git log 080dfceca6e3db7267 git log 080d
-
Git如何追踪文件内容和文件名
- Git追踪文件内容的方式是通过object目录保存的blob文件
- 文件名,目录的追踪方式是通过树对象,也是保存到objects目录中
- 那文件的改名,移动目录只是更改相应的树对象,而对应内容的object不会有任何改变
-
Git如何保存对象内容
-
概念
- Git 保存变更后的完整文件
-
区别
- Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统(CVS,Subversion,Perforce,Bazaar 等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容
-
特点
- Git每次都保存修改后的整体文件,这样会导致文件特别大,所以Git通过一种打包文件(pack file)机制来高效的存储文件。
-
要创建打包文件,Git会首先通过算法确定相似文件,将共同的内容提取出来保存一份,之后再保存单个文件与这个打包文件的差异
-
Git对象总结
-
初始化
- 创建一个空的Git仓库
-
git init
- 添加到本地仓库
- 执行git add命令添加到暂存区:
git add hello.txt
- 查看添加到objects目录里的文件内容
- 通过cat-file查看objects目录里的文件内容,只是他不是保存的文本文件,所以编辑打开是不能查看的:
git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 输出:
hello world
其中-p参数是表示打印object的内容,当然还有其他参数,直接输入git cat-file即可查看,常用的有:
-t:表示打印object类型
-s:查看对象大小
下面我们来看看树对象。
- 查看树对象与文件
- 查看目录下的所有文件:
git ls-files -s
- 给暂存区的信息创建为一个树对象
- git write-tree
- 提交树对象
- git commit-tree 4924
- 显示各种类型的对象
- git show <sha1>
- 提交标签
- git tag -m "publish v1.0.0" v1.0.0 8cee
- 查看标签内容
- git rev-parse v1.0.0
-
获取Git使用帮助
- git help git help git help pull
-
配置Git
- git config --global user.name "ixueadev" git config --global user.email "[email protected]"
-
创建一个仓库
- git init
-
查看仓库状态
- git status
-
添加文件到Git中
- git add
-
提交更新
- git commit -m "message"
-
推送更新
- git push
-
拉取文件
- git pull
-
还原文件
- git reset --hard HEAD~
-
为什么会有冲突
- 如果两个人同时编辑一个文件的同一行,然后一方先提交,另一方也编辑了,然后更新了,导致的结果就是有可能发生冲突;所谓冲突就是Git不支持该选那一部分代码了,要你手动来选择,选择好了告诉Git。
-
解决冲突
-
拉取代码
- 先执行git pull命令,拉取冲突的内容
-
查看状态
- 用git status命令查看一下状态 , 可以发现文件前面的状态是both modified,这表示该文件有冲突
-
查看冲突文件
- 查看内容如下: <<<<<<< HEAD Hello index new other ======= Hello index new hi
-
514629604932a47d2894360215ef8e9fc133f6c1 - <<<<<<< HEAD到=======表示我们自己更改的(也就是执行git pull命令的这人) - =======到>>>>>>> 514629604932a47d2894360215ef8e9fc133f6c1表示是远程仓库上的修改。 - <<<<<<< HEAD ,======= , >>>>>>> 删除了这些符号,同时将内容更改为你认为正确的! - 最关键的一步就是,使用git add命令将这个文件标记为已经解决的。 - 提交修改文件,推送到远程仓库
-
为什么需要发布一个版本
- 如果下次上线项目出现问题,可以通过发布的版本快速回滚解决问题
-
如何发布
- 其实需要用到Git的一个tag功能,说白了就是在当前仓库的当前状态时创建一个标签,下次如果出现什么问题了,我们就可以通过该tag找到这个版本的代码。 将当前版本创建一个tag的命令如下
- 创建一个tag的命令如下:
git tag v1.0.0 - 查看现在有哪些版本呢? 可以通过如下命令:
git tag - 推送标签到Github仓库 默认执行git push命令只会推送代码,推送tag需要加一些参数。
git push --tags
-
查看工作区状态和暂存区操作
- 执行git status命令查看工作区状态
- 使用 git add . 命令将所有文件添加到暂存区
- 执行 git rm --cached hi.txt ,移除暂存区的文件
-
储存工作区
-
工作问题
- 假设我们有这样一个需求,你正在开发,突然接到一个紧急修复Bug的事,但是你当前目录还没有干完,所以不能把本地提交上去
-
解决方法
-
单独用一个目录创建一个分支解决Bug
-
将当前文件拷贝出来,然后新建分支解决Bug,解决完了拷贝原来的文件到当前目录然后在继续工作
-
将当前目录的通过Git提供的存储工作区命令保存
-
储存工作区 解决方法
- #先将文件保存到暂存区(当前的分支) git add hello.txt
-
-
-
#储存工作区 git stash save - 查看该工作区状态发现是干净了。现在你可以切换到其他分支工作,修复Bug - 假设现在修复完了,我们执行如下命令恢复工作空间:
git stash pop - 恢复完成后,查看工作区状态发现和储存前一样。但一定要注意,储存是保持到本地的。 - git stash list:查看有哪些储存 - git stash show -p stash@{0}:查看这个stash
XMind: ZEN - Trial Version