克隆git存储库的Python方法


83

有没有不使用子进程来克隆git存储库的Python方法吗?我准备使用您推荐的任何种类的模块。


3
gitpy,我想它会被称为
SilentGhost

@SilentGhost:您的意思是这个混蛋?ryaari.com/blog/?p=9上github.com/vmalloc/gitpy
VonC

貌似有GitPython(pypi.python.org/pypi/GitPythongitorious.org/git-python),我不认为有一个克隆的方法,但我敢打赌,你可以添加一个...在内部它会git clone无论如何还是要打电话。
卡斯卡贝尔

1
[Dulwich] [1]是完全不分叉的Git的纯Python实现。请注意,它仍在开发中,因此可能有问题。[1]:samba.org/~jelmer/dulwich
Mark Lodato 2010年

Answers:


57

GitPython。之前和内部都没有听说过,它依赖于git可执行文件的位置。另外,他们可能有很多错误。但这可能值得一试。

如何克隆

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

(这不是很好,我不知道这是否是受支持的方法,但确实有效。)


是的 但这有点令人费解。
Debilski 2010年

1
哦,我的天哪,我错过了这种可能性。Mike,请记住,在内部,这只是调用git可执行文件。它只是为您管理一点。
卡斯卡贝尔

我看着很奇怪..只是忽略了克隆选项,因为它根本没有记录..但是我希望我习惯了某种过程命令。.谢谢!
Mike

这个模块真的很有帮助,谢谢。您能帮助我如何使用此模块拉出已克隆
的仓库

1
如果必须以自动方式运行身份验证,该如何处理?
SunilS

130

使用GitPython将为您提供一个良好的Git python接口。

例如,在安装(pip install gitpython)后,要克隆新的存储库,可以使用clone_from函数:

from git import Repo

Repo.clone_from(git_url, repo_dir)

有关使用Repo对象的示例,请参见GitPython教程

注意: GitPython需要将git安装在系统上,并且可以通过系统的PATH进行访问。


如果必须以自动方式运行身份验证,该如何处理?
SunilS

您可以在git_url中提供身份验证,具体取决于克隆存储库的位置,您可能需要在其中放置用户名和密码/ pat。Github
LemurPwned

18

我的解决方案非常简单直接。它甚至不需要手动输入密码/密码。

这是我完整的代码:

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 '18

9

Github的libgit2绑定,pygit2提供了一个单行克隆远程目录:

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

7

这是在使用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
以下是一些有关如何编写好的答案的指导原则。提供的答案可能是正确的,但可以从解释中受益。仅代码答案不视为“好”答案。从审查
特伦顿·麦金尼

5

对于python 3

首先安装模块:

pip3 install gitpython

然后编码:)

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

我希望这可以帮助你


3

使用Dulwich技巧,您应该可以:

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

这仍然是非常基本的-它跨对象和refs复制,但是如果您创建一个非裸仓库,它还不会创建工作树的内容。


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

这是使用gitpython模块的gitpull和gitpush的示例代码。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.