How to push local files to github using python? (or post a commit via Python)
Asked Answered
C

2

11

What options are there for commiting and pushing files to github from python?

Here are three methods I thought should be feasible so attempted in order:

  1. Use pygithub: (Github's python API) to send push requests to my repository. Failed because I can find no push functions in the API. I can see edit files, but that doesn't help when I plan on replacing the file often.

  2. Use git push in command line from a python subprocess (HTTPS): This almost works, but I cannot figure out how to fill in the user and password fields required. Attempt:

    import subprocess
    from pexpect import popen_spawn
    
    
    user = 'GithubUsername'
    password = '***********'
    
    cmd = "cd C:\\Users\Dropbox\git-test"
    returned_value = subprocess.call(cmd, shell=True)  # returns the exit code in unix
    
    cmd = "git add ." 
    subprocess.call(cmd, shell=True)
    
    cmd = 'git commit -m "python project update"'
    subprocess.call(cmd, shell=True)
    
    cmd = "git remote set-url origin https://github.com/Tehsurfer/git-test.git"
    subprocess.call(cmd, shell=True)
    
    cmd = "git push "
    child_process = popen_spawn.PopenSpawn(cmd)
    child_process.expect('User')
    child_process.sendline(user)
    child_process.expect('Password')
    child_process.sendline(password)
    print('returned value:', returned_value)
    
    print('end of commands')`
    
  3. Use git push in command line from a python subprocess (SSH): The problem I had here is that I cannot find a way to create a ssh agent in the windows command prompt. I have been able to create one in the MINGW64 terminal easily enough via this tutorial , but have no way of interacting with it via Python.

Casaubon answered 28/4, 2018 at 0:59 Comment(6)
So what is your question exactly?Meetly
Github doesn't have an API called "push", but it does have APIs to post a commit. Since that's committing to your Github repo, not to a local clone or anything, that's exactly what you want. Using it is not as trivial as it should be, but now that you know what it's called, you should be able to search for it. (Try including "push" in the search, because most of the blog posts about it, someone started off looking for "an easier way to push"…)Rhetorical
@brendanAbel Sorry will update the title to be a bit more specific nowCasaubon
@Rhetorical Thank you I did not actually realise that posting a commit was the same as pushing for my purposes. I will research this now and hopefully answer the question.Casaubon
Yeah, it's one of those things that's kind of obvious one you think about it enough, but not at all obvious until you do. But then everything that has anything to do with git is that way. :)Rhetorical
You might like how this https://mcmap.net/q/1016918/-function-that-would-push-add-commit-a-database-file-to-github-using-python-3 was solved and see if it can help you too.Karole
C
15

How do I push new files to GitHub?

A very similar question who's code I was able to modify to make multiple file pushes to github via python:

import base64
from github import Github
from github import InputGitTreeElement

user = "GithubUsername"
password = "*********"
g = Github(user,password)
repo = g.get_user().get_repo('git-test') # repo name
file_list = [
    'C:\\Users\jesse\Dropbox\Swell-Forecast\git-test\index.html',
    'C:\\Users\jesse\Dropbox\Swell-Forecast\git-test\margin_table.html'
]
file_names = [
    'index.html',
    'margin_table.html'
]
commit_message = 'python commit'
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 i, entry in enumerate(file_list):
    with open(entry) as input_file:
        data = input_file.read()
    if entry.endswith('.png'): # images must be encoded
        data = base64.b64encode(data)
    element = InputGitTreeElement(file_names[i], '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)
Casaubon answered 28/4, 2018 at 1:54 Comment(4)
This is a wonderful explanation, thanks for writing this out. I wanted to ask why in the InputGitTreeElement section, '100644' and 'blob' were used as the inputs. Thanks for any help.Perfectible
As a guess, I would say they are Unix file permissions . The pygithub documentation isn't that comprehensive and I don't have much knowledge on the topic so it's hard for me to figure out much more than that.Casaubon
Is there a way to do a commit WITHOUT supplying the file_list? i.e. have github workout which files need committing.Soundboard
@Soundboard I'm sure you could check which files have been changed and only commit those. Try this answer: Get changed files using gitpythonCasaubon
L
0

you can also use repository contents API to push to github.

original answer coming from similar thread.

Lanctot answered 17/1, 2024 at 10:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.