Zlib

Git 将数据存储在 的文件中。.git/objects

Python 有一个模块zlib。我们想用 python 读取 git 文件数据:

>>> import zlib
>>> f = open('.git/objects/9d/aeafb9864cf43055ae93beb0afd6c7d144bfa4', 'rb')
>>> data = f.read()
>>> print(data)
b'x\x01K\xca\xc9OR0e(I-.\xe1\x02\x00\x19\xa6\x03\xbf'
>>> zlib.decompress(data)
b'blob 5\x00test\n'
>>>

blob 类型的文件(git 使用 3 种类型的文件 ),并且是内容长度:blobblobcommittree5test\n

我们也可以检查哈希值:

>>> import hashlib
>>> hashlib.sha1(zlib.decompress(data)).hexdigest()
'9daeafb9864cf43055ae93beb0afd6c7d144bfa4'
>>>

现在我们可以看到哈希与我们之前使用的完全相同。

创建自己的对象文件

Pro Git book展示了如何在 Ruby 中创建对象文件。但是要在 python 中创建对象文件,我们需要用于读取文件的相同模块以及用于创建目录的模块:os

>>> import zlib
>>> import hashlib
>>> import os
>>> s = 'blob 11\x00new string\x00'.encode()

获取哈希值:

>>> hash = hashlib.sha1(s).hexdigest() # 90cc64bc4738805499e19ab3bab69ecb2c3a16c0
>>> os.mkdir('.git/objects/' + hash[0:2]) # .git/objects/90 do it if necessary
>>> f = open('.git/objects/' + hash[0:2] + '/' + hash[2:], 'wb')
>>> f.write(zlib.compress(s))
27
>>> f.close()

现在我们在 中有了新的格式良好的 git 对象。.git/objects/90

GitPython

GitPython是 git 存储库的 python API,从脚本中执行 git 提交和推送。

安装

GitPython是一个托管在 pypi 上的 Python 库,我们希望使用 pip 将其安装到我们的虚拟环境中。

pip install GitPython

创建 Repo 对象

从 git 库导入 Repo,并通过为对象提供包含目录的目录的路径来创建对象的实例。

from git import Repo repo = Repo('~/git/waylonwalker.com/')

请求 git 状态可以按如下方式完成。

>>> print(repo.git.status())

On branch main Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        blog/

使用日志的示例。

>>> print(repo.git.log('--oneline', '--graph'))

* 0d28bd8 fix broken image link
* 3573928 wip screenshot-to-blog
* fed9abc wip screenshot-to-blog
* d383780 update for wsl2
* ad72b14 wip screenshot-to-blog
* 144c2f3 gratitude-180

查找所有已删除的文件以及它们被删除的哈希值。

print(repo.git.log('--diff-filter', 'D', '--name-only', '--pretty=format:"%h"'))