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


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

Git deposuyla etkileşime girmek (ekleme, silme, taahhüt etme) gerektiren, ama Git ile ilgili hiçbir deneyimim olmayan bir program yazıyorum, bu yüzden aradığım şeylerden biri de Git'e göre kullanım / anlayış kolaylığı.

Öncelikle ilgilendiğim diğer konular kütüphanenin olgunluğu ve bütünlüğü, makul bir hata eksikliği, sürekli gelişim ve belgelerin ve geliştiricilerin yardımlarıdır.

Bilmem / bilmem gereken başka bir şey düşünüyorsanız, lütfen bunu belirtmekten çekinmeyin.


146
2017-09-21 19:10


Menşei


Bu soruyu bir topluluk vikisine çevirebilir miyiz? En iyi cevabın zamanla değişeceğini hissediyorum. - relet
@relet: Kapalı olduğu sürece wiki yapılamaz. - PTBNL


Cevaplar:


Bu soruyu bir süre önce sormuşken ve bu noktada kütüphanelerin durumunu bilmemekle birlikte, arama yapanlar için GitPython'un komut satırı araçlarını soyutlamak için iyi bir iş çıkardığını, dolayısıyla kullanmanıza gerek olmadığını belirtmek gerekir. alt işlemi. Kullanabileceğiniz bazı soyut dokular var, ama her şey için şunları 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üphaneden oldukça memnunum ve temel git araçlarında bir sarıcı olduğunu takdir ediyorum.

GÜNCELLEŞTİRME: Sh modülünü sadece git için değil, python'da ihtiyacım olan komut satırı yardımcı programlarını kullanmaya başladım. Yukarıdakileri çoğaltmak için şunu yapardım:

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

102
2017-12-20 15:49



Mükemmel Legit aracı, GitPython'u kullanır: github.com/kennethreitz/legit/blob/develop/legit/scm.py - forivall
Bu cevaba dayanarak şansımı git-python ile denedim. Anlaşılması gereken API'yi buldum. Çoğu zaman repo.git. * Genel arayüzüne geri dönmeniz gerekir ve hatta zaman zaman düzgün çalışmaz (ör. repo.git.branch(b=somebranch) çalışır ama repo.git.branch(D=somebranch) bir alan eksik olduğundan değil). Sanırım alt işlem tabanlı bir genel işlevi kendim uygulayacağım. Üzgünüm, yüksek umutlarım vardı. : - / - Christoph
şimdi sh modülünü kullanmaya başladım git = sh.git.bake(_cwd=repopath). awesomely çalışır. - underrun
sh'a bağlantı: amoffat.github.io/sh  python stdlib'in bir parçası olmalı. - g33kz0r
En son python sh sürümü Windows üzerinde çalışmıyor. Tamamen başarısız. - void.pointer


Kendi sorumu cevaplayacağımı düşündüm, çünkü cevaplarda önerilenden farklı bir yol izliyorum. Yine de, cevap verenlere teşekkürler.

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

  • GitPython: İndirme işleminden sonra, bunu içe aktardım ve uygun nesne başlatıldı. Ancak, öğreticide önerilenleri yapmaya çalışmak hatalara neden oldu. Daha fazla dokümantasyon eksikliği, başka bir yere döndüm.
  • PyGit: Bu bile ithal etmeyecek ve hiçbir belge bulamadım.
  • Dulwich: En umut verici (en azından istediğim ve gördüklerim için). Yumurtası Python kaynağı ile geldiğinden beri onunla ilerleme kaydettim, GitPython'dan daha fazla. Ancak bir süre sonra yaptığım şeyi denemenin daha kolay olabileceğine karar verdim.

Ayrıca, StGit ilginç görünüyor, ama ayrı bir modülde ayıklanan işlevselliğe ihtiyacım var ve şu anda bunun gerçekleşmesini beklemek istemiyorum.

Üç modülden çalışmayı denemeye harcadığımdan çok daha az sürede, alt süreç modülü üzerinden çalışıp git komutlarını almayı başardım.

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, ama belki de bir hız beklemiyorum (zaman zaman yüzlerce hatta binlerce dosya işleyeceğim).

Belki de Dulwich ya da GitPython ile bir şeyler yapmak için sabrım yoktu. Dedi ki, modüller daha fazla gelişme ve yakında daha yararlı olacak umarım.


64
2017-09-25 21:26



Bir süre önce bu yaklaşımı da aldım, çünkü ihtiyaçlarım için uygun oldu. - Tzury Bar Yochay
Bu cevap yaşlanıyor. - Alex Chamberlain
Evet, bir güncellemeyle ilgilenirim. - JosefAssad


Tavsiye ederim pygit2 - mükemmel kullanıyor libgit2 bağlamaları


27
2018-06-04 17:04



