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.