2016-07-26 25 views
11

Tôi tạo ra một kho lưu trữ mới trên github.com và sau đó nhân bản nó vào máy địa phương của tôi vớiLàm cách nào để đẩy các tệp mới vào GitHub?

git clone https://github.com/usrname/mathematics.git 

tôi đã thêm 3 file mới trong thư mục mathematics

$ tree 
. 
├── LICENSE 
├── numerical_analysis 
│   └── regression_analysis 
│    ├── simple_regression_analysis.md 
│    ├── simple_regression_analysis.png 
│    └── simple_regression_analysis.py 

Bây giờ, tôi muốn tải lên 3 tệp mới vào GitHub của tôi bằng Python, cụ thể hơn, PyGithub. Dưới đây là những gì tôi đã cố gắng:

#!/usr/bin/env python 
# *-* coding: utf-8 *-* 
from github import Github 

def main(): 
    # Step 1: Create a Github instance: 
    g = Github("usrname", "passwd") 
    repo = g.get_user().get_repo('mathematics') 

    # Step 2: Prepare files to upload to GitHub 
    files = ['mathematics/numerical_analysis/regression_analysis/simple_regression_analysis.py', 'mathematics/numerical_analysis/regression_analysis/simple_regression_analysis.png'] 

    # Step 3: Make a commit and push 
    commit_message = 'Add simple regression analysis' 

    tree = repo.get_git_tree(sha) 
    repo.create_git_commit(commit_message, tree, []) 
    repo.push() 

if __name__ == '__main__': 
    main() 

Tôi không biết

  • làm thế nào để có được chuỗi sha cho repo.get_git_tree
  • làm thế nào để tôi thực hiện một mối liên hệ giữa bước 2 và 3, tức là đẩy các tệp cụ thể

Cá nhân, PyGithub documentation không thể đọc được. Tôi không thể tìm thấy api phù hợp sau khi tìm kiếm trong thời gian dài.

+1

Để có được 'sha' bạn sẽ cần phải sử dụng' hashlib' –

+5

@WayneWerner đó chắc chắn * không * những gì anh ấy nên làm. 'Sha' được tính bằng' git' và bạn gần như chắc chắn sẽ sai nếu bạn cố tính nó. –

+0

@BrianMalehorn Tôi đã có một kịch bản bash mà sẽ tải lên cam kết git của tôi thông qua CURL và api github, IIRC - nó không * mà * xấu. –

Trả lời

7

tôi cố gắng sử dụng GitHub API để thực hiện nhiều tệp. Trang này cho Git Data API nói rằng nó phải là "khá đơn giản". Để biết kết quả của cuộc điều tra đó, hãy xem this answer.

tôi khuyên bạn nên sử dụng một cái gì đó giống như GitPython:

from git import Repo 

repo_dir = 'mathematics' 
repo = Repo(repo_dir) 
file_list = [ 
    'numerical_analysis/regression_analysis/simple_regression_analysis.py', 
    'numerical_analysis/regression_analysis/simple_regression_analysis.png' 
] 
commit_message = 'Add simple regression analysis' 
repo.index.add(file_list) 
repo.index.commit(commit_message) 
origin = repo.remote('origin') 
origin.push() 

Lưu ý: Phiên bản này của kịch bản đã được chạy trong thư mục cha của kho.

0
import subprocess 
p = subprocess.Popen("git rev-parse HEAD".split(), stdout=subprocess.PIPE) 
out, err = p.communicate() 
sha = out.strip() 

Có thể là cách để làm điều này với PyGithub, nhưng thao tác này sẽ hoạt động để nhanh chóng hack.

0

Nếu bạn không cần pygithub cụ thể, thư viện git dulwich cung cấp high level git commands. Đối với các lệnh, hãy xem https://www.dulwich.io/apidocs/dulwich.porcelain.html

+0

Thx để phản hồi nhanh. Sẽ rất tuyệt nếu bạn có thể cung cấp một MWE. – SparkAndShine

+0

@sparkandshine Xin lỗi - MWE là gì? Ví dụ làm việc tối thiểu? – janbrohl

+0

