16

我在 github.com 上创建了一个新存储库,然后将其克隆到我的本地计算机

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

我在文件夹下添加了 3 个新文件mathematics

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

现在,我想使用 Python 将 3 个新文件上传到我的 GitHub,更具体地说,是 PyGithub。这是我尝试过的:

#!/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()

我不知道

  • 如何获取sha字符串repo.get_git_tree
  • 如何在第 2 步和第 3 步之间建立连接,即推送特定文件

就个人而言,PyGithub 文档是不可读的。经过长时间的搜索,我无法找到合适的 api。

4

7 回答 7

18

我尝试使用GitHub API提交多个文件。Git Data API的这个页面说它应该“非常简单”。有关该调查的结果,请参阅此答案

我建议使用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()

注意:此版本的脚本在存储库的父目录中运行。

于 2016-09-21T14:59:19.200 回答
8

注意:这个版本的脚本是从 GIT 存储库中调用的,因为我从文件路径中删除了存储库名称。

我终于想通了如何使用PyGithub提交多个文件:

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)

如果我尝试从 PNG 文件中添加原始数据,create_git_tree最终会调用json.dumpsin Requester.py,这会导致引发以下异常:

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

base64我通过对 PNG 数据进行编码并提交来解决这个问题。后来,我使用该update_file方法更改PNG数据。这会导致对存储库的两次单独提交,这可能不是您想要的。

于 2016-09-21T22:45:25.037 回答
3

我可以给你一些信息支持,但也可以提供一个具体的解决方案。

在这里,您可以找到将新文件添加到存储库的示例,这里有一个视频教程。

下面你可以在 GitHub 的开发者页面上看到与 GitHub 一起工作的 python 包列表:

但如果需要,您也可以使用 IPython 中的命令推送文件:

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)
于 2016-09-21T12:33:37.677 回答
1

使用子流程,这将做同样的工作 -

import subprocess
subprocess.call(['git', 'add', '-A'])
subprocess.call(['git', 'commit', '-m', '{}'.format(commit_message)])
subprocess.call(['git', 'push', 'https://{}@github.com/user-name/repo.git'.format(token)])

确保使用 -A 或 -all 来跟踪项目中的所有文件/甚至在父目录中。使用“混帐添加。” 将仅跟踪编写此代码的 cwd 内的文件。

于 2021-01-28T08:54:39.770 回答
0
import subprocess
p = subprocess.Popen("git rev-parse HEAD".split(), stdout=subprocess.PIPE)
out, err = p.communicate()
sha = out.strip()

PyGithub 可能有一种方法可以做到这一点,但这应该可以快速破解。

于 2016-07-26T16:17:03.457 回答
0

如果您不需要 pygithub,dulwich git-library 提供了高级 git 命令。有关命令,请查看https://www.dulwich.io/apidocs/dulwich.porcelain.html

于 2016-07-26T16:17:20.290 回答
0

如果 PyGithub 的文档不可用(而且看起来不可用),而您只想推送一个提交(不对问题、repo 配置等做任何花哨的事情),那么直接与 git 交互可能会更好,调用git可执行文件或使用包装库,例如GitPython

直接使用git诸如subprocess.Popen您提到的东西可能会在倾斜曲线上更容易,但从长远来看对于错误处理等也更困难,因为您实际上并没有很好的抽象可以传递,并且必须这样做自己解析。

摆脱 PyGithub 还可以让你摆脱对 GitHub 及其 API 的束缚,允许你推送到任何 repo,甚至是你计算机上的另一个文件夹。

于 2016-09-21T17:30:54.440 回答