Опыт работы с Python Git Module?
Каков опыт людей с любым из модулей Git для Python? (Я знаю о GitPython, PyGit и Dulwich - не стесняйтесь упоминать других, если вы знаете о них.)
Я пишу программу, которая должна взаимодействовать (добавлять, удалять, фиксировать) с Git-репозиторием, но не иметь опыта работы с Git, поэтому одна из вещей, которые я ищу, - это простота использования / понимания в отношении Git.
Другие вещи, которые меня в первую очередь интересуют, - это зрелость и полнота библиотеки, разумное отсутствие ошибок, постоянное развитие и полезность документации и разработчиков.
Если вы думаете о чем-то еще, что я хотел бы / нужно знать, пожалуйста, не стесняйтесь упоминать об этом.
11 ответов
Я думал, что отвечу на свой вопрос, так как я иду по другому пути, чем предложено в ответах. Тем не менее, спасибо тем, кто ответил.
Во-первых, краткий обзор моего опыта с GitPython, PyGit и Dulwich:
- GitPython: После загрузки я импортировал это и инициализировал соответствующий объект. Однако попытка сделать то, что было предложено в руководстве, привела к ошибкам. Не имея больше документации, я обратился в другое место.
- PyGit: это даже не импортировать, и я не смог найти документацию.
- Дульвич: Кажется, это самое перспективное (по крайней мере, то, что я хотел и увидел). Я добился некоторого прогресса в этом, больше, чем в GitPython, так как его яйцо поставляется с исходным кодом Python. Однако через некоторое время я решил, что может быть проще попробовать то, что я сделал.
Кроме того, StGit выглядит интересно, но мне нужно, чтобы функциональность была выделена в отдельный модуль, и я не хочу ждать, пока это произойдет прямо сейчас.
За (намного) меньше времени, чем я потратил, пытаясь заставить работать три вышеупомянутых модуля, мне удалось заставить команды 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')
Это еще не полностью включено в мою программу, но я не ожидаю проблемы, кроме, возможно, скорости (так как я буду обрабатывать сотни или даже тысячи файлов за раз).
Возможно, у меня просто не хватило терпения наладить отношения с Далвичем или 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.
ОБНОВЛЕНИЕ: я перешел на использование модуля sh не только для git, но и для большинства утилит командной строки, которые мне нужны в 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()
Возможно, это помогает, но Bazaar и Mercurial используют dulwich для своей совместимости с Git.
Далвич, вероятно, отличается от других в том смысле, что это повторная реализация git в python. Другой может быть просто оберткой вокруг команд Git (так что это может быть проще использовать с точки зрения высокого уровня: commit/add/delete), это, вероятно, означает, что их API очень близок к командной строке git, поэтому вам понадобится получить опыт работы с Git.
Это довольно старый вопрос, и, ища библиотеки 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="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()
Обновленный ответ, отражающий изменившиеся времена:
GitPython в настоящее время является самым простым в использовании. Он поддерживает перенос многих команд git plumbing и имеет подключаемую базу данных объектов (dulwich является одной из них), и, если команда не реализована, предоставляет легкий API-интерфейс для обработки командной строки. Например:
repo = Repo('.')
repo.checkout(b='new_branch')
Это вызывает:
bash$ git checkout -b new_branch
Дульвич тоже хороший, но гораздо более низкий уровень. Это немного болезненно, потому что требует работы с объектами git на уровне сантехники и не имеет хорошего фарфора, который вы обычно хотели бы делать. Однако, если вы планируете модифицировать какие-либо части git или использовать git-receive-pack и git-upload-pack, вам нужно использовать dulwich.
Для полноты http://github.com/alex/pyvcs/ это уровень абстракции для всех dvcs. Он использует Далвич, но обеспечивает взаимодействие с другими 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() )
Часть библиотеки Git Interaction в StGit на самом деле довольно хороша. Тем не менее, он не разбит на отдельные пакеты, но если есть достаточный интерес, я уверен, что это можно исправить.
Он имеет очень хорошие абстракции для представления коммитов, деревьев и т. Д., А также для создания новых коммитов и деревьев.
Напомним, что ни одна из вышеупомянутых библиотек Git Python, похоже, не содержит эквивалента "git status", что на самом деле является единственной вещью, которую я хотел бы получить, поскольку иметь дело с остальными командами git с помощью подпроцесса.