python + dulwich で git-show 的なこと
dulwich-0.7.0
で入った dulwich.diff_tree
の使い方を確認するために、 git-show
的なスクリプトを書いてみた。
ついでに format
も使いまくってみているので python-2.6
以上じゃないと動かん。
#!/usr/bin/python import datetime import difflib import dulwich import re import sys repo = dulwich.repo.Repo('.') if len(sys.argv) > 1: commit_sha = sys.argv[1] else: commit_sha = repo.head() commit = repo.get_object(commit_sha) date = datetime.datetime.fromtimestamp(commit.commit_time) message = re.compile('^', re.MULTILINE).sub(' ', commit.message) print '''commit {commit_sha} Author: {commit.author} Date: {date:%c} {message} '''.format(**locals()), parent = repo.get_object(commit.parents[0]) for change in dulwich.diff_tree.tree_changes(repo.object_store, parent.tree, commit.tree): if change.type == 'modify': print 'diff --git a/{0} b/{1}'.format(change.old.path, change.new.path) # TODO: if mode changed print 'index {0:.7}..{1:.7} {2:o}'.format(change.old.sha, change.new.sha, change.new.mode) for line in difflib.unified_diff(repo.get_object(change.old.sha).data.splitlines(True), repo.get_object(change.new.sha).data.splitlines(True), 'a/' + change.old.path, 'b/' + change.new.path): print line, elif change.type == 'add': print 'diff --git a/{0} b/{0}'.format(change.new.path) print 'new file mode {0:o}'.format(change.new.mode) print 'index {0:.7}..{1:.7}'.format('0'*40, change.new.sha) for line in difflib.unified_diff([], repo.get_object(change.new.sha).data.splitlines(True), '/dev/null', 'b/' + change.new.path): print line, elif change.type == 'delete': print 'diff --git a/{0} b/{0}'.format(change.old.path) print 'deleted file mode {0:o}'.format(change.old.mode) print 'index {0:.7}..{1:.7}'.format(change.old.sha, '0'*40) for line in difflib.unified_diff(repo.get_object(change.old.sha).data.splitlines(True), [], 'a/' + change.old.path, '/dev/null'): print line, else: # TODO: implement 'copy', 'rename', 'unchanged' print change