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 Overflowit'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.
It should work like this
r = Repo.clone_from(cloneUrl, localRepoPath)
r.remotes.origin.push()
provided that a tracking branch was setup already.
Otherwise you would set a refspec:
r.remotes.origin.push(refspec='master:master')
Videos
Following is the code to git add, git commit and then git push using GitPython.
Install GitPython using pip install gitpython.
from git import Repo
PATH_OF_GIT_REPO = r'path\to\your\project\folder\.git' # make sure .git folder is properly configured
COMMIT_MESSAGE = 'comment from python script'
def git_push():
try:
repo = Repo(PATH_OF_GIT_REPO)
repo.git.add(update=True)
repo.index.commit(COMMIT_MESSAGE)
origin = repo.remote(name='origin')
origin.push()
except:
print('Some error occured while pushing the code')
git_push()
You can try the following. It may have your problem solved...
repo.git.pull('origin', new_branch)
repo.git.push('origin', new_branch)
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)
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
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')
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()
I managed this by getting the repo name directly:
repo = git.Repo('repo_path')
o = repo.remotes.origin
o.pull()
As the accepted answer says it's possible to use repo.remotes.origin.pull(), but the drawback is that it hides the real error messages into it's own generic errors. For example when DNS resolution doesn't work, then repo.remotes.origin.pull() shows the following error message:
git.exc.GitCommandError: 'Error when fetching: fatal: Could not read from remote repository.
' returned with exit code 2
On the other hand using git commands with GitPython like repo.git.pull() shows the real error:
git.exc.GitCommandError: 'git pull' returned with exit code 1
stderr: 'ssh: Could not resolve hostname github.com: Name or service not known
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.'