How can I call 'git pull' from within Python?

Using the github webhooks, I would like to be able to pull any changes to a remote development server. At the moment, when in the appropriate directory, git pull gets any changes that need to be made. However, I can’t figure out how to call that function from within Python. I have tried the following:

import subprocess
process = subprocess.Popen("git pull", stdout=subprocess.PIPE)
output = process.communicate()[0]

But this results in the following error

  • Git plumbing - find out if there are any unstaged files in a directory quickly
  • Is there a 'git sed' or equivalent?
  • How to add existing ssh key to project's deploy key in gitlab
  • Specify private SSH-key to use when executing shell command with or without Ruby?
  • Git Bash cannot find git directory when git is installed
  • Getting TravisCI to commit and push a modified file with Tags (releases)
  • Traceback (most recent call last): File “”, line 1, in
    File “/usr/lib/python2.7/subprocess.py”, line 679, in
    init
    errread, errwrite) File “/usr/lib/python2.7/subprocess.py”, line 1249, in _execute_child
    raise child_exception OSError: [Errno 2] No such file or directory

    Is there a way that I can call this bash command from within Python?

  • Change configuration on azure website when using GIT to deploy
  • git merge against an arbitrary base revision (git-svn)
  • How to clone source code of Android marshallow
  • Git - Move the contents of a file into another directory
  • How to use git for managing several projects?
  • Why in Windows might attempting to delete a file twice work?
  • 4 Solutions collect form web for “How can I call 'git pull' from within Python?”

    Have you considered using GitPython? It’s designed to handle all this nonsense for you.

    import git 
    
    g = git.cmd.Git(git_dir)
    g.pull()
    

    https://github.com/gitpython-developers/GitPython

    subprocess.Popen expects a list of the program name and arguments. You’re passing it a single string, which is (with the default shell=False) equivalent to:

    ['git pull']
    

    That means that subprocess tries to find a program named literally git pull, and fails to do so: In Python 3.3, your code raises the exception FileNotFoundError: [Errno 2] No such file or directory: 'git pull'. Instead, pass in a list, like this:

    import subprocess
    process = subprocess.Popen(["git", "pull"], stdout=subprocess.PIPE)
    output = process.communicate()[0]
    

    By the way, in Python 2.7+, you can simplify this code with the check_output convenience function:

    import subprocess
    output = subprocess.check_output(["git", "pull"])
    

    Also, to use git functionality, it’s by no way necessary (albeit simple and portable) to call the git binary. Consider using git-python or Dulwich.

    This is a sample recipe, I’ve been using in one of my projects. Agreed that there are multiple ways to do this though. 🙂

    >>> import subprocess, shlex
    >>> git_cmd = 'git status'
    >>> kwargs = {}
    >>> kwargs['stdout'] = subprocess.PIPE
    >>> kwargs['stderr'] = subprocess.PIPE
    >>> proc = subprocess.Popen(shlex.split(git_cmd), **kwargs)
    >>> (stdout_str, stderr_str) = proc.communicate()
    >>> return_code = proc.wait()
    
    >>> print return_code
    0
    
    >>> print stdout_str
    # On branch dev
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #   file1
    #   file2
    nothing added to commit but untracked files present (use "git add" to track)
    
    >>> print stderr_str
    

    The problem with your code was, you were not passing an array for subprocess.Popen() and hence was trying to run a single binary called git pull. Instead it needs to execute the binary git with the first argument being pull and so on.

    Try:

    subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)
    
    Git Baby is a git and github fan, let's start git clone.