파이썬 힘내 모듈 경험? [닫은]


172

Python 용 Git 모듈에 대한 사람들의 경험은 무엇입니까? (GitPython, PyGit 및 Dulwich에 대해 알고 있습니다. 다른 사람을 알고 있으면 자유롭게 언급하십시오.)

Git 저장소와 상호 작용 (추가, 삭제, 커밋) 해야하는 프로그램을 작성하고 있지만 Git에 대한 경험이 없으므로 Git과 관련하여 사용하기 쉽고 이해하기 쉽습니다.

내가 주로 관심을 갖고있는 다른 것은 라이브러리의 완성도와 완성도, 적절한 버그 부족, 지속적인 개발, 문서와 개발자의 도움입니다.

내가 알고 / 필요한 다른 것을 생각하면 자유롭게 언급하십시오.


25
이 질문을 커뮤니티 위키로 바꿀 수 있습니까? 가장 좋은 답변은 시간이 지남에 따라 변할 것입니다.
relet

4
@relet : 닫혀있는 한 Wiki로 만들 수 없습니다.
PTBNL

답변:


119

이 질문은 얼마 전에 요청되었지만 그 시점에서 라이브러리의 상태를 알지 못하지만 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 도구의 래퍼임을 알고 있습니다.

업데이트 : git뿐만 아니라 파이썬에서 필요한 대부분의 명령 줄 유틸리티에 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()

2
훌륭한 Legit 도구는 GitPython을 사용합니다 : github.com/kennethreitz/legit/blob/develop/legit/scm.py
forivall

9
이 답변을 바탕으로 git-python으로 운을 시험해 보았습니다. 처리해야 할 API가 이상하다고 생각합니다. 대부분의 경우 repo.git. * 일반 인터페이스로 돌아 가야하며 심지어 제대로 repo.git.branch(b=somebranch)작동 repo.git.branch(D=somebranch)하지 않습니다 (예 : 작동하지만 공간이 없어서 작동 하지 않음). 하위 프로세스 기반의 일반 함수를 직접 구현할 것 같습니다. 나는 슬프다, 나는 높은 희망을 가지고 있었다. :-/
Christoph

6
와 함께 sh 모듈을 사용하도록 전환했습니다 git = sh.git.bake(_cwd=repopath). 그것은 훌륭하게 작동합니다.
언더런

10
sh에 링크 : amoffat.github.io/sh는 실제로 파이썬 stdlib의 일부 여야합니다.
g33kz0r 2016 년

4
최신 Python sh 버전은 Windows에서 작동하지 않습니다. 완전한 실패.
void.pointer

81

나는 대답에서 제안 된 것과 다른 길을 가고 있기 때문에 내 자신의 질문에 대답 할 것이라고 생각했습니다. 그럼에도 불구하고 대답 한 사람들에게 감사합니다.

먼저 GitPython, PyGit 및 Dulwich에 대한 나의 경험에 대한 간략한 개요 :

  • GitPython : 다운로드 후 이것을 가져 와서 적절한 객체를 초기화했습니다. 그러나 튜토리얼에서 제안한 작업을 수행하려고하면 오류가 발생했습니다. 더 많은 문서가 부족하여 다른 곳으로 향했습니다.
  • PyGit : 이것은 가져올 수도 없으며 문서를 찾을 수 없습니다.
  • 덜 위치 : 가장 유망한 것 같습니다 (적어도 내가 원하고 본 것). 계란은 파이썬 소스와 함께 제공되므로 GitPython보다 더 발전했습니다. 그러나 잠시 후, 나는 내가 한 일을 시도하는 것이 더 쉬울 것이라고 결정했습니다.

또한 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')

이것은 아직 내 프로그램에 완전히 통합되어 있지는 않지만 속도를 제외하고는 문제를 예상하지 않습니다 (시간에 수백 또는 수천 개의 파일을 처리하기 때문에).

어쩌면 Dulwich 또는 GitPython과 관련하여 인내심이 없었을 수도 있습니다. 즉, 모듈이 더 많이 개발되고 곧 더 유용해질 것으로 기대합니다.


25
이 답변은 오래되었습니다.
Alex Chamberlain

3
예, 업데이트에 관심이 있습니다.
JosefAssad

GitPython은 매우 잘 작동하며 광범위하게 문서화되어 있습니다.
Arthur

1
@Arthur 저는 적어도 3 시간 동안 StackOverflow 및 GitPython 설명서에 git pull, add, commit 및 push를 사용하여 원격 저장소에 기본 사항을 이해하기 때문에 동의하지 않습니다. 이 문서에는 몇 가지 고급 사용 사례가 있지만 기본적인 내용은 부족합니다. 기본적으로 하위 프로세스를 포기하고 사용하고 있습니다.
Daniel Lavedonio de Lima

31

pygit2를 추천 합니다 -우수한 libgit2 바인딩을 사용합니다


1
또한 git 배관에 대한 최상의 액세스를 제공합니다.
pielgrzym 2016 년

pygit2정말 유용한 라이브러리이며 앞으로 확장 될 것으로 기대합니다!
Alex Chamberlain

