Python Git Modülü deneyimleri? [kapalı]


172

Python için Git modüllerinden herhangi biriyle insanların deneyimleri nelerdir? (GitPython, PyGit ve Dulwich'i biliyorum - eğer biliyorsanız başkalarından da bahsetmekten çekinmeyin.)

Git deposuyla etkileşimde bulunmak (eklemek, silmek, işlemek), ancak Git ile ilgili deneyimi olmayan bir program yazıyorum, bu yüzden aradığım şeylerden biri Git ile ilgili kullanım kolaylığı / anlayış.

Öncelikle ilgilendiğim diğer şeyler kütüphanenin olgunluğu ve bütünlüğü, makul bir hata eksikliği, sürekli gelişim ve dokümantasyon ve geliştiricilerin yardımseverliğidir.

Bilmek isteyebileceğim / bilmem gereken başka bir şey düşünüyorsanız, lütfen bundan çekinmeyin.


25
Bu soruyu topluluk vikisine dönüştürebilir miyiz? En iyi cevabın zamanla değişeceğini hissediyorum.
relet

4
@relet: Kapalı olduğu sürece wiki yapılamaz.
PTBNL

Yanıtlar:


119

Bu soru bir süre önce sorulmuş olsa da ve bu noktada kütüphanelerin durumunu bilmiyorum, arama yapanlar için GitPython'un komut satırı araçlarını soyutlamak için iyi bir iş yaptığını belirtmeniz gerekiyor, böylece kullanmanıza gerek yok alt işlemi. Kullanabileceğiniz bazı soyut soyutlamalar vardır, ancak diğer her şey için aşağıdakileri yapabilirsiniz:

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'daki diğer her şey gezinmeyi kolaylaştırır. Bu kütüphane ile oldukça iyi memnunum ve temel git araçları üzerinde bir sarıcı olduğunu takdir ediyorum.

GÜNCELLEME : Ben sadece git değil python içinde gereken çoğu komut satırı yardımcı programları için sh modülünü kullanmaya geçtim. Yukarıdaki çoğaltmak için bunu yerine:

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
Mükemmel Legit aracı GitPython kullanıyor: github.com/kennethreitz/legit/blob/develop/legit/scm.py
forivall

9
Bu cevaba dayanarak, şansımı git-python ile denedim. API ile uğraşmak garip buluyorum. Çoğu zaman repo.git. * Genel arayüzüne geri dönmeniz gerekir ve bu bile zaman zaman düzgün çalışmaz (örneğin repo.git.branch(b=somebranch)çalışır, ancak repo.git.branch(D=somebranch)bir alan eksik olduğu için çalışmıyor). Sanırım bir alt işleme dayalı genel işlev uygulayacağım. Üzgünüm, büyük umutlarım vardı. : - /
Christoph

6
Şimdi sh modülünü kullanmaya geçtim git = sh.git.bake(_cwd=repopath). harika çalışıyor.
boşalması

10
sh: amoffat.github.io/sh bağlantısı gerçekten python stdlib'in bir parçası olmalıdır.
g33kz0r

4
En son python sh sürümü Windows'ta çalışmaz. Tamamen başarısız.
void.pointer

81

Kendi soruma cevap vereceğimi düşündüm, çünkü cevaplarda önerilenden farklı bir yol izliyorum. Yine de cevaplayanlara teşekkürler.

İlk olarak, GitPython, PyGit ve Dulwich ile deneyimlerimin kısa bir özeti:

  • GitPython : İndirdikten sonra bunu içe aktardım ve uygun nesne başlatıldı. Ancak, öğreticide önerilenleri yapmaya çalışmak hatalara yol açtı. Daha fazla dokümantasyon eksik, başka bir yere döndüm.
  • PyGit : Bu bile içe aktarılmaz ve hiçbir belge bulamadım.
  • Dulwich : En umut verici görünüyor (en azından istediğim ve gördüklerim için). Yumurtası Python kaynağı ile geldiğinden, GitPython'dan daha fazla ilerledim. Ancak, bir süre sonra, ne yaptığımı denemenin daha kolay olabileceğine karar verdim.

Ayrıca, StGit ilginç görünüyor, ancak ayrı bir modüle çıkarılan işlevselliğe ihtiyacım var ve şu anda bunun olmasını beklemek istemiyorum.

Yukarıdaki üç modülü çalışmaya çalışırken harcadığımdan (çok) daha kısa sürede, git komutlarını alt işlem modülü aracılığıyla çalıştırabildim, örn.

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

Bu henüz programıma tam olarak dahil edilmedi, ancak belki de hız dışında bir sorun beklemiyorum (çünkü bazen yüzlerce hatta binlerce dosyayı işleyeceğimden).

Belki de Dulwich veya GitPython ile işleri halletme sabrım yoktu. Bununla birlikte, modüllerin daha fazla gelişme göstereceğini ve yakında daha yararlı olacağını umuyorum.


25
Bu cevap yaşlanıyor.
Alex Chamberlain

3
Evet, bir güncellemeyle ilgilenirim.
JosefAssad

GitPython çok iyi çalışıyor ve kapsamlı bir şekilde belgelendi.
Arthur

1
@Arthur'a katılmıyorum çünkü StackOverflow ve GitPython belgelerine en az 3 saat gidiyorum, sadece git pull'un temellerini anlamak, kullanmak, eklemek ve kullanmak için uzak bir repoya girmek. Belgelerin bazı ileri kullanım durumları vardır, ancak çok basit değildir. Temelde vazgeçip alt süreci de kullanıyorum.
Daniel Lavedonio de Lima

31

Pygit2'yi tavsiye ederim - mükemmel libgit2 bağlarını kullanır


1
Git tesisatına da en iyi erişimi sağlar.
pielgrzym

pygit2gerçekten kullanışlı bir kütüphane ve gelecekte genişlemeyi dört gözle bekliyorum!
Alex Chamberlain

2
Şimdi olduğu gibi, tek elle indirip hem derleme / kurulum yarı kararlı sürümleri gerekir libgitve pygit2GitHub kaynağını alarak. Sorun şu ki, kafa dalları testleri kırdı ve en son "kararlı" başarısız kurulum ... Güvenilirlik önemliyse ve çeşitli ortamlarda konuşlandırmanız gerekiyorsa uygun bir çözüm değil ... :(
mac

1
cygwin kullanan istemcileri planlıyorsanız bu kombinasyondan uzak durun. pygit2 libgit2 için bir pakettir ve libgit2 tüm cygwin desteğini düşürmüştür. Geliştiricilerin birinden aldığım yorum, "Deneyebilirsiniz, ancak güzel API oluşturuyorsa bir mucize olabilir", evet, ancak müşterilerimin yarısı cygwin olduğundan bu yüzden kullanamıyorum. Muhtemelen GitPython'a gidiyoruz.
scphantm

2
Odakları bunun yerine yerel Windows desteğinde olduğu için cygwin'i desteklemediklerini unutmayın . Bu nedenle libgit2'nin cygwin'de desteklenmediği doğru olsa da , Windows kullanıcılarının soğukta kaldığı anlamına gelmez.
Xiong Chiamiov

19

Bu oldukça eski bir soru ve Git kütüphanelerini ararken, bu yıl (2013) Gittle olarak adlandırılan bir tane buldum .

Benim için harika çalıştı (denediğim diğerlerinin lapa lapa olduğu yerlerde) ve ortak eylemlerin çoğunu kapsıyor gibi görünüyor.

README'den bazı örnekler:

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
i "dizin" yerine "sahne" dosyaları sevmiyorum. ortak / önemli operasyonların adlarını değiştirmek, kafa karıştırıcı gibi görünüyor.
boşalması

3
@underrun ekleyerek sahneye dosya ekliyor. Dosyaları hazırlama ile aynı değil mi?
Jimmy Kane

dosya eklemek, işlenecek dosyaları hazırlıyor (bunları dizine ekliyor). işlem aynıdır, ancak komut satırına yazmanız git add other1.txt other2.txtgerekir, böylece beklenenleri izlemez.
alt

1
Bu paketin üstünlüğü konusunda anlaştılar. Hatta paketlenmiş olan StaSh'i yükledikten sonra Pythonista uygulamasında bile kullanabildim. Ayrıca, cevabınızın bu sorunun cevaplarından en son güncellenmiş olduğunu belirtmek gerekir.
Chris Redford

1
Aslında, sadece benim için Pythonista üzerinde çalışıyor gibi görünüyor . Mac bilgisayarımdaki özel bir bitbucket repo klonunu şifre almak, nihayet vazgeçtiğim bir kabus oldu.
Chris Redford

17

Belki yardımcı olur, ancak Bazaar ve Mercurial, Git birlikte çalışabilirlikleri için dulwich kullanıyorlar.

Dulwich, python'da git'in yeniden uygulanması anlamında muhtemelen diğerinden farklıdır. Diğeri, Git'in komutlarının etrafında bir sarıcı olabilir (bu nedenle, üst düzey bir bakış açısıyla kullanmak daha kolay olabilir: commit / add / delete), muhtemelen API'lerinin git'in komut satırına çok yakın olduğu anlamına gelir. Git ile deneyim kazanmak.


Çok faydalı bir cevap, Mercurial'ın Dulwich'i kullandığını bilmiyordum, teşekkürler!
kissgyorgy


7

Değişen zamanları yansıtan güncellenmiş bir cevap:

GitPython şu anda kullanımı en kolay olanıdır. Birçok git sıhhi tesisat komutunun kaydırılmasını destekler ve takılabilir nesne veritabanına sahiptir (dulwich bunlardan biridir) ve bir komut uygulanmazsa, komut satırına bombardıman için kolay bir API sağlar. Örneğin:

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

Bu çağrı:

bash$ git checkout -b new_branch

Dulwich de iyi ama çok daha düşük bir seviyede. Kullanımı biraz acıdır, çünkü sıhhi tesisat seviyesinde git nesnelerinde çalışmayı gerektirir ve normalde yapmak istediğiniz güzel porselene sahip değildir. Ancak, git'in herhangi bir parçasını değiştirmeyi veya git-alma-paketi ve git-upload-paketini kullanmayı planlıyorsanız, dulwich kullanmanız gerekir.


2

İşte "git status" un gerçekten hızlı bir uygulaması:

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
Ayrıştırma tavsiye etmemgit status
Ehtesh Choudhury

1
Ayrıştırma git status --shortdaha kolay olurdu ve bence --shortçıktının değişme olasılığı daha düşük.
Ben Sayfa

2
Kullanım git status --porcelainbunun için--porcelain: Give the output in a stable, easy-to-parse format for scripts...
estani

Ya da daha iyisi, --zyerine kullanın --porcelain. Aksine --porcelain, --zdosya adlarından kaçmaz.
Vojislav Stojkovic

2

PTBNL'nin Cevabı benim için oldukça mükemmel. Windows kullanıcısı için biraz daha fazlasını yapıyorum.

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
Kod tekrarı çok görüyorum ...: p
Ciasto piekarz

0

StGit'in git etkileşim kütüphanesi kısmı aslında oldukça iyi. Ancak, ayrı bir paket olarak dağıtılmaz, ancak yeterli ilgi varsa, bunun düzeltilebileceğinden eminim.

Taahhütleri, ağaçları vb. Temsil etmek ve yeni taahhütler ve ağaçlar oluşturmak için çok güzel soyutlamalar vardır.


-3

Kayıt için, yukarıda belirtilen Git Python kütüphanelerinin hiçbiri "git status" eşdeğerini içermiyor gibi görünüyor, bu da alt işlem yoluyla git komutlarının geri kalanıyla uğraşmaktan dolayı gerçekten isteyeceğim tek şey.


3
GitPython ile: git.Repo (repoDir) .git.status ()
underrun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.