我想通过仅读取.git文件夹中的内容来获取当前分支或标签。
我看了很多的解决方案,它们都依赖于执行git status,git branch,git describe,或类似的东西,然后解析输出。但是如果我们不能确定有一个git二进制文件可以调用怎么办?我们不能依赖那个。
对于分支,它看起来几乎非常简单:cat .git/HEAD,但对于标签,它变得有点复杂。我git-flow用来创建我的特征分支和我的标签。当我切换到标签时,我得到:
$ git checkout tags/v0.11.2
Note: checking out 'tags/v0.11.2'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at 86ce70a... Merge branch 'hotfix/0.11.2'
Run Code Online (Sandbox Code Playgroud)
现在内容 at.git/HEAD只是一个散列:86ce70a29fdb2c0bdb0b683d00ab61607d8531de。
如果我想查看与该哈希相关的对象的内容,我会这样做:
$ zlib-flate -uncompress < .git/objects/86/ce70a29fdb2c0bdb0b683d00ab61607d8531de
commit 309tree 9d01f72a058e705a7bc6f9ffc5489096edd2e85a
parent 8c767a0d7538f735c5a537ed14f7f96eb8ae05f8
parent 67d98e0149c72856ddb07ff42197071a4c35fa87
author ####################################### 1520980212 -0600
committer #################################### 1520980212 -0600
Merge branch 'hotfix/0.11.2'
Run Code Online (Sandbox Code Playgroud)
最后一行是我在提交中放入的消息,但这并不意味着我可以从那里获取标签版本,因为每次提交的消息都不同。
我还尝试在.git运行的文件夹中找到包含该哈希的任何文件:
$ grep -ilr `cat .git/HEAD` .git/
.git/gitk.cache
.git/HEAD
.git/FETCH_HEAD
.git/logs/HEAD
.git/logs/refs/heads/master
.git/logs/refs/remotes/origin/master
Run Code Online (Sandbox Code Playgroud)
但是没有一个文件有任何东西指向我的标签名称。
我的想法不多了。任何光线都会非常感激。
您也可以假设(或要求)安装了 Git,因为您最接近能够生成 的输出的方法git describe是从 复制算法git describe。您还需要至少访问git rev-parse和git reflog如果您尝试我在这里建议的想法,
请注意,evengit describe可能不会生成您用于运行的标记名称git checkout。如果您有两个指向相同的标签提交的标签,则事后不可能从修订哈希 ID 转到标签名称,因为检查任一标签都会获得相同的状态\xe2\x80\x94(除了 reflog)痕迹:
您可以查看HEAD引用日志(如果存在),因为它会在此处git checkout写入一条消息以及哈希 ID。对于git checkout检查标签的命令,消息为checkout: moving from <name-or-ID> to <tag-name>。因此HEAD已分离,HEAD@{0}匹配的引用日志条目moving from .* to (.*)$和末尾捕获的正则表达式是有效的标签名称并正在运行git rev-parse $tag^{commit} produces the correct hash ID, the last checkout was no doubt given that tag name. (Adjust the regexp syntax as necessary depending on which RE grammar it uses.)
您可以直接打开并读取.git/logs/HEAD以避免使用git二进制文件,但我认为 reflog 格式至少已更改一次,并且不能保证它将来会稳定。使用确实能提供一定保证的工具可能会更好。