PythonのGitモジュールのいずれかでの人々の経験は何ですか? (私はGitPython、PyGit、およびDulwichを知っています-それらを知っていれば、他の人に言及してください。)
私はGitリポジトリと対話(追加、削除、コミット)する必要があるプログラムを書いていますが、Gitの経験がないため、探しているものの1つはGitに関する使いやすさ/理解です。
私が主に興味を持っている他のことは、ライブラリの成熟度と完全性、バグの合理的な不足、継続的な開発、ドキュメントと開発者の有用性です。
私が知りたい/必要とするかもしれない何かについて考えているなら、気軽にそれを言及してください。
私は答えで提案されたものとは異なる道を進んでいるので、自分の質問に答えると思いました。それにもかかわらず、答えた人に感謝します。
まず、GitPython、PyGit、およびDulwichでの私の経験の簡単な概要:
また、 StGit は面白そうですが、機能を別のモジュールに抽出する必要があり、それがすぐに起こるのを待ちたくありません。
上記の3つのモジュールを機能させるために費やした時間よりも(はるかに)短い時間で、サブプロセスモジュールを介してgitコマンドを機能させることができました。
def gitAdd(fileName, repoDir):
cmd = ['git', 'add', fileName]
p = subprocess.Popen(cmd, cwd=repoDir)
p.wait()
gitAdd('exampleFile.txt', '/usr/local/example_git_repo_dir')
これはまだ私のプログラムに完全には組み込まれていませんが、速度を除いて問題を予想していません(何百または何千ものファイルを処理することがあるため)。
たぶん、DulwichやGitPythonで物事を進める忍耐力がなかったのかもしれません。そうは言っても、モジュールがより多くの開発を得て、すぐにもっと便利になることを願っています。
この質問は少し前に尋ねられたものであり、その時点でのライブラリの状態はわかりませんが、GitPythonはコマンドラインツールを抽象化するのに適しているため、使用する必要はありません。サブプロセス。使用できるいくつかの便利な組み込みの抽象化がありますが、他のすべてについては次のようなことができます。
import git
repo = git.Repo( '/home/me/repodir' )
print repo.git.status()
# checkout and track a remote branch
print repo.git.checkout( 'Origin/somebranch', b='somebranch' )
# add a file
print repo.git.add( 'somefile' )
# commit
print repo.git.commit( m='my commit message' )
# now we are one commit ahead
print repo.git.status()
GitPythonの他のすべての機能により、ナビゲートが簡単になります。私はこのライブラリにかなり満足しており、基礎となるgitツールのラッパーであることを高く評価しています。
UPDATE:gitだけでなく、Pythonで必要なほとんどのコマンドラインユーティリティでshモジュールを使用するように切り替えました。上記を複製するには、代わりにこれを行います:
import sh
git = sh.git.bake(_cwd='/home/me/repodir')
print git.status()
# checkout and track a remote branch
print git.checkout('-b', 'somebranch')
# add a file
print git.add('somefile')
# commit
print git.commit(m='my commit message')
# now we are one commit ahead
print git.status()
これはかなり古い質問です。Gitライブラリを探しているときに、今年(2013年)に作成された Gittle と呼ばれるものを見つけました。
それは私にとってはうまくいきました(私が試した他のものは不安定でした)。また、一般的なアクションのほとんどをカバーしているようです。
READMEのいくつかの例:
from gittle import Gittle
# Clone a repository
repo_path = '/tmp/gittle_bare'
repo_url = 'git://github.com/FriendCode/gittle.git'
repo = Gittle.clone(repo_url, repo_path)
# Stage multiple files
repo.stage(['other1.txt', 'other2.txt'])
# Do the commit
repo.commit(name="Samy Pesse", email="[email protected]", message="This is a commit")
# Authentication with RSA private key
key_file = open('/Users/Me/keys/rsa/private_rsa')
repo.auth(pkey=key_file)
# Do Push
repo.Push()
たぶんそれは役立つかもしれませんが、BazaarとMercurialはどちらもGitの相互運用性のためにdulwichを使用しています。
Dulwichは、Pythonでのgitの再実装であるという意味で、おそらく他のものとは異なります。もう1つはGitのコマンドのラッパーである可能性があり(したがって、高レベルの観点から使用する方が簡単かもしれません:コミット/追加/削除)、おそらくAPIがgitのコマンドラインに非常に近いため、必要になりますGitの経験を積むため。
変更された時間を反映した更新された回答:
現在、GitPythonが最も使いやすいです。多くのgit plumbコマンドのラッピングをサポートし、プラグ可能なオブジェクトデータベース(それらの1つであるダッチ)があり、コマンドが実装されていない場合、コマンドラインにシェルアウトするための簡単なAPIを提供します。例えば:
repo = Repo('.')
repo.checkout(b='new_branch')
これは以下を呼び出します:
bash$ git checkout -b new_branch
Dulwichも良いですが、はるかに低いレベルです。配管レベルでgitオブジェクトを操作する必要があり、通常はしたい素敵な磁器がないため、使用するのはやや苦痛です。ただし、gitの一部を変更する場合、またはgit-receive-packとgit-upload-packを使用する場合は、dulwichを使用する必要があります。
完全を期すために、 http://github.com/alex/pyvcs/ はすべてのdvcの抽象化レイヤーです。ダルウィッチを使用しますが、他のdvcとの相互運用性を提供します。
PTBNLの回答は私にとって非常に完璧です。 Windowsユーザー向けにもう少し作成します。
import time
import subprocess
def gitAdd(fileName, repoDir):
cmd = 'git add ' + fileName
pipe = subprocess.Popen(cmd, Shell=True, cwd=repoDir,stdout = subprocess.PIPE,stderr = subprocess.PIPE )
(out, error) = pipe.communicate()
print out,error
pipe.wait()
return
def gitCommit(commitMessage, repoDir):
cmd = 'git commit -am "%s"'%commitMessage
pipe = subprocess.Popen(cmd, Shell=True, cwd=repoDir,stdout = subprocess.PIPE,stderr = subprocess.PIPE )
(out, error) = pipe.communicate()
print out,error
pipe.wait()
return
def gitPush(repoDir):
cmd = 'git Push '
pipe = subprocess.Popen(cmd, Shell=True, cwd=repoDir,stdout = subprocess.PIPE,stderr = subprocess.PIPE )
(out, error) = pipe.communicate()
pipe.wait()
return
temp=time.localtime(time.time())
uploaddate= str(temp[0])+'_'+str(temp[1])+'_'+str(temp[2])+'_'+str(temp[3])+'_'+str(temp[4])
repoDir='d:\\c_Billy\\vfat\\Programming\\Projector\\billyccm' # your git repository , windows your need to use double backslash for right directory.
gitAdd('.',repoDir )
gitCommit(uploaddate, repoDir)
gitPush(repoDir)
「git status」の非常に簡単な実装を次に示します。
import os
import string
from subprocess import *
repoDir = '/Users/foo/project'
def command(x):
return str(Popen(x.split(' '), stdout=PIPE).communicate()[0])
def rm_empty(L): return [l for l in L if (l and l!="")]
def getUntracked():
os.chdir(repoDir)
status = command("git status")
if "# Untracked files:" in status:
untf = status.split("# Untracked files:")[1][1:].split("\n")
return rm_empty([x[2:] for x in untf if string.strip(x) != "#" and x.startswith("#\t")])
else:
return []
def getNew():
os.chdir(repoDir)
status = command("git status").split("\n")
return [x[14:] for x in status if x.startswith("#\tnew file: ")]
def getModified():
os.chdir(repoDir)
status = command("git status").split("\n")
return [x[14:] for x in status if x.startswith("#\tmodified: ")]
print("Untracked:")
print( getUntracked() )
print("New:")
print( getNew() )
print("Modified:")
print( getModified() )
StGitのgitインタラクションライブラリ部分は、実際には非常に優れています。ただし、個別のパッケージとして分割されるわけではありませんが、十分な関心があれば、修正できると確信しています。
コミット、ツリーなどを表すため、および新しいコミットとツリーを作成するための非常に素晴らしい抽象化があります。