Sposób w Pythonie na sklonowanie repozytorium git

88

Czy istnieje sposób w Pythonie bez użycia podprocesu do sklonowania repozytorium git? Jestem gotów użyć dowolnego rodzaju modułów, które polecisz.

Mikrofon
źródło
3
gitpy, myślę, że zostałby nazwany
SilentGhost
@SilentGhost: masz na myśli tego gitpy? github.com/vmalloc/gitpy from ryaari.com/blog/?p=9
VonC
Wygląda na to, że istnieje GitPython ( pypi.python.org/pypi/GitPython , gitorious.org/git-python ), który moim zdaniem nie ma metody klonowania, ale założę się, że mógłbyś dodać jeden ... wewnętrznie to będzie git clonemimo to muszę zadzwonić .
Cascabel
1
[Dulwich] [1] to implementacja Gita w czystym Pythonie, która w ogóle się nie rozwidla. Pamiętaj, że wciąż jest w fazie rozwoju, więc może być wadliwy. [1]: samba.org/~jelmer/dulwich
Mark Lodato

Odpowiedzi:

60

Jest GitPython . Nie słyszałem o tym wcześniej i wewnętrznie, polega to na posiadaniu gdzieś plików wykonywalnych git; dodatkowo mogą mieć wiele błędów. Ale warto spróbować.

Jak sklonować :

import git
git.Git("/your/directory/to/clone").clone("git://gitorious.org/git-python/mainline.git")

(To nie jest miłe i nie wiem, czy jest to obsługiwany sposób, ale zadziałało).

Dębilski
źródło
To robi. Ale to jest trochę zawiłe.
Dębilski
1
Och, moja wina, przegapiłem tę możliwość. Mike, pamiętaj tylko, że wewnętrznie i tak jest to po prostu wywołanie pliku wykonywalnego git; po prostu zarządzasz tym trochę za Ciebie.
Cascabel
Patrzyłem na gitorious ... właśnie przeoczyłem opcję klonowania, ponieważ nie jest ona w ogóle udokumentowana ... ale spodziewałem się tego, co kiedyś robiłem z jakimś poleceniem procesu .. to działa, dzięki!
Mike
Ten moduł był bardzo pomocny, dziękuję. Czy możesz mi pomóc, jak wyciągnąć główną gałąź już sklonowanego repozytorium za pomocą tego modułu
Gr8 Adakron
1
Jak obsłużyć uwierzytelnianie, jeśli ma działać w sposób zautomatyzowany?
SunilS,
136

Korzystanie z GitPython zapewni dobry interfejs Pythona do Git.

Na przykład po zainstalowaniu it ( pip install gitpython) do sklonowania nowego repozytorium możesz użyć funkcji clone_from :

from git import Repo

Repo.clone_from(git_url, repo_dir)

Zobacz samouczek GitPython, aby zapoznać się z przykładami używania obiektu Repo.

Uwaga: GitPython wymaga zainstalowania git w systemie i dostępu przez ścieżkę systemu.

Amir Ali Akbari
źródło
Jak obsłużyć uwierzytelnianie, jeśli ma działać w sposób zautomatyzowany?
SunilS,
Możesz podać uwierzytelnianie w git_url, w zależności od tego, skąd klonujesz repozytorium, może być konieczne umieszczenie tam nazwy użytkownika i hasła / patcha. Zobacz tutaj dla Github
LemurPwned
20

Moje rozwiązanie jest bardzo proste i nieskomplikowane. Nie wymaga nawet ręcznego wprowadzania hasła / hasła.

Oto mój pełny kod:

import sys
import os

path  = "/path/to/store/your/cloned/project" 
clone = "git clone gitolite@<server_ip>:/your/project/name.git" 

os.system("sshpass -p your_password ssh user_name@your_localhost")
os.chdir(path) # Specifying the path where the cloned project needs to be copied
os.system(clone) # Cloning
Manje
źródło
1
Działa świetnie, jednak jeśli używasz innych ścieżek względnych w swoim projekcie, możesz zechcieć zapamiętać prawdziwy katalog roboczy os.getcwd()przed zmianą go za pomocą os.chdir(...)i później zresetować.
Maximosaic
@Maximosaic można tego uniknąć, używając git clone <repo_url> <target_path>. Nie trzeba używaćchdir
Lahiru Chandima
działa tylko na Linuksie i Macu. nie działa na oknach
matan h
9

