脑图
介绍
Git是一个分布式版本控制系统,能够使得身处不同物理位置的开发者紧密的协同开发一个软件.也能够控制开发者能够查阅与修改的代码权限.简而言之,git是多人协同开发必不可少的工具,下面我来逐一介绍git的一些概念:
版本库(repository)
版本库是一个简单的数据库.提供版本库自身与所有文件的副本.
它主要维护2种数据结构:对象库与索引.
对象库(object store)
对象库包含三个部分:原子对象, 存储系统与一个简单的数据库.
原子对象
原子对象是版本库的基础对象,分为四种类型:
块(blob)
每一个文件的版本表示为块,它只被目录树引用.
目录树(tree)
保存blob的标识符,路径名和一个目录中所有文件的元数据.
引用blob对象,每一次变化(比如新增了文件)都会产生一个新的树,新树包含着所有文件,旧树则包含着除了新增文件文件外的其他文件.
目录树只会包含该目录下的文件与子目录的信息,不会包含子目录下的文件及孙子目录的信息.
提交(commit)
保存版本库中每一次变化的元数据,诸如作者,提交者等.每一个提交对象都指向一个目录树对象.
标签(tag)
标签分为轻量级标签与标注
轻量级标签是一个提交对象的引用,通常被版本库视为私有.
标注则可以根据RFC4880来使用GnuPG密匙进行数字签名.
索引(index)
索引是临时,动态的二进制文件,描述整个版本库的目录结构.
不包含任何文件内容,只追踪你想要提交的那些内容.
添加文件到索引的操作被称为暂存.
工作目录
文件所在目录
内容追踪与存储机制
只追踪内容
git只追踪内容,如果两个文件的内容完全一样,就算名字不一样,目录结构不一样,git也只会保存其中一份,用以,并以这一份文件代指其他内容一样的文件.
对文件变化的处理
文件发生改变时,会计算新的SHA1值,然后将新的blob添加到对象库中.
文件差异的存储
第一次存储时,会储存全部文件.之后则只会存储不同文件中有差异的那一部分,而不是又把文件再完整存储一份.
文件分类
已追踪(Tracked)
已在版本库或已被暂存到索引中的文件.
被忽略(Ignored)
被索引忽视的文件
未追踪(Untracked)
未被忽略且未被索引的文件
提交(commit)
绝对提交名
散列id
相对提交名
引用和符号引用:
.git/heads代表本地分支
.git/remotes代表远程分支
提交历史记录
提交图: 使用gitk即可查看版本库的DAG.
查找提交
查找错误提交
git bisect:该指令会让用户判断哪些提交没问题,哪些提交有问题,最后找出有问题的提交.
git blame: 获取每一行是谁修改的和那一次提交做出了变更.
可达提交
把提交看成一棵树,可达提交就是指从某一个节点开始,他的所有父节点及其父节点的兄弟节点,都是可达提交的节点.
合并
概要
要合并的分支必须位于同一个版本库.
分支冲突时,git不解决冲突,并且会在索引中标价为未合并(unmerged).
git merge的当前分支是目标分支.
冲突的合并
这里列举几条解决冲突的建议:
- 使用diff指令查看工作目录与索引的差异,它会通过额外的+与-符号来表示相对于最终版本的来之余多个源的变化,方便找出冲突
- git status则是一个更好的选择,相比diff会展示所有细节,status只展示未合并与有冲突的文件.
- git log --merge --left-right -p 这个指令将会显示2个提交之间的冲突
- 建议提交大型修改之后,修复冲突的复杂性.高频率小型提交是更合适的实践.
回滚
git reset --hard [
这条指令会把工作目录和索引还原到某一次提交.常用的git reset --hard HEAD^则会回退至当前分支的上一个版本.