Cách sao chép kho lưu trữ git trong Python


83

Có cách nào trong Python mà không cần sử dụng quy trình con để sao chép kho lưu trữ git không? Tôi sẵn sàng sử dụng bất kỳ loại mô-đun nào mà bạn đề xuất.


3
gitpy, tôi đoán nó sẽ được gọi
SilentGhost

@SilentGhost: ý bạn là gitpy này ? github.com/vmalloc/gitpy từ ryaari.com/blog/?p=9
VonC

Có vẻ như có GitPython ( pypi.python.org/pypi/GitPython , gitorious.org/git-python ) mà tôi không nghĩ là có phương pháp sao chép, nhưng tôi cá là bạn có thể thêm một phương pháp ... nội bộ nó sẽ git clonedù sao cũng phải gọi .
Cascabel

1
[Dulwich] [1] là một triển khai Python thuần túy của Git hoàn toàn không rẽ nhánh. Hãy lưu ý rằng nó vẫn đang được phát triển, vì vậy nó có thể bị lỗi. [1]: samba.org/~jelmer/dulwich
Đánh dấu Lodato

Câu trả lời:


57

GitPython . Chưa từng nghe nói về nó trước đây và trong nội bộ, nó dựa vào việc có các tệp thực thi git ở đâu đó; ngoài ra, chúng có thể có nhiều lỗi. Nhưng nó có thể đáng để thử.

Cách sao chép :

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

(Nó không hay và tôi không biết đó có phải là cách được hỗ trợ để làm điều đó hay không, nhưng nó đã hiệu quả.)


Nó có. Nhưng nó là một chút phức tạp.
Debilski

1
Ôi, tệ thật, tôi đã bỏ lỡ khả năng đó. Mike, chỉ cần nhớ rằng, nội bộ đây chỉ là gọi git thực thi; nó chỉ quản lý nó một chút cho bạn.
Cascabel

Tôi đã nhìn vào gitorious .. chỉ bỏ qua tùy chọn nhân bản vì nó không được ghi lại chút nào .. nhưng tôi mong đợi bất cứ điều gì tôi đã sử dụng với một số loại lệnh xử lý .. điều này hoạt động, cảm ơn!
Mike

Mô-đun này thực sự hữu ích, cảm ơn bạn. Bạn có thể giúp tôi cách kéo nhánh chính của repo đã được
sao chép

1
Làm thế nào để xử lý xác thực nếu nó phải chạy theo cách tự động?
SunilS

130

Sử dụng GitPython sẽ cung cấp cho bạn một giao diện python tốt cho Git.

Ví dụ: sau khi cài đặt nó ( pip install gitpython), để sao chép một kho lưu trữ mới, bạn có thể sử dụng hàm clone_from :

from git import Repo

Repo.clone_from(git_url, repo_dir)

Xem Hướng dẫn GitPython để biết các ví dụ về cách sử dụng đối tượng Repo.

Lưu ý: GitPython yêu cầu cài đặt git trên hệ thống và có thể truy cập thông qua PATH của hệ thống.


Làm thế nào để xử lý xác thực nếu nó phải chạy theo cách tự động?
SunilS

Bạn có thể cung cấp xác thực trong git_url, tùy thuộc vào nơi bạn sao chép repo, bạn có thể cần đặt tên người dùng và mật khẩu / pat vào đó. Xem ở đây cho Github
LemurPwned

18

Giải pháp của tôi rất đơn giản và dễ hiểu. Nó thậm chí không cần nhập cụm mật khẩu / mật khẩu theo cách thủ công.

Đây là mã hoàn chỉnh của tôi:

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
Hoạt động tốt, tuy nhiên nếu bạn sử dụng các đường dẫn tương đối khác trong dự án của mình, bạn có thể muốn nhớ thư mục làm việc thực sự os.getcwd()trước khi thay đổi nó os.chdir(...)và đặt lại sau đó.
Maximosaic

9

Liên kết libgit2 của Github , pygit2 cung cấp một bản sao một lớp lót một thư mục từ xa:

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

7

Đây là một cách để in tiến trình trong khi sao chép một repo với 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
Dưới đây là một số hướng dẫn về Làm cách nào để viết một câu trả lời tốt? . Câu trả lời được cung cấp này có thể đúng, nhưng nó có thể có lợi từ một lời giải thích. Câu trả lời chỉ có mã không được coi là câu trả lời "tốt". Từ đánh giá .
Trenton McKinney

5

Đối với python 3

Mô-đun cài đặt đầu tiên:

pip3 install gitpython

và sau đó, hãy viết mã nó :)

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

Tôi hy vọng cái này sẽ giúp bạn


3

Với mẹo Dulwich, bạn sẽ có thể làm:

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

Điều này vẫn rất cơ bản - nó sao chép qua các đối tượng và các tham chiếu, nhưng nó chưa tạo ra nội dung của cây làm việc nếu bạn tạo một kho lưu trữ không phải của riêng mình.


3

Phương pháp khá đơn giản là chỉ cần vượt qua các khoản tín dụng trong url, mặc dù có thể hơi nghi ngờ - hãy sử dụng một cách thận trọng.

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

Đây là mã mẫu cho gitpull và gitpush sử dụng mô-đun 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

Bạn có thể sử dụng dload

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

pip install dload
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.