首先,光看标题你就知道这是一个比较奇葩的需求了。大多数情况下,如果你需要操作一个Git版本库,那你系统里面肯定安装了Git。这次的需求是这样的:我需要在Unity打包的时候获取版本,而打包的方式有可能是用打包机自动打包或者是手动触发打包。用自动构建非常简单,只需要一个git describe就可以知道当前的版本了。然而对于手动触发来说,因为它有可能是在Windows下触发的,而Windows下的git有自己的一套运行环境,不是很方便直接调用。所以就想有什么办法能够直接读取到Git库的版本。

首先,我们知道,Git会将库的所有信息放在.git目录下。如果我们要知道当前的版本,那么直接读取.git/HEAD文件就可以了。在部分情况下,这个文件会存放一个提交的Hash,这就是我们要的版本。
当然,在另外一部分情况下,它的内容是以ref:开头的一个字符串,指示你应该到后面跟着的那个文件名里面去找对应的文件。

同理,如果你要找指定分支的版本,直接找.git/refs/heads目录。这个目录存放了所有分支的最新版本的Hash信息。

如果我要找的是一个标签的信息,那么也是一样。.git/refs/tags目录下存放了标签的Hash信息,只要知道了这个Hash信息,就可以找到对应的标签信息了。当然,如果你在这个目录下没找到任何文件,说明Git的内置的GC功能将这些标签压缩了,你需要打开.git/packed-refs这个文件,里面便是剩下的标签的Hash了。

有了Hash,我们应该怎么读取对应的内容呢?答案很简单,查看你的.git/objects目录。这里面存放了Git整个数据库的文件。你只需要根据你的Hash,进入对应的文件夹,找到对应的文件就可以了。这个文件是经过了Zlib压缩的,所以你只要调用Zlib解压就行。使用zlib-flate.exe -uncompress < FILENAME 命令可以直接解压并显示文件的内容,你可以发现一个提交的内容大概是这样的:

commit 732tree fe4d21d1f65c6e25f207791a2957c4668ea06062
parent ebfb123aed8ad35778777f3aca561019ba968775
author Jim Jiang <jim@lotlab.org> 1610514358 +0800
committer Jim Jiang <jim@lotlab.org> 1610514358 +0800

提交信息

而标签的内容大概是这样的:

tag 139object 6e875fa190b7a690a7dd6ac677d7a1f35f0e7899
type commit
tag 0.8.13
tagger Jim Jiang <jim@lotlab.org> 1610508422 +0800

打一个标签

非常好读取的格式对吧。不过这里有个坑的地方,就是上面的732tree实际上是732\0tree,中间是有一个文本结束符的。如果你尝试用某些语言的string的话,有可能会直接在这里截断。

当然,大部分情况下,你并不能直接在文件夹找到这些文件。Git的GC会将一些旧的文件压缩到一个大文件中。你可以在.git/objects/pack文件夹下找到这些打包好的文件。这篇博客介绍了要怎么解压读取里面的数据。不过因为我只需要最新的版本的标签,所以没有详细了解内部的原理。

分类: 未分类

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注