How do I push new files to GitHub?
I created a new repository on github.com and then cloned it to my local machine with
git clone https://github.com/usrname/mathematics.git
I added 3 new files under the folder
$ tree . ├── LICENSE ├── numerical_analysis │ └── regression_analysis │ ├── simple_regression_analysis.md │ ├── simple_regression_analysis.png │ └── simple_regression_analysis.py
Now, I’d like to upload 3 new files to my GitHub using Python, more specifically, PyGithub. Here is what I have tried:
#!/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()
I don’t know
- how to get the string
- how do I make a connection between step 2 and 3, i.e. pushing specific files
Personally, PyGithub documentation is not readable. I am unable to find the right api after searching for long time.
6 Solutions collect form web for “How do I push new files to GitHub?”
I tried to use the GitHub API to commit multiple files. This page for the Git Data API says that it should be “pretty simple”. For the results of that investigation, see this answer.
I recommend using something like 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()
Note: This version of the script was run in the parent directory of the repository.
If PyGithub’s documentation is not usable (and it doesn’t look so), and you just want to push a commit (not doing anything fancy with issues, repo configuration, etc.), you would probably be better off directly interfacing with git, either calling the
git executable or using a wrapper library such as GitPython.
git directly with something such as
subprocess.Popen that you mentioned would probably be easier on the leaning curve, but also more difficult in the long term for error handling, etc. since you don’t really have nice abstractions to pass around, and would have to do the parsing yourself.
Getting rid of PyGithub also frees you from being tied to GitHub and its API, allowing you to push to any repo, even another folder on your computer.
I can give you some information support, but also one concrete solution.
Here you can find examples of adding new files to your repository, and here is a video tutorial for this.
Below you can see a list of python packages that work with GitHub found on the developer page of GitHub:
But also you can push your files with commands in IPython if you need:
In : import subprocess In : print subprocess.check_output('git init', shell=True) Initialized empty Git repository in /home/code/.git/ In : print subprocess.check_output('git add .', shell=True) In : print subprocess.check_output('git commit -m "a commit"', shell=True)
Note: This version of the script was called from inside the GIT repository because I removed the repository name from the file paths.
I finally figured out how to use PyGithub to commit multiple files:
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)
If I try to add the raw data from a PNG file, the call to
create_git_tree eventually calls
Requester.py, which causes the following exception to be raised:
UnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 0: invalid start byte
I work around this problem by
base64 encoding the PNG data and committing that. Later, I use the
update_file method to change the PNG data. This results in two separate commits to the repository which is probably not what you want.
import subprocess p = subprocess.Popen("git rev-parse HEAD".split(), stdout=subprocess.PIPE) out, err = p.communicate() sha = out.strip()
There’s probably a way to do this with PyGithub, but this should work for a quick hack.
If you do not need pygithub specifically, the dulwich git-library offers high level git commands. For the commands have a look at https://www.dulwich.io/apidocs/dulwich.porcelain.html