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.