Способ Python клонировать репозиторий git


88

Есть ли способ Python без использования подпроцесса для клонирования репозитория git? Я за использование любых модулей, которые вы рекомендуете.


3
gitpy, я думаю, это будет называться
SilentGhost

@SilentGhost: вы имеете в виду этот gitpy? 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

Я посмотрел на чудовищный ... просто пропустил опцию клонирования, так как она вообще не задокументирована ... но я ожидал того, что я использовал для какой-то команды процесса ... это работает, спасибо!
Майк,

Этот модуль был действительно полезен, спасибо. Можете ли вы помочь мне, как вытащить основную ветку уже клонированного репо с помощью этого модуля
Gr8 Adakron

1
Как обрабатывать аутентификацию, если она должна выполняться автоматически?
SunilS

136

Использование GitPython предоставит вам хороший интерфейс Python для Git.

Например, после установки it ( pip install gitpython) для клонирования нового репозитория вы можете использовать функцию clone_from :

from git import Repo

Repo.clone_from(git_url, repo_dir)

См. Учебник GitPython для примеров использования объекта Repo.

Примечание: GitPython требует, чтобы git был установлен в системе и доступен через системный PATH.


Как обрабатывать аутентификацию, если она должна выполняться автоматически?
SunilS

Вы можете предоставить аутентификацию в git_url, в зависимости от того, откуда вы клонируете репо, вам может потребоваться ввести туда имя пользователя и пароль / pat. См. Здесь для Github
LemurPwned

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

@Maximosaic этого можно избежать, используя git clone <repo_url> <target_path>. Нет необходимости использоватьchdir
Лахиру Чандима

работают только на linux и mac. не работает на windows
matan h

9

Привязка Github libgit2 , pygit2 обеспечивает однострочное клонирование удаленного каталога:

clone_repository(url, path, 
    bare=False, repository=None, remote=None, checkout_branch=None, callbacks=None)

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
Вот несколько советов о том, как написать хороший ответ? . Этот предоставленный ответ может быть правильным, но для него может быть полезно объяснение. Ответы только на код не считаются "хорошими" ответами. Из обзора .
Трентон МакКинни

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.