Forma de Python para clonar un repositorio de git

83

¿Existe una forma de Python sin usar un subproceso para clonar un repositorio de git? Estoy dispuesto a usar cualquier tipo de módulo que recomiende.

Miguel
fuente
3
gitpy, supongo que sería llamado
SilentGhost
@SilentGhost: ¿te refieres a este gitpy? github.com/vmalloc/gitpy de ryaari.com/blog/?p=9
VonC
Parece que hay GitPython ( pypi.python.org/pypi/GitPython , gitorious.org/git-python ) que no creo que tenga un método de clonación, pero apuesto a que podría agregar uno ... internamente va a git cloneaunque tengo que llamar de todos modos.
Cascabel
1
[Dulwich] [1] es una implementación de Git en Python puro que no se bifurca en absoluto. Tenga en cuenta que todavía está en desarrollo, por lo que puede tener errores. [1]: samba.org/~jelmer/dulwich
Mark Lodato

Respuestas:

57

Existe GitPython . No he oído hablar de él antes e internamente, se basa en tener los ejecutables git en alguna parte; además, pueden tener muchos errores. Pero podría valer la pena intentarlo.

Cómo clonar :

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

(No es agradable y no sé si es la forma admitida de hacerlo, pero funcionó).

Debilski
fuente
Lo hace. Pero es un poco complicado.
Debilski
1
Oh, mi mal, perdí esa posibilidad. Mike, recuerda, internamente esto es simplemente llamar al ejecutable git de todos modos; es solo manejarlo un poco por ti.
Cascabel
Miré a gitorious ... simplemente pasé por alto la opción de clonar ya que no está documentada en absoluto ... pero esperaba cualquier tipo de comando de proceso ... ¡esto funciona gracias!
Mike
Este módulo fue realmente útil, gracias. ¿Me pueden ayudar a extraer la rama maestra del repositorio ya clonado usando este módulo
El Gr8 Adakron
1
¿Cómo manejar la autenticación si tiene que ejecutarse de forma automatizada?
Domingos
130

El uso de GitPython le proporcionará una buena interfaz de Python para Git.

Por ejemplo, después de instalarlo ( pip install gitpython), para clonar un nuevo repositorio puede usar la función clone_from :

from git import Repo

Repo.clone_from(git_url, repo_dir)

Consulte el tutorial de GitPython para obtener ejemplos sobre el uso del objeto Repo.

Nota: GitPython requiere que git esté instalado en el sistema y sea accesible a través de la RUTA del sistema.

Amir Ali Akbari
fuente
¿Cómo manejar la autenticación si tiene que ejecutarse de forma automatizada?
Domingos
Puede proporcionar la autenticación en git_url, dependiendo de dónde clone el repositorio, es posible que deba ingresar el nombre de usuario y la contraseña / pat allí. Ver aquí para Github
LemurPwned el
18

Mi solución es muy simple y directa. Ni siquiera necesita la entrada manual de frase de paso / contraseña.

Aquí está mi código completo:

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
Manje
fuente
1
Funciona muy bien, sin embargo, si usa otras rutas relativas en su proyecto, es posible que desee recordar el directorio de trabajo real os.getcwd()antes de cambiarlo os.chdir(...)y restablecerlo después.
Maximosaic
9

El enlace libgit2 de Github , pygit2 proporciona una clonación de una sola línea de un directorio remoto:

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

Aquí hay una forma de imprimir el progreso mientras se clona un repositorio con 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())
crizCraig
fuente
1
Aquí hay algunas pautas para ¿Cómo escribo una buena respuesta? . Esta respuesta proporcionada puede ser correcta, pero podría beneficiarse de una explicación. Las respuestas de solo código no se consideran respuestas "buenas". De revisión .
Trenton McKinney
5

Para python 3

Primer módulo de instalación:

pip3 install gitpython

y luego codifícalo :)

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

Espero que esto te ayude

Mike Brian Olivera
fuente
3

Con la sugerencia de Dulwich, debería poder hacer:

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

Esto sigue siendo muy básico: copia a través de los objetos y las referencias, pero aún no crea el contenido del árbol de trabajo si crea un repositorio no básico.

jelmer
fuente
3

Un método bastante simple es simplemente pasar las credenciales en la URL, aunque puede ser un poco sospechoso, utilícelo con precaución.

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'})
haku-kiro
fuente
1

Este es el código de muestra para gitpull y gitpush usando el módulo 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 "[email protected]: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('')
vk
fuente
0

Puedes usar dload

import dload
dload.git_clone("https://github.com/some_repo.git")

pip install dload
Pedro Lobito
fuente