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

17,608

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)
Share:
17,608
Jesse Reza Khorasanee
Author by

Jesse Reza Khorasanee

studying Engineering Science at the University of Auckland

Updated on July 24, 2022

Comments

  • Jesse Reza Khorasanee
    Jesse Reza Khorasanee almost 2 years

    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.

  • FrankMank1
    FrankMank1 almost 4 years
    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.
  • Jesse Reza Khorasanee
    Jesse Reza Khorasanee almost 4 years
    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.
  • ManInMoon
    ManInMoon about 3 years
    Is there a way to do a commit WITHOUT supplying the file_list? i.e. have github workout which files need committing.
  • Jesse Reza Khorasanee
    Jesse Reza Khorasanee about 3 years
    @ManInMoon I'm sure you could check which files have been changed and only commit those. Try this answer: Get changed files using gitpython