Python спосіб клонування репозиторію git


88

Чи існує спосіб Python без використання підпроцесу для клонування сховища git? Я готовий використовувати будь-які модулі, які ви рекомендуєте.


3
gitpy, мабуть, це було б названо
— SilentGhost

@SilentGhost: ти маєш на увазі цього хитрого? github.com/vmalloc/gitpy від ryaari.com/blog/?p=9
— VonC

Схоже, є GitPython ( pypi.python.org/pypi/GitPython , gitorious.org/git-python ), який, на мою думку, не має методу клонування, але, впевнений, ви могли б додати його ... внутрішньо він буде все git cloneодно доводиться телефонувати .
— Cascabel

1
[Dulwich] [1] - це реалізація Git на чистому Python, яка взагалі не розгалужується. Майте на увазі, що він все ще знаходиться в розробці, тому він може бути помилковим. [1]: samba.org/~jelmer/dulwich
— Марк Лодато

Відповіді:


60

Існує GitPython . Не чув про це раніше і внутрішньо, він покладається на наявність десь виконуваних файлів git; крім того, у них може бути багато помилок. Але варто було б спробувати.

Як клонувати :

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

(Це не приємно, і я не знаю, чи підтримується це способом, але це спрацювало.)


Це робить. Але це трохи заплутано.
— Debilski

1
О, боже, я пропустив таку можливість. Майк, тільки пам’ятай, всередині це все одно просто викликає виконуваний файл git; це просто трохи вам це вдається.
— Cascabel

Я подивився на gitorious .. просто пропустив варіант клонування, оскільки його взагалі не задокументовано .. але я очікував, що я звик, до якоїсь команди процесу .. це працює, спасибі!
— Mike

Цей модуль був дуже корисний, дякую. Чи можете ви мені допомогти, як витягнути головну гілку вже клонованого репо за допомогою цього модуля
— The Gr8 Adakron,

1
Як обробити автентифікацію, якщо вона повинна запускатися автоматизовано?
— SunilS

136

Використання GitPython дасть вам хороший інтерфейс python для Git.

Наприклад, після встановлення його ( pip install gitpython) для клонування нового сховища ви можете використовувати функцію clone_from :

from git import Repo

Repo.clone_from(git_url, repo_dir)

Див. Підручник з GitPython для прикладів використання об'єкта Repo.

Примітка: GitPython вимагає встановлення git в системі та доступу до нього через PATH системи.


Як обробити автентифікацію, якщо вона повинна запускатися автоматизовано?
— SunilS

Ви можете надати аутентифікацію в git_url, залежно від того, де ви клонуєте репо, вам може знадобитися помістити туди ім’я користувача та пароль / пат. Дивіться тут Github
— Lemur, винесено

20

Моє рішення дуже просте і прямолінійне. Він навіть не потребує ручного введення парольної фрази / пароля.

Ось мій повний код:

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
Чудово працює, однак, якщо ви використовуєте інші відносні шляхи у своєму проекті, можливо, ви захочете запам'ятати справжній робочий каталог os.getcwd()перед тим, як змінити його, os.chdir(...)і скинути його назад після цього.
— Максимозаїка

@Maximosaic цього можна уникнути, використовуючи git clone <repo_url> <target_path>. Не потрібно використовуватиchdir
— Лахіру Чандіма

працювати тільки на linux та mac. не працювати на вікнах
— matan h


8

Ось спосіб надрукувати прогрес під час клонування репо за допомогою 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
Ось декілька вказівок щодо того, як написати хорошу відповідь? . Ця надана відповідь може бути правильною, але вона може отримати користь від пояснення. Відповіді лише за кодом не вважаються "хорошими" відповідями. З огляду .
— Trenton McKinney

6

Для python 3

Модуль першої інсталяції:

pip3 install gitpython

і пізніше, кодуйте :)

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

Сподіваюся, це вам допоможе


4

За допомогою наконечника Далвіч ви зможете:

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

Це все ще дуже базово - воно копіює об'єкти та посилання, але ще не створює вміст робочого дерева, якщо ви створюєте непросте сховище.


3

Досить простим методом є просто передача атрибутів в URL-адресі, хоча можна трохи підозрювати - використовуйте з обережністю

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

Це зразок коду для gitpull та gitpush за допомогою модуля 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('')

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.