2
지금이기 때문에, 하나는 수동으로 다운로드 모두의 컴파일 / 설치 준 안정 버전 있어야 libgitpygit2GitHub의에서 소스를 복용. 문제는 헤드 브랜치에서 테스트가 중단되고 최신 "안정된"설치가 실패하는 것입니다 ... 안정성이 중요하고 다양한 환경에 배포해야하는 경우 적합한 솔루션이 아닙니다 ... :(
mac

1
cygwin을 사용하는 클라이언트를 계획하는 경우이 조합을 피하십시오. pygit2는 libgit2의 래퍼이며 libgit2는 모든 cygwin 지원을 중단했습니다. 개발자의 한 사람으로부터받은 의견, "당신은 시도해 볼 수 있지만, 그것이 만들어지면 기적 일 것입니다." 아마 GitPython에 갈 것입니다.
scphantm

2
Cygwin 은 기본 Windows 지원에 중점을두기 때문에 cygwin을 지원하지 않습니다 . 따라서 cygitwin에서 libgit2가 지원되지 않는 것은 맞지만 Windows 사용자가 추위 에 빠졌다는 의미 는 아닙니다 .
Xiong Chiamiov

19

이것은 매우 오래된 질문이며 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()

2
인덱스에 파일을 "추가"하는 대신 파일을 "스테이지"하는 것이 마음에 들지 않습니다. 일반적인 / 중요한 작업의 이름을 변경하면 혼란 스러울 것 같습니다.
21:53에

3
@underrun을 추가하면 스테이지에 파일이 추가됩니다. 준비 파일과 동일하지 않습니까?
Jimmy Kane

파일을 추가하는 것은 커밋 할 파일을 준비하는 것입니다 (인덱스에 추가하는 것). 작업은 동일하지만 명령 줄에 입력 git add other1.txt other2.txt하면 예상되는 내용을 따르지 않습니다.
언더런

1
이 패키지의 우수성에 동의했습니다. StaSh를 설치 한 후 Pythonista 앱에서 사용할 수있었습니다. 또한 귀하의 답변이이 질문에 대한 답변 중에서 가장 최근에 업데이트되었음을 ​​주목할 가치가 있습니다.
Chris Redford

1
실제로, 그것은 Pythonista 에서만 나를 위해 일하는 것 같습니다 . 내 Mac에서 개인 비트 버킷 저장소의 복제본을 암호로 인증하는 것은 마침내 포기한 악몽이었습니다.
Chris Redford

17

아마도 도움이 될 수 있지만 Bazaar와 Mercurial은 Git 상호 운용성을 위해 덜 리치를 사용하고 있습니다.

덜 리치는 아마도 파이썬에서 git을 다시 구현한다는 점에서 다른 것과 다를 수 있습니다. 다른 하나는 Git의 명령을 감싸는 래퍼 일 수 있습니다 (따라서 높은 수준의 관점에서 사용하는 것이 더 간단 할 수 있습니다 : commit / add / delete), 아마도 API가 git의 명령 줄에 매우 가깝기 때문에 필요할 것입니다. 힘내 경험을 얻을 수 있습니다.


매우 유용한 답변, 나는 Mercurial이 Dulwich를 사용한다는 것을 몰랐습니다. 감사합니다!
kissgyorgy


7

변경된 시간을 반영하는 업데이트 된 답변 :

GitPython은 현재 가장 사용하기 쉽습니다. 많은 git plumbing 명령의 래핑을 지원하고 플러그 가능한 객체 데이터베이스 (둘 중 하나임)가 있으며 명령이 구현되지 않은 경우 명령 줄에 셸하기 쉬운 API를 제공합니다. 예를 들면 다음과 같습니다.

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

이것은 다음을 호출합니다.

bash$ git checkout -b new_branch

덜 위치도 좋지만 훨씬 낮은 수준입니다. 배관 수준에서 git 객체에서 작동해야하고 일반적으로하고 싶은 좋은 도자기가 없기 때문에 사용하기가 다소 고통 스럽습니다. 그러나 git의 일부를 수정하거나 git-receive-pack 및 git-upload-pack을 사용하려면 dulwich를 사용해야합니다.


2

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

5
나는 구문 분석 권하고 싶지 않다git status
Ehtesh Choudhury의

1
파싱 git status --short이 쉬울 것이고 --short출력이 변경 될 가능성이 적 다고 생각합니다 .
Ben 페이지

2
git status --porcelain이것을 위해 사용--porcelain: Give the output in a stable, easy-to-parse format for scripts...
estani

또는 더 나은 --z대신을 사용하십시오 --porcelain. 달리 --porcelain, --z파일 이름 탈출하지 않습니다.
Vojislav Stojkovic

2

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)

4
나는 많은 코드 반복을 본다 ... : p
Ciasto piekarz

0

StGit의 git 상호 작용 라이브러리 부분은 실제로 꽤 좋습니다. 그러나 별도의 패키지로 분류되지는 않지만 충분한 관심이 있다면 수정할 수 있다고 확신합니다.

커밋, 트리 등을 표현하고 새로운 커밋과 트리를 생성하는 데 아주 좋은 추상화가 있습니다.


-3

기록을 위해 앞에서 언급 한 Git Python 라이브러리에는 "git status"에 해당하는 것이 없으며 하위 프로세스를 통해 나머지 git 명령을 처리하는 것이 매우 쉽기 때문에 실제로 원하는 유일한 것입니다.


3
GitPython 사용 : git.Repo (repoDir) .git.status ()
언더런
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.