読者です 読者をやめる 読者になる 読者になる

dulwichを使ってPythonでGitのカスタムコマンドを作る

Gitのコマンドがわかりづらくて好きになれないんですが、気に入らない部分はカスタムコマンドを作ればいいよね。
ということで方法を調べてました。

カスタムコマンドの作り方

Gitのカスタムコマンドは、「git-コマンド名」のような実行可能ファイルを用意して、パスが通ってる場所に置けば有効になるようです。
実行可能であればシェルスクリプトでも問題ないようで、git-flowなどはシェルスクリプトで実装されていますね。

Pythonでdulwichを使ってみる

dulwichはGitリポジトリPythonで読み書きするためのモジュールです。
Dulwich
Pythonでdulwichを使って実行可能なスクリプトを書くことで、カスタムのGitコマンドをPythonで実装する、というのをやってみます。
試したバージョンは、dulwich 0.11.2, Python 3.4。
dulwichのインストールはpipでvirtualenvにでも入れておけばよいかと。
dulwichの使い方はドキュメントのチュートリアルが参考になります。
Tutorial — dulwich 0.14.0 documentation
以下のようにgit-helloという名前のファイルを作成します。
git-hello:

#!/usr/bin/env python
import os
import itertools

from dulwich.repo import Repo


def decode(b):
    return b.decode('utf8')


def main():
    print("----- My Git Command! -----")
    repo = Repo(os.getcwd())
    # Walkerを使ってコミットを取得し、id, author, messageを表示する
    for entry in itertools.islice(repo.get_walker(), 10):
        print("{}: {}, {}".format(
            decode(entry.commit.id),
            decode(entry.commit.author),
            decode(entry.commit.message).strip()))


if __name__ == '__main__':
    main()

先頭のshebangの部分は、環境に応じて変更すると良いかと思います(virtualenvを使っているなら、virtualenv内のpythonにするとか)
これを適当なディレクトリに置いてパスを通します。今回は $HOME/bin に置きました。

(venv)tokibito@ubuntu:~$ ls -l bin
合計 8
-rwxrwxr-x 1 tokibito tokibito  471 11月  5 23:34 git-hello
drwxrwxr-x 5 tokibito tokibito 4096 11月  5 23:07 venv
(venv)tokibito@ubuntu:~$ export PATH=$PATH:$HOME/bin

gitリポジトリになっているディレクトリで実行してみると、最近の10件のコミットが表示されました。
試したのは django-ftpserver のローカルリポジトリ

(venv)tokibito@ubuntu:~/github/django-ftpserver$ git hello
----- My Git Command! -----
a2fa94d4e594d25a9b28203b3a82e5f47b43d67d: Shinya Okano <tokibito@gmail.com>, fixes PEP8, and update version 0.3.2
a8fa3f773714c8b80d8e65cc42c2e5add2b70724: Shinya Okano <tokibito@gmail.com>, Merge pull request #7 from akoumjian/master

merged: Custom Authorizer and Handler classes via settings
659e0eb3204a56a56d0946a9ee880a9adb259cc5: Shinya Okano <shinya.okano@beproud.jp>, added: docker settings for test env
9df037ba02770e1bdd0be8e23ed024031a842948: Alec Koumjian <akoumjian@gmail.com>, allow custom authorizers and handlers

custom tls

add note in docs
8f63fcb3873aa2e9f85870e84a05cf30fc26bb85: Shinya Okano <tokibito@gmail.com>, modify document config
0189b075a633717b27443449558ed6ceda77dbdc: Shinya Okano <tokibito@gmail.com>, update library for documentation
0bc3875f6649db4a0d4234c20a9a14360667e651: Shinya Okano <tokibito@gmail.com>, update version 0.3.1
34d5ef6dc168e43010e4a2e80c346c097671caa7: Shinya Okano <tokibito@gmail.com>, flake8
9c9437f30336abb779871f78ce7d0f39a5e90b17: Shinya Okano <tokibito@gmail.com>, update travis config
664fd42ef583b4f5f2c6ac26827e11ea4f50a4c3: Shinya Okano <tokibito@gmail.com>, modify setup test

こんな感じで、Repoオブジェクトからいろいろ辿れるので、やりたい放題ですね。