it's all in the documentation:

repo = Repo.clone_from(cloneUrl, localRepopath)
remote = repo.create_remote(remote_name, url=another_url)
remote.push(refspec='{}:{}'.format(local_branch, remote_branch))

see also the push reference API. You can avoid the refspec setting if you set a tracking branch for the remote you want to push to.

Answer from zmo on Stack Overflow
🌐
AskPython
askpython.com › home › how to use gitpython to pull remote repository?
How To Use GitPython To Pull Remote Repository? - AskPython
June 30, 2023 - Push: In GitPython, you can push your local changes to the remote repository using the push() method.
🌐
Medium
zchelseal.medium.com › automate-your-git-workflow-with-gitpython-3320e833c4e2
Automate Your Git Workflow with GitPython | by Chelsea Liu | Medium
April 13, 2021 - Don’t forget to import git at the top of your script (sidenote: if you’ve also wondered why the package names (GitPython) are sometimes different from their import counterparts (git), here are some insights from wonderful internet people). Grab your repo with the latest meta-data from origin: repo = git.Repo(path_to_your_repo) # ex. "/User/some_user/some_dir" origin = repo.remote("origin") assert origin.exists() origin.fetch()
Top answer
1 of 4
3

I'm using gitpython==2.1.11 with Python 3.7. Below is my push function in which I first try a high-level push, and then a low-level push as necessary. Note how I check the return value of either command. I also log the push actions, and this explains what's happening at every step.

class GitCommandError(Exception):
    pass

class Git:
    def _commit_and_push_repo(self) -> None:
        repo = self._repo
        remote = repo.remote()
        remote_name = remote.name
        branch_name = repo.active_branch.name

        # Note: repo.index.entries was observed to also include unpushed files in addition to uncommitted files.
        log.debug('Committing repository index in active branch "%s".', branch_name)
        self._repo.index.commit('')
        log.info('Committed repository index in active branch "%s".', branch_name)

        def _is_pushed(push_info: git.remote.PushInfo) -> bool:
            valid_flags = {push_info.FAST_FORWARD, push_info.NEW_HEAD}  # UP_TO_DATE flag is intentionally skipped.
            return push_info.flags in valid_flags  # This check can require the use of & instead.

        push_desc = f'active branch "{branch_name}" to repository remote "{remote_name}"'
        log.debug('Pushing %s.', push_desc)
        try:
            push_info = remote.push()[0]
        except git.exc.GitCommandError:  # Could be due to no upstream branch.
            log.warning('Failed to push %s. This could be due to no matching upstream branch.', push_desc)
            log.info('Reattempting to push %s using a lower-level command which also sets upstream branch.', push_desc)
            push_output = repo.git.push('--set-upstream', remote_name, branch_name)
            log.info('Push output was: %s', push_output)
            expected_msg = f"Branch '{branch_name}' set up to track remote branch '{branch_name}' from '{remote_name}'."
            if push_output != expected_msg:
                raise RepoPushError(f'Failed to push {push_desc}.')
        else:
            is_pushed = _is_pushed(push_info)
            logger = log.debug if is_pushed else log.warning
            logger('Push flags were %s and message was "%s".', push_info.flags, push_info.summary.strip())
            if not is_pushed:
                log.warning('Failed first attempt at pushing %s. A pull will be performed.', push_desc)
                self._pull_repo()
                log.info('Reattempting to push %s.', push_desc)
                push_info = remote.push()[0]
                is_pushed = _is_pushed(push_info)
                logger = log.debug if is_pushed else log.error
                logger('Push flags were %s and message was "%s".', push_info.flags, push_info.summary.strip())
                if not is_pushed:
                    raise RepoPushError(f'Failed to push {push_desc} despite a pull.')
        log.info('Pushed %s.', push_desc)
2 of 4
1

You have to define a remote repo, then push to it. e.g.

origin = repo.remote(name='origin')
origin.push()

See the Handling Remotes documentation for more examples of push/pull

