pygit2 是 libgit2 的 Python 绑定,而 libgit2 是一个可动态链接的 git 库,除去头文件和 pkgconfig 信息就一个 .so 文件。它是我在 The Architecture of Open Source Applications(AOSA)第二巻讲 git 的部分中看到的。git 本身遵循了传统的 Unix 哲学,提供了一系列的命令来管理源码库。这对于 shell 脚本是非常不错,可是对于嵌入到其它应用(如 IDE、Web 服务)中却不太好用。于是,我们有了 libgit2。
很遗憾的是,我并没有找到 API 文档,只有一些示例性的用法介绍,更别提教程之类。即使在 pygit2 中,使用help
命令能够得到的信息也很有限。所以,我只能在 Python 这样动态语言的交互式会话时独自探索。
下面是我搜索出来的使用 pygit2 进行提交的过程:
导入需要用到的模块:
1 2 | import pygit2 import time |
我的 git 仓库,还有 index:
1 2 | repo = pygit2.Repository( '/home/lilydjwg/.vim/.git' ) ind = repo.index |
先看看未提交到 index 的修改(相当于git diff
)
1 | print (ind.diff()) |
唔,我看到就一个plugin/colorizer.vim
文件修改了。把它加到 index 中(相当于git add
)。如果是git rm
的话就用del ind[filename]
了。操作之后要调用write()
方法写入更改。
1 2 | ind.add( 'plugin/colorizer.vim' ) ind.write() |
写入 tree 对象,其返回值是二进制编码的 hash 值(使用binascii.b2a_hex
可编码成 git 命令中使用的字符串)
1 | oid = ind.write_tree() |
作者和提交者的信息,其中最后一个参数(offset
)是以分钟计的时区偏移(当然是相对于 UTC)。邮件地址很显然被打码了 :-)
1 | author = pygit2.Signature( '依云' , 'a@b.c' , int (time.time()), 480 ) |
创建提交。其中HEAD
是个「符号引用」(symbolic reference),而repo.head
就是当前最后一个提交了,oid
属性还是二进制编码的 hash 啦。这里,提交者和作者是同一人,因此我都使用刚刚创建的author
对象了。这步就是git commit
命令了。
1 | repo.create_commit( 'HEAD' , author, author, 'colorizer: solved name color conflict' , oid, [repo.head.oid]) |
在命令行下看看结果是否正确:
1 2 3 4 5 6 7 | >>> git cat - file -p HEAD tree 20e8937d41b6df16da2c8c5661f9c4a8dd31b5a1 parent ab9c662ce0d1cb2deac7a9ae388ecb40d8ec5e15 author 依云 <a@b.c> 1340188028 +0800 committer 依云 <a@b.c> 1340188028 +0800 colorizer: solved name color conflict |