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.


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ó).


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.


¿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

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)

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())

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


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.


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'})

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 "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('')

0

Puedes usar dload

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

pip install dload
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.