Git tesisatına da en iyi şekilde erişim sağlar. - pielgrzym
pygit2 gerçekten kullanışlı bir kütüphanedir ve gelecekte genişlemeyi dört gözle bekliyorum! - Alex Chamberlain
Şimdi olduğu gibi, her ikisinin de yarı kararlı sürümlerini manuel olarak indirmeli ve kurmalı / ayarlamalıdır. libgit ve pygit2Kaynağı GitHub'dan alarak. Sorun şu ki, kafa dalları testler bozuldu ve en son "kararlı" arıza kurulumu ... Güvenilirlik önemliyse ve çeşitli ortamlarda dağıtmanız gerekiyorsa uygun bir çözüm değil ... :( - mac
Eğer cygwin kullanarak müşterileri planlıyorsanız, bu kombinasyondan uzak durun. pygit2 libgit2 için bir sarıcı ve libgit2 tüm cygwin desteğini bıraktı. Dev'in birinden aldığım yorum, "Deneyebilirsin, ama güzel bir API yaparsa, bu bir mucizedir, evet, ama müşterilerimin yarısı cygwin'dir, bu yüzden onu kullanamıyorum. Muhtemelen GitPython'a gidiyor. - scphantm
Mac’deki Homebrew’la birlikte bunu keyifli bir şekilde buldum. brew install libgit2; pip install pygit2 - geowa4


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

Benim için harika çalıştı (çalıştığım diğer insanlar lapa lapaçıktı) ve ortak eylemlerin çoğunu kapsadığı görülü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()

18
2017-08-25 20:35



Ben onları "dizine eklemek" yerine "sahne" dosyaları sevmiyorum. Ortak / önemli operasyonların isimlerini değiştirmek sadece kafa karıştırıcı gibi görünüyor. - underrun
@underrun ekleme, sahneye dosya ekliyor. Evreleme ile aynı şey değil mi? - Jimmy Kane
dosya eklemek, işlenecek dosyaları hazırlamadır (bunları dizine ekliyor). işlem aynıdır ancak yazdığınız komut satırında git add other1.txt other2.txt bu yüzden beklenecek olanı takip etmiyor. - underrun
Bu paketin üstünlüğü konusunda anlaştılar. Pythonista uygulamasında, paketlendiği StaSh'i yükledikten sonra bile kullanabildim. Ayrıca, cevabınızın bu soruya verilen cevaplardan en güncel olarak güncellenmiş olduğunu da belirtmek gerekir. - Chris Redford
Aslında öyle görünüyor bir tek Pythonista'da benim için çalış. Mac'imde özel bir bitbucket repo bir klonunu doğrulamak için şifre almak sonunda nihayet pes ettim bir kabus oldu. - Chris Redford


Belki yardımcı olur, ancak Çarşı ve Mercurial her ikisi de Git birlikte çalışabilirliği için dulwich kullanıyor.

Dulwich, muhtemelen python'da gitmenin yeniden tasarlanması anlamında diğerlerinden farklıdır. Diğeri sadece Git'in komutları etrafında bir sarıcı olabilir (bu yüzden yüksek düzeyde bir bakış açısından kullanmak daha kolay olabilir: commit / add / delete), muhtemelen onların API'sinin git komutunun satırına çok yakın olması gerektiği anlamına gelir. Git ile deneyim kazanmak için.


15
2017-09-22 09:09



Çok yararlı bir cevap, Mercurial'ın Dulwich'i kullanıp kullanmadığını bilmiyordum, teşekkürler! - kissgyorgy


Bütünlüğü uğruna, http://github.com/alex/pyvcs/ tüm dvcs'ler için bir soyutlama katmanıdır. Dulwich kullanır, ancak diğer dvcs'lerle birlikte çalışır.


6
2018-04-21 02:23





Değiştirilen süreleri yansıtan güncellenmiş bir cevap:

GitPython şu anda kullanımı en kolay olanıdır. Birçok tesisat sıyırma komutunun sarılmasını destekler ve takılabilir nesne veritabanına (bunlardan biri olan dulwich) sahiptir ve bir komut uygulanmadığında 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ıları:

bash$ git checkout -b new_branch

Dulwich de iyi ama çok daha düşük seviyede. Bu, kullanım için bir acıdır çünkü tesisat seviyesinde git nesneleri üzerinde çalışmayı gerektirir ve normalde yapmak istediğiniz güzel porselene sahip değildir. Ancak, git'in herhangi bir bölümünü değiştirmeyi planlıyorsanız veya git-alma-pack ve git-upload-pack'i kullanıyorsanız, dulwich'i kullanmanız gerekir.


6
2017-09-20 09:44





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

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)

2
2017-10-07 02:31



Çok fazla kod tekrarı görüyorum ...: p - Ciasto piekarz
Teşekkürler bayım! - Norfeldt


İşte "git durumunun" hızlı bir şekilde uygulanması:

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

1
2018-04-30 14:13



Ben ayrıştırma tavsiye etmem git status - Ehtesh Choudhury
ayrıştırma git status --short daha kolay olurdu ve bence --short Çıkışın değişmesi daha az olasıdır. - Ben Page
kullanım git status --porcelain bunun için --porcelain: Give the output in a stable, easy-to-parse format for scripts... - estani
Veya daha da iyisi, kullan --z yerine --porcelain. aksine --porcelain, --z dosya isimleri kaçmaz. - Vojislav Stojkovic