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.