0

我正在使用git rev-list --all --format="%H%n%B"检索 git 存储库的所有(可访问的)提交。

我需要能够将生成的输出解析为提交哈希原始正文的单独字段。

-> 是否有任何可靠的方法来格式化输出以便可以对其进行解析?

虽然提交哈希是固定长度的,但原始正文中的行数未知,需要某种分隔符。我曾考虑将输出包装在 xml 之类的标签中,例如--format="<record>%H%n%B</record>",但这有一个明显的缺点,即</record>如果将字符串插入原始正文中,则会破坏解析器。当然,我可以使分隔符更复杂,以降低有人将它们插入提交消息的风险,但我真正需要的是一个在技术上不能成为原始正文一部分的字符。我尝试使用 ASCII 控制字符作为记录分隔符“\x1F”。但是,它并没有按预期插入输出,而是按原样打印。


根据torek的回复(谢谢!)我能够创建一个小的 python 函数:

from subprocess import Popen, PIPE
from codecs import decode

directory = '/path/to/git/repo'

git_rev_list = Popen(['git', '-C', directory, 'rev-list', '--all'], stdout=PIPE)
git_cat_file = Popen(['git', '-C', directory, 'cat-file', '--batch'],
                     stdin=git_rev_list.stdout, stdout=PIPE)
while True:
    line = git_cat_file.stdout.readline()
    try:
        hash_, type_, bytes_ = map(decode, line.split())
    except ValueError:
        break
    content = decode(git_cat_file.stdout.read(int(bytes_)))
    if type_ == 'commit':
        yield _get_commit(hash_, content)
    git_cat_file.stdout.readline()
4

2 回答 2

2

要通过格式插入 ASCII RS,请使用%x1F,而不是\x1F

一般来说,你最好的选择是单独进行身体检索,因为%B它可以扩展到任何东西并且没有可用的保护。一次运行每个提交通常很容易git log --no-walk --pretty=format:%B,只是速度很慢。

为了加快速度,您可以使用git cat-file --batch或类似的方法,它确实提供了一种在程序中解析数据的简单方法:每个对象前面都有它的大小。提交对象也很容易解析,因为%B等效的只是“前两个相邻换行符之后的所有内容”。因此,而不是:

git rev-list --all --format=something-tricky | ...

您可以使用:

git rev-list --all | git cat-file --batch | ...

并修改预期的输入格式以预期<hash> <type> <size-in-bytes> LF <bytes>. 或者,向 中添加格式指令以git cat-file放弃对象类型(但我会保留它,因为这意味着您可以将提交与带注释的标签区分开来)。

于 2017-08-24T14:51:04.823 回答
0

您使用“\x1F”走在正确的道路上,但它应该是“%x1F”,你很高兴。

从 git rev-list 的联机帮助页:

· %x00: print a byte from a hex code

于 2017-08-24T14:50:56.573 回答