git积累的一些点

148 阅读3分钟

git很奇怪,平常使用的时候,明明是版本控制工具(VSC),但是在git的man page上面,清楚写了一个解释:the stupid content tracker, Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals. git底层的数据结构存在以下几种,以下使用伪代码示意:

type blob = array<byte>
type tree = map<string, tree | blob>
type commit = struct {
    parents: array<commit>
    author: string
    message: string
    snapshot: tree_id
}
type object = blob | tree | commit
type objects = map<string, object>

def store(o) {
    id = sha1(0)
    objects[id] = o
}

def load(id) {
    return obejcts[id]
}

学习git最好的教材就是man page和pro git book,在man page中使用连字符连接之后查询,比如man git-add等,文档非常详细,本文中使用的是git最新版本2.26。
首先我们会在空目录中执行命令git init,命令执行后,目录中会新建.git的目录,这个目录将作为git数据库目录保存用户操作的数据,分支的映射等。将一串字符串存入git中echo "hello world" | git hash-object -w --stdin其中的-w表示将hash的结果写入git数据库中,--stdin这个是说读取标准的输入流。

git init
echo
可以看到sha1得到的40位hash值的前2位作为文件夹,以其他hash值作为文件名保存数据,可以使用如下的命令来查看:git cat-file -p [hash]其中-p代表pretty display,还有-t代表类型。
git fetch不会改变本地的HEAD指向,即不会做merge的操作
git clone --shalldow只会clone最近的提交
git init --bare用于新建git server
git checkout用于改变HEAD二级指针
git add -p/-i 可以选择提交的path
git blame file查看file的修改记录,然后可以使用git show查看
git show master:hello.txt 查看master分支下的hello.txt文件的信息
git update-index --add --cache-info 10064,3b18e512dba79e4c8300dd08aeb37f8e728b8dad,hello.txt 将工作区的内容加入到index(stage)
git write-tree将index中的内容生成一个树
git commit-tree [hash] -p [parent_hash] [-m message]生成commit tree git ls-files显示working area或者stage中的文件
通过使用上述的命令,可以在数据库中生成2个tree,然后使用commit-tree可以将他们连接起来,但是当使用git log的时候是没有记录的,因为master没有关联任何commit tree hash,所以使用git log [commit hash]可以看到内容。
很明显,在实际开发中,这样是很不方便的
我们可以将git branch(reference)跟commit tree联系起来,使用echo d9a862fb8c531c5240265cacf6c04d4d372be9a6 > .git/refs/heads/master 如果要移动master分支指向其他的commit tree,使用命令:git update-ref refs/heads/master e398589c547908cbc8aba60b6b0c4ac88601a867这个时候使用命令git show master:hello.txt显示master分支中的内容了。这个里面有一个很明显的点,就是master是一个指针,指向commit tree,而head是一个二级指针,指向master,即head->master->commit tree。git checkout是个有多种表达的命令,一是可以改变head的指向,即所谓的切换分支,这个新版本中分离出来,使用git switch命令,另外就是还原working tree的文件,还是使用man page原文吧(restore working tree files),还有就是有一个点,在checkout中也存在这-p的参数,这个参数就是可以选择patch去还原。