Wiązanie libgit2 na Github , pygit2 zapewnia jednowierszowe klonowanie zdalnego katalogu:

clone_repository(url, path, 
    bare=False, repository=None, remote=None, checkout_branch=None, callbacks=None)
chiffa
źródło
8

Oto sposób na wydrukowanie postępu podczas klonowania repozytorium za pomocą GitPython

import time
import git
from git import RemoteProgress

class CloneProgress(RemoteProgress):
    def update(self, op_code, cur_count, max_count=None, message=''):
        if message:
            print(message)

print('Cloning into %s' % git_root)
git.Repo.clone_from('https://github.com/your-repo', '/your/repo/dir', 
        branch='master', progress=CloneProgress())
crizCraig
źródło
1
Oto kilka wskazówek, jak napisać dobrą odpowiedź? . Ta udzielona odpowiedź może być prawidłowa, ale może skorzystać z wyjaśnienia. Odpowiedzi zawierające tylko kod nie są uważane za „dobre” odpowiedzi. Z recenzji .
Trenton McKinney,
6

Dla Pythona 3

Pierwsza instalacja modułu:

pip3 install gitpython

a później zakoduj :)

import os
from git.repo.base import Repo
Repo.clone_from("https://github.com/*****", "folderToSave")

mam nadzieję, że to Ci pomoże

Mike Brian Olivera
źródło
4

Z końcówką Dulwich powinieneś być w stanie:

from dulwich.repo import Repo
Repo("/path/to/source").clone("/path/to/target")

Jest to nadal bardzo podstawowe - kopiuje między obiektami i referencjami, ale nie tworzy jeszcze zawartości drzewa roboczego, jeśli utworzysz nie-gołe repozytorium.

galaretka
źródło
3

Dość prostą metodą jest po prostu przekazanie kredytów w adresie URL, choć może być nieco podejrzane - używaj ostrożnie.

import os

def getRepo(repo_url, login_object):
  '''
  Clones the passed repo to my staging dir
  '''

  path_append = r"stage\repo" # Can set this as an arg 
  os.chdir(path_append)

  repo_moddedURL = 'https://' + login_object['username'] + ':' + login_object['password'] + '@github.com/UserName/RepoName.git'
  os.system('git clone '+ repo_moddedURL)

  print('Cloned!')


if __name__ == '__main__':
    getRepo('https://github.com/UserName/RepoYouWant.git', {'username': 'userName', 'password': 'passWord'})
haku-kiro
źródło
1

To jest przykładowy kod dla gitpull i gitpush przy użyciu modułu gitpython.

import os.path
from git import *
import git, os, shutil
# create local Repo/Folder
UPLOAD_FOLDER = "LocalPath/Folder"
if not os.path.exists(UPLOAD_FOLDER):
  os.makedirs(UPLOAD_FOLDER)
  print(UPLOAD_FOLDER)
new_path = os.path.join(UPLOADFOLDER)
DIR_NAME = new_path
REMOTE_URL = "GitURL"  # if you already connected with server you dont need to give 
any credential
# REMOTE_URL looks "[email protected]:path of Repo"
# code for clone
class git_operation_clone():
  try:
    def __init__(self):
        self.DIR_NAME = DIR_NAME
        self.REMOTE_URL = REMOTE_URL

    def git_clone(self):

        if os.path.isdir(DIR_NAME):
            shutil.rmtree(DIR_NAME)
        os.mkdir(DIR_NAME)
        repo = git.Repo.init(DIR_NAME)
        origin = repo.create_remote('origin', REMOTE_URL)
        origin.fetch()
        origin.pull(origin.refs[0].remote_head)
  except Exception as e:
      print(str(e))
# code for push
class git_operation_push():
  def git_push_file(self):
    try:
        repo = Repo(DIR_NAME)
        commit_message = 'work in progress'
        # repo.index.add(u=True)
        repo.git.add('--all')
        repo.index.commit(commit_message)
        origin = repo.remote('origin')
        origin.push('master')
        repo.git.add(update=True)
        print("repo push succesfully")
    except Exception as e:
        print(str(e))
if __name__ == '__main__':
   a = git_operation_push()
   git_operation_push.git_push_file('')
   git_operation_clone()
   git_operation_clone.git_clone('')
vk
źródło
1

Możesz użyć dload

import dload
dload.git_clone("https://github.com/some_repo.git")

pip install dload
Pedro Lobito
źródło