web-dev-qa-db-fra.com

Comment envoyer de nouveaux fichiers à GitHub?

J'ai créé un nouveau référentiel sur github.com, puis je l'ai cloné sur ma machine locale avec

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

J'ai ajouté 3 nouveaux fichiers dans le dossier mathematics

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

Maintenant, j'aimerais télécharger 3 nouveaux fichiers sur mon GitHub en utilisant Python, plus précisément, PyGithub . Voici ce que j'ai essayé:

#!/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 __== '__main__':
    main()

Je ne sais pas 

  • comment obtenir la chaîne sha pour repo.get_git_tree
  • comment établir une connexion entre les étapes 2 et 3, c’est-à-dire le transfert de fichiers spécifiques

Personnellement, La documentation PyGithub n'est pas lisible. Je suis incapable de trouver le bon api après une longue recherche.

13
SparkAndShine

J'ai essayé d'utiliser l'API GitHub pour valider plusieurs fichiers. Cette page de la Git Data API indique que cela devrait être "assez simple". Pour les résultats de cette enquête, voir cette réponse .

Je recommande d'utiliser quelque chose comme 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()

Remarque: Cette version du script a été exécutée dans le répertoire parent du référentiel.

12
David Cullen

Remarque: Cette version du script a été appelée depuis le référentiel GIT car j'ai supprimé le nom du référentiel des chemins de fichiers.

J'ai enfin compris comment utiliser PyGithub pour valider plusieurs fichiers:

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)

Si j'essaie d'ajouter les données brutes d'un fichier PNG, l'appel à create_git_tree appelle finalement json.dumps dans Requester.py , ce qui provoque la levée de l'exception suivante:

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

Je contourne ce problème en codant base64 en codant les données PNG et en les validant. Plus tard, j’utilise la méthode update_file pour modifier les données PNG. Cela entraîne deux commits distincts dans le référentiel, ce qui n'est probablement pas ce que vous voulez.

4
David Cullen

Si la documentation de PyGithub n'est pas utilisable (et que cela ne semble pas être le cas), et que vous souhaitiez simplement pousser un commit (vous ne feriez rien d'extraordinaire avec les problèmes, la configuration du repo, etc.), il serait probablement préférable de vous connecter directement à git soit en appelant l'exécutable git, soit en utilisant une bibliothèque wrapper telle que GitPython

Utiliser git directement avec quelque chose comme subprocess.Popen que vous avez mentionné serait probablement plus facile sur la courbe penchée, mais aussi plus difficile à long terme pour la gestion des erreurs, etc. puisque vous n'avez pas vraiment d'abstractions de Nice à transmettre, et vous faire l'analyse vous-même.

Se débarrasser de PyGithub vous évite également d'être lié à GitHub et à son API, ce qui vous permet de transférer du contenu vers un dépôt, même un autre dossier sur votre ordinateur.

1
MayeulC

Je peux vous fournir des informations, mais également une solution concrète. 

Ici vous pouvez trouver des exemples d’ajout de nouveaux fichiers à votre référentiel, et ici est un didacticiel vidéo pour cela.

Ci-dessous, vous pouvez voir une liste des paquets python fonctionnant avec GitHub qui se trouvent sur la page de développement de GitHub:

Mais vous pouvez aussi pousser vos fichiers avec des commandes en IPython si vous avez besoin de:

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
vlad.rad
import subprocess
p = subprocess.Popen("git rev-parse HEAD".split(), stdout=subprocess.PIPE)
out, err = p.communicate()
sha = out.strip()

Il y a probablement un moyen de faire cela avec PyGithub, mais cela devrait marcher rapidement.

0
Brian Malehorn

Si vous n'avez pas spécifiquement besoin de pygithub, la bibliothèque git-library de dulwich propose les commandes git de haut niveau . Pour les commandes, regardez https://www.dulwich.io/apidocs/dulwich.porcelain.html

0
janbrohl