Chính xác, [Ví dụ làm việc tối thiểu] (https://en.wikipedia.org/wiki/Minimal_Working_Example) – SparkAndShine

1

Tôi có thể cung cấp cho bạn một số hỗ trợ thông tin, nhưng cũng là một giải pháp cụ thể.

Here bạn có thể tìm thấy ví dụ về cách thêm tệp mới vào kho lưu trữ của mình và here là video hướng dẫn cho việc này.

Dưới đây bạn có thể thấy một danh sách các gói python mà làm việc với GitHub tìm thấy trên trang nhà phát triển của GitHub:

Nhưng cũng có thể bạn có thể đẩy tập tin của bạn với lệnh trong IPython nếu bạn cần:

In [1]: import subprocess 
In [2]: print subprocess.check_output('git init', shell=True) 
Initialized empty Git repository in /home/code/.git/ 
In [3]: print subprocess.check_output('git add .', shell=True) 
In [4]: print subprocess.check_output('git commit -m "a commit"', shell=True) 
1

Nếu tài liệu của PyGithub không thể sử dụng được (và nó không giống như vậy), và bạn chỉ muốn đẩy một cam kết (không làm bất cứ điều gì ưa thích với các vấn đề, cấu hình repo, vv), có lẽ bạn nên tắt trực tiếp giao tiếp với git, hoặc gọi git thực thi hoặc sử dụng thư viện trình bao bọc như GitPython.

Sử dụng git trực tiếp với một cái gì đó như subprocess.Popen mà bạn đề cập đến có lẽ sẽ dễ dàng hơn trên đường cong nghiêng, mà còn khó khăn hơn trong thời gian dài để xử lý lỗi, vv từ bạn không thực sự có trừu tượng tốt đẹp để vượt qua xung quanh và sẽ phải tự phân tích cú pháp.

Loại bỏ PyGithub cũng giúp bạn không bị ràng buộc với GitHub và API của nó, cho phép bạn đẩy tới bất kỳ repo nào, thậm chí một thư mục khác trên máy tính của bạn.

1

Lưu ý: Phiên bản này của tập lệnh được gọi từ bên trong kho GIT vì tôi đã xóa tên kho lưu trữ khỏi đường dẫn tệp.

cuối cùng tôi đã tìm ra cách sử dụng PyGithub cam kết nhiều file:

import base64 
from github import Github 
from github import InputGitTreeElement 

token = '5bf1fd927dfb8679496a2e6cf00cbe50c1c87145' 
g = Github(token) 
repo = g.get_user().get_repo('mathematics') 
file_list = [ 
    'numerical_analysis/regression_analysis/simple_regression_analysis.png', 
    'numerical_analysis/regression_analysis/simple_regression_analysis.py' 
] 
commit_message = 'Add simple regression analysis' 
master_ref = repo.get_git_ref('heads/master') 
master_sha = master_ref.object.sha 
base_tree = repo.get_git_tree(master_sha) 
element_list = list() 
for entry in file_list: 
    with open(entry, 'rb') as input_file: 
     data = input_file.read() 
    if entry.endswith('.png'): 
     data = base64.b64encode(data) 
    element = InputGitTreeElement(entry, '100644', 'blob', data) 
    element_list.append(element) 
tree = repo.create_git_tree(element_list, base_tree) 
parent = repo.get_git_commit(master_sha) 
commit = repo.create_git_commit(commit_message, tree, [parent]) 
master_ref.edit(commit.sha) 
""" An egregious hack to change the PNG contents after the commit """ 
for entry in file_list: 
    with open(entry, 'rb') as input_file: 
     data = input_file.read() 
    if entry.endswith('.png'): 
     old_file = repo.get_contents(entry) 
     commit = repo.update_file('/' + entry, 'Update PNG content', data, old_file.sha) 

Nếu tôi cố gắng thêm các dữ liệu thô từ một tập tin PNG, cuộc gọi đến create_git_tree cuối cùng gọi json.dumps trong Requester.py, gây ra các ngoại lệ sau đây được nâng lên:

UnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 0: invalid start byte

Tôi giải quyết vấn đề này bằng cách base64 mã hóa dữ liệu PNG và cam kết điều đó. Sau đó, tôi sử dụng phương thức update_file để thay đổi dữ liệu PNG. Điều này dẫn đến hai cam kết riêng biệt cho kho lưu trữ mà có lẽ không phải là những gì bạn muốn.

Các vấn đề liên quan