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.


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


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.


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

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)

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

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


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.


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

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 "git@github.com: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('')

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.