🌐
Readthedocs
gitpython.readthedocs.io › en › 0.3.2 › tutorial.html
GitPython Tutorial — GitPython 0.3.2 documentation
Remotes are used as alias for a foreign repository to ease pushing to and fetching from them:
🌐
Readthedocs
gitpython.readthedocs.io › en › stable › tutorial.html
GitPython Tutorial — GitPython 3.1.46 documentation
Remotes are used as alias for a foreign repository to ease pushing to and fetching from them
🌐
GitHub
github.com › gitpython-developers › GitPython › issues › 567
Push a commit to a named branch · Issue #567 · gitpython-developers/GitPython
I've been reading through the documentation, and I'm probably missing something, but my question is how would I achieve the following through this library? I'm trying to do the equivalent of this: git push origin master:some-remote-branch
Find elsewhere
🌐
LinuxConfig
linuxconfig.org › home › how to manage git repositories with python
Manage Git Repositories with Python: GitPython Guide
May 27, 2022 - We created our first commit with GitPython, now we want to push the commit to the remote we added in the first step of this tutorial. Performing such actions is really easy. First of all we must say that all the remotes associate to our repository can be accessed via the remotes method of the Repo class: ... As we know, each remote is represented by a Remote object. In our example we want to push our commit to the remote we called “origin”, so all we have to do is to call the push method on it:
🌐
Readthedocs
gitpython.readthedocs.io › en › stable › reference.html
API Reference — GitPython 3.1.46 documentation
It will only be written into the configuration if it not None, which is when the checked out branch will be the one the remote HEAD pointed to. The result you get in these situation is somewhat fuzzy, and it is recommended to specify at least master here. Examples are master or feature/new.
🌐
GitHub
github.com › gitpython-developers › GitPython › issues › 334
Is there a way to force a git push? · Issue #334 · gitpython-developers/GitPython
August 5, 2015 - Hi guys, I'm using GitPython to commit and push some changes in my Python application. However, sometimes my developers and I want to force push the commit (git push --force) instead of sometim...
Author   g12mcgov
🌐
Python Developer's Guide
devguide.python.org › gitbootcamp
Git bootcamp and cheat sheet
You should have been redirected · If not, click here to continue
🌐
Grimoire
grimoire.carcano.ch › the grimoire of a modern linux professional › blog › dev-ops tools › scripting › git with python howto gitpython tutorial and pygit2 tutorial
Git With Python HowTo GitPython Tutorial And PyGit2 Tutorial
November 14, 2024 - Git With Python HowTo GitPython Tutorial And PyGit2 Tutorial with also real life use case showing cloning, committing and pushing using HTTP or SSH transport
🌐
GitHub
github.com › gitpython-developers › GitPython › issues › 471
Create a new branch and push to remote? · Issue #471 · gitpython-developers/GitPython
June 13, 2016 - Hi, i really tried reading all over the docs, and tutorial but for some reason i can't find it. given repo - how can i create a new local branch and push it to remote? i must say even i really like the API i think a simple demonstration ...
Author   itielshwartz
🌐
GitHub
github.com › gitpython-developers › GitPython › blob › master › git › remote.py
GitPython/git/remote.py at master · gitpython-developers/GitPython
To make things more complicated, it can be possible for the list to include · other kinds of references, for example, tag references, if these are stale · as well. This is a fix for the issue described here: https://github.com/gitpython-developers/GitPython/issues/260 · """ out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name) for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]: # expecting ·
Author   gitpython-developers
🌐
GeeksforGeeks
geeksforgeeks.org › python › automating-some-git-commands-with-python
Automating some git commands with Python - GeeksforGeeks
April 28, 2025 - import git repo = git.Repo("/h....commit('Initial commit on new branch') print('Commited successfully') origin.push() print('Pushed changes to origin')...
🌐
Readthedocs
gitpython.readthedocs.io › en › 3.1.26 › tutorial.html
GitPython Tutorial — GitPython 3.1.26 documentation
Remotes are used as alias for a foreign repository to ease pushing to and fetching from them
Top answer
1 of 3
14

I've done something like creating a txt in a remote branch from newly created branch and commit, push to remote. Here's my code

import git
import datetime
import os
from time import *
from os import path
from git import Repo

def commit_files():
    if repo != None:
        new_branch = 'your_new_branch'
        current = repo.create_head(new_branch)
        current.checkout()
        master = self.repo.heads.master
        repo.git.pull('origin', master)
        #creating file
        dtime = strftime('%d-%m-%Y %H:%M:%S', localtime())
        with open(self.local_repo_path + path.sep + 'lastCommit' + '.txt', 'w') as f:
            f.write(str(dtime))
        if not path.exists(self.local_repo_path):
            os.makedirs(self.local_repo_path)
        print('file created---------------------')

        if repo.index.diff(None) or repo.untracked_files:

            repo.git.add(A=True)
            repo.git.commit(m='msg')
            repo.git.push('--set-upstream', 'origin', current)
            print('git push')
        else:
            print('no changes')
2 of 3
1

This was exactly my use case, with the added requirement that I needed to switch back to original branch afterwards. I did it using this:

def switch_commit_branch(branch_name, msg='Automatic commit by switch_commit_branch', force=True):
    '''
    This function 
        (1) switches to branch `branch_name` (and creates it if it doesnt aready exist)
        (2) ads and commits all changes
        (3) pushes to origin
    :param branch_name: desired branch name
    :param msg: commit message
    :param force: whether to create branch if it doesnt already exist 
    :return: 
    '''
    repo = Repo(search_parent_directories=True)
    original_branch = repo.active_branch
    branch = [b for b in repo.branches if b.name == branch_name]
    if len(branch) == 0:
        if force:
            print(f'Creating new branch {branch_name}')
            branch = repo.create_head(branch_name)  # create new branch if none exists
        else:
            print(f'Branch {branch_name} does not exist. Set `force=True` to create. Aborting')
            return None
    else:
        branch = branch[0]

    branch.checkout()
    repo.git.add('*')
    repo.git.commit(m=msg)
    repo.git.push('--set-upstream', 'origin', branch)
    original_branch.checkout()