Git对象
简单了解下git对象,有助于对分支的理解,在git系统中共有四种对象:blob对象,commit对象,tree对象,tag对象
这四种对象存储数据的格式相同,格式如下:
content:表示存储的数据内容
head:表示对象的头部信息
object type:表示对象类型,为字符串,取值为"blob","commit","tree","tag"
whitespace:一个空格
content byte size:content的大小
NUL:空字符' '
Git按照这种数据格式存储对象,并使用SHA1摘要算法对整个对象提取出40个字符,并以前两个字符作为文件夹名称,
后38个字符作为对象的文件名存储在文件夹中,git所有的对象全部存放在./git/objects/下,例如:
- blob对象:用来存储Git仓库中的文件快照
- tree对象:用来管理文件或者目录, 它记录了若干个blob对象或者其它的tree对象
- commit对象:包含着指向树对象的指针和作者,时间,提交信息
- tag对象:包括一个对象名(SHA1签名)对象类型、标签名、标签创建人的名字, 如果是附注标签,则还有标签信息
查看对象:
git cat-file 对象ID
常用参数选项:-t表示查看对象类型, -p表示查看对象内容
例:查看某次提交后,git各种对象的组织结构:
因为1.txt和2.txt都为空文件,所以这两个文件被同一个blob对象表示
现在我修改这个两个文件,然后在提交:
可以看出commit对象之间以链表的形式组织起来,当前的提交对象中记录了上次提交对象的SHA1校验和
另外在git命令行中有如下的高亮显示:
这里master是一个分支,在我们执行git init时,git会默认创建一个master分支,HEAD始终指向本地当前的分支
分支操作
-
创建分支
git branch 分支名称
例:创建一个名为Testing的分支
从例子中可以看出新创建的分支指向最近一次的commit对象
可以使用git log --decorate命令来查看当前所有分支指向的对象:
修改文件然后提交,在查看所有分支所指对象:
Testing分支和master分支指向不同的提交对象 -
切换分支
git checkout 分支名称
例:切换到Testing分支
可以看出HEAD已经指向Testging分支当前处于Testing分支下,现在在做一个有意思的测试,先查看一个文本文件的内容:
然后修改这个文件内容为"Learning git",然后在提交修改,然后把分支切到master:
可以看出切换分支后,2.txt的文件内容被恢复到master分支最后一次提交时的内容可以使用git log命令简单查看下各分支的提交历史以及分叉情况:
-
合并分支
git merge 分支名称
-
无分歧合并
如果不知道本地当前用的是哪个分支,则可以使用:git branch
来查看:
git branch命令列出了所有的分支,前面带有"*"的表示本地当前使用的分支现在切回master分支,在创建另一个新的分支Test1并切换到这个分支:
此时2.txt文件中的内容如下:
紧接着修改2.txt内容如下:
然后提交修改,那么此时所有分支结构图如下图:
此时切到master分支,使用合并分支命令,将Test1合并到master分支:
此时2.txt内容如下:
而此时的分支结构如下:
当Git在合并master和Test1分支时,从Test1分支出发可以找到master分支最后一次commit对象时,此时
Git只是将master的指向前移,使其指向Test1即可;在这种情况下没有需要解决的分歧,所以也可以成为
无分歧合并(也称快进)
-
-
删除分支
git branch -d 分支名称
master和Test1合并后,也就不需要Test1分支了,此时可以删除它:
-
有分歧的分支合并
经过上面一通操作后,本地所有分支结构如下:
此时Testing分支和master之间无法通过一个分支找到另一个分支,第二次提交是两个分支公共的祖先,Git会使用
Testing分支和master分支的最后一次提交已经公共的第二次提交做一个三方合并,并生成一个新的提交对象,因
为当前处于master分支并执行git merge Testing命令,所以master指向这个新的提交对象:
but....,合并时遇到了冲突,不要慌,这很正常,因为两个分支中2.txt的第一行内容不同,所以Git合并时会有冲突
,所以Git不会为此次合并创建一个合并提交对象,此时执行git status命令查看状态:
在查看下2.txt内容:
可以看出Git已经将有冲突的内容写入到2.txt中,并使用"======="分割开来,但是Git并没有将其添加到暂存区,
这时候需要我们手动修改2.txt,然后对冲突文件使用git add 命令将其标记为冲突已经解决,当然也可以不做任
何修改,直接暂存:
-
分支管理
查看分支列表git branch
例:
分支前面有"*"则表示该分支是当前正在使用的分支
查看每个分支最后一次提交:git branch -v
例:
查看当前分支已经合并的分支:git branch --merged
前面有"*"表示已经当前分支,没有"*"的表示已经被合并的分支
查看没有被合并的分支
git branch --no-merged
由于当前仓库就两个分支,而且Testing分支已经被合并,所以这里新建一个分支,并修改文件内容,然后提交修改:
切换到Test1分支后master就是未合并分支,为合并分支使用-d参数无法删除:
可以使用-D参数强行删除