Python的Git模块的经验?

什么是人们对Python的任何Git模块的经验? (我知道GitPython,PyGit和德威 – 如果你知道的话,随意提及其他人。)

我正在编写一个程序,它必须与Git存储库进行交互(添加,删除,提交),但对Git没有经验,所以我正在寻找的一件事情就是简单地使用/理解Git。

我主要感兴趣的是图书馆的成熟度和完整性,合理缺乏错误,持续发展以及文档和开发人员的乐于助人。

如果您想了解其他我可能想要/需要了解的内容,请随时提及。

虽然这个问题刚才被问到,而且我不知道那个时候库的状态,但是对于search者来说值得一提的是,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工具的一个包装。

更新 :我已经切换到使用sh模块不只是混帐,但大多数命令行工具,我需要在Python中。 要复制上面,我会做这个,而不是:

 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() 

我想我会回答我自己的问题,因为我采取了不同于答案中build议的路线。 尽pipe如此,感谢那些回答。

首先,我简要介绍一下GitPython,PyGit和Dulwich的经验:

  • GitPython :下载后,我得到了这个导入和适当的对象初始化。 然而,试图做什么在教程中build议导致错误。 缺less更多的文件,我转向其他地方。
  • PyGit :这甚至不会导入,我找不到任何文档。
  • 德威 :似乎是最有前途的(至less是我想要和看到的)。 我用GitPython取得了一些进展,因为它的Python来源是Python。 但是,过了一段时间,我决定尝试我所做的事情可能会更容易一些。

此外, StGit看起来很有趣,但是我需要把这个function提取到一个单独的模块中,而不想等待这个事件发生。

比我花在上面的三个模块上花费的时间less得多,我设法通过subprocess模块获得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。 也就是说,我希望模块能够得到更多的发展,并且很快就会变得更有用。

我build议pygit2 – 它使用优秀的libgit2绑定

这是一个相当古老的问题,在寻找Git库时,我发现今年(2013年)创build了一个名为Gittle的库 。

它对我来说很好(我尝试过的其他的都是片状的),似乎涵盖了大部分常见的行为。

自述文件中的一些示例:

 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="samy@friendco.de", 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可能与另一个不同,因为它是Python中git的重新实现。 另一个可能只是Git命令的一个包装(所以从高级angular度来看可能会更简单:commit / add / delete),这可能意味着他们的API非常接近git的命令行,所以你需要获得与Git的经验。

为了完整起见, http ://github.com/alex/pyvcs/是所有dvcs的抽象层。 它使用德威,但提供其他dvcs的互操作。

反映更改时间的更新答案:

GitPython目前是最容易使用的。 它支持许多gitpipe道命令的包装,并具有可插入的对象数据库(dulwich是其中之一),如果没有执行一个命令,提供了一个简单的api shelling到命令行。 例如:

 repo = Repo('.') repo.checkout(b='new_branch') 

这要求:

 bash$ git checkout -b new_branch 

德威也不错,但水平要低得多。 使用起来有些痛苦,因为它需要在pipe道水平上对git对象进行操作,而且通常不会有很好的瓷器。 但是,如果您打算修改git的任何部分,或者使用git-receive-pack和git-upload-pack,则需要使用dulwich。

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交互库部分实际上是相当不错的。 但是,这并不是一个单独的scheme,但是如果有足够的兴趣,我相信这个问题是可以解决的。

它有非常好的抽象代表提交,树木等,并创build新的提交和树木。

为了logging,上面提到的Git Python库似乎都没有包含一个“git status”等价物,这是我唯一想要的,因为通过subprocess处理其余的git命令非常简单。