Как отправить новые файлы на 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 после долгого поиска.
7 ответов
Я пытался использовать 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()
Примечание. Эта версия сценария была запущена в родительском каталоге хранилища.
Примечание. Эта версия скрипта была вызвана из репозитория 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. Это приводит к двум отдельным фиксациям в хранилище, что, вероятно, не то, что вам нужно.
Я могу оказать вам некоторую информационную поддержку, но также и одно конкретное решение.
Здесь вы можете найти примеры добавления новых файлов в ваш репозиторий, и вот видеоурок для этого.
Ниже вы можете увидеть список пакетов Python, которые работают с GitHub, которые можно найти на странице разработчиков GitHub:
Но вы также можете отправить свои файлы командами в 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
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 для отслеживания всех файлов в проекте/даже в родительском каталоге. Используя 'gitadd.' будет отслеживать только те файлы внутри cwd, где написан этот код.
import subprocess
p = subprocess.Popen("git rev-parse HEAD".split(), stdout=subprocess.PIPE)
out, err = p.communicate()
sha = out.strip()
Вероятно, есть способ сделать это с PyGithub, но это должно работать для быстрого взлома.
Если вам не нужен pygithub, git-библиотека dulwich предлагает команды git высокого уровня. Для команд посмотрите на https://www.dulwich.io/apidocs/dulwich.porcelain.html