Как мне отправить новые файлы на GitHub?

Я создал новый репозиторий на 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

Теперь я хотел бы загрузить 3 новых файла на мой GitHub с помощью Python, более конкретно,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 после долгого поиска.

 SparkAndShine21 сент. 2016 г., 11:24
@MayeulC, я больше знаком с Python. Мне легче выбрать конкретные файлы для отправки.
 Brian Malehorn26 июл. 2016 г., 18:03
@WayneWerner это определенноне что он должен делать.sha вычисляетсяgit и вы почти наверняка ошибетесь, если попытаетесь сами это вычислить.
 Wayne Werner26 июл. 2016 г., 18:06
@BrianMalehorn У меня был bash-скрипт, который загружал бы мои git-коммиты через CURL и github api, IIRC - это не тактот плохой.
 vlad.rad22 сент. 2016 г., 12:45
@ sparkandshine, пожалуйста, расскажите нам, что вы пробовали и что сработало в конце? Это будет ценная информация для всех, я думаю.
 MayeulC21 сент. 2016 г., 11:01
Почему бы не использовать скрипт bash? Я полагаю, вам следует установить bash в git в вашей среде. Затем вы можете нажать через SSH с ключом аутентификации.
 SparkAndShine26 июл. 2016 г., 18:14
Могу ли я узнать причину понижения?
 SparkAndShine21 сент. 2016 г., 14:01
@MayeulC, спасибо за эту информацию. Я тоже рассматриваюsubprocess.Popen, В любом случае, я попробую GitPython, как вы упомянули. Кстати, вы можете ответить на вопрос? Срок действия награды истекает через 2 дня.
 MayeulC21 сент. 2016 г., 11:44
Тогда как насчет вызоваgit напрямую с ним взаимодействовать? Или используя интерфейс Python, такой какGitPython, не обязательно GitHub ориентированный? Его документация действительно ... очень скудная, и я бы не стал ее использовать.
 Wayne Werner26 июл. 2016 г., 18:01
Чтобы получитьsha вам нужно будет использоватьhashlib
 Brian Malehorn26 июл. 2016 г., 18:13
Ты использовалsha1sum вычислить git хэш? Если это так, я впечатлен, чтобы получить правильный формат.
 Hasturkun21 сент. 2016 г., 17:47
Насколько я понимаю, документация заключается в том, что вы хотите получить ветку, из которой вы получаете коммит HEAD (из которого вы получаетеsha значения для коммита и базовое дерево). с этим в руке, позвонитеcreate_git_tree передавая ГОЛОВУ дерево в качестве базы, и давая ему списокInputGitTreeElement (настройкаcontent, но оставивsha в одиночку) с вашими модификациями. затем позвонитеcreate_git_commit с твоим новым деревом. Наконец, вам нужно получить ссылку на ветку и обновить ее до нового коммитаsha, Вероятно, легче найти какую-нибудь библиотеку, которая обернет это, чем сделать это самостоятельно.

Ответы на вопрос(6)

Решение Вопроса

Я пытался использовать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()

Замечания: Эта версия скрипта была запущена в родительском каталоге репозитория.

 Juha Untinen03 апр. 2018 г., 22:19
Вы можете добавлять файлы только в корневой каталог или подкаталоги текущего рабочего каталога, но не из родительских каталогов.
 Juha Untinen04 апр. 2018 г., 10:04
Ну, вы можете просто сделатьos.chdir() работать с другим каталогом Dir или Git, например, при использовании отдельного хранилища для резервных копий. Вышесказанное также продолжит работу в «новом» git-проекте.

Я могу оказать вам некоторую информационную поддержку, но также и одно конкретное решение.

Вот вы можете найти примеры добавления новых файлов в ваш репозиторий иВот это видеоурок для этого.

Ниже вы можете увидеть список пакетов Python, которые работают с GitHub, которые можно найти на странице разработчиков GitHub:

PyGithubPygithub3libsaasgithub3.pyсанкцияagithubgithubpyoctohubGithub-колбаtorngithub

Но вы также можете отправить свои файлы командами в 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)

Если документация PyGithub непригодна для использования (и это не выглядит так), и вы просто хотите отправить коммит (не делая ничего сложного с проблемами, конфигурацией репо и т. Д.), Вам, вероятно, будет лучше напрямую взаимодействовать с git, либо зоветgit исполняемый или использующий библиотеку-оболочку, такую ​​какGitPython.

С помощьюgit непосредственно с чем-то вродеsubprocess.Popen то, что вы упомянули, вероятно, будет проще на кривой наклона, но также сложнее в долгосрочной перспективе для обработки ошибок и т. д., поскольку у вас нет действительно хороших абстракций для передачи, и вам придется выполнять синтаксический анализ самостоятельно.

Избавление от PyGithub также освобождает вас от привязки к GitHub и его API, что позволяет вам перемещаться в любое хранилище, даже в другую папку на вашем компьютере.

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

Вероятно, есть способ сделать это с PyGithub, но это должно работать для быстрого взлома.

Замечания: Эта версия скрипта была вызвана из репозитория 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.dumps вRequester.py, который вызывает следующее исключение:

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

Я работаю над этой проблемойbase64 кодирование данных PNG и фиксация этого. Позже я используюupdate_file метод для изменения данных PNG. Это приводит к двум отдельным фиксациям в хранилище, что, вероятно, не то, что вам нужно.

Если вам не нужен pygithub специально, dulwich git-library предлагаеткоманды git высокого уровня, Для команд взглянуть наhttps://www.dulwich.io/apidocs/dulwich.porcelain.html

 SparkAndShine26 июл. 2016 г., 18:22
Спасибо за быстрый ответ. Было бы очень хорошо, если бы вы могли предоставить MWE.
 SparkAndShine26 июл. 2016 г., 19:08
 janbrohl26 июл. 2016 г., 19:10
Думаю, я использовал dulwich в более старом проекте, но на самом деле я использую только обычные команды git через подпроцесс - извините, не работает пример
 janbrohl26 июл. 2016 г., 18:50
@sparkandshine Извините - что такое MWE? Минимальный рабочий пример?

Ваш ответ на вопрос