31

I have been asked to write a script that pulls the latest code from Git, makes a build, and performs some automated unit tests.

I found that there are two built-in Python modules for interacting with Git that are readily available: GitPython and libgit2.

What approach/module should I use?

c32hedge
  • 785
  • 10
  • 19
user596922
  • 1,501
  • 3
  • 18
  • 27

7 Answers7

50

An easier solution would be to use the Python subprocess module to call git. In your case, this would pull the latest code and build:

import subprocess
subprocess.call(["git", "pull"])
subprocess.call(["make"])
subprocess.call(["make", "test"])

Docs:

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
Ian Wetherbee
  • 6,009
  • 1
  • 29
  • 30
  • 3
    With Python 3.5 and later, the .call() method [has been deprecated](https://stackoverflow.com/questions/40697583/whats-the-difference-between-pythons-subprocess-call-and-subprocess-run). You can now use : `import subprocess` `subprocess.run(["git", "pull"])` etc. – Bart Jonk Sep 30 '21 at 11:07
25

I agree with Ian Wetherbee. You should use subprocess to call git directly. If you need to perform some logic on the output of the commands then you would use the following subprocess call format.

import subprocess
PIPE = subprocess.PIPE
branch = 'my_branch'

process = subprocess.Popen(['git', 'pull', branch], stdout=PIPE, stderr=PIPE)
stdoutput, stderroutput = process.communicate()

if 'fatal' in stdoutput:
    # Handle error case
else:
    # Success!
aychedee
  • 24,871
  • 8
  • 79
  • 83
  • Why is this better than GitPython? Does GitPython simply do this under the hood? If so, why re-invent it? – John May 06 '22 at 04:50
  • 2
    Actually I've just read that there is leakage of system resources with GitPython (https://gitpython.readthedocs.io/en/stable/intro.html#limitations). So that is enough for me to stay away from it! – John May 06 '22 at 04:56
  • 1
    Also, I wrote this answer in 2012. 10 years ago. So new pieces of software have been written since then. If there's a new, awesome, way to do it then add it as an answer to this question. – aychedee Jun 16 '22 at 17:32
24

So with Python 3.5 and later, the .call() method has been deprecated.

https://docs.python.org/3.6/library/subprocess.html#older-high-level-api

The current recommended method is to use the .run() method on subprocess.

import subprocess
subprocess.run(["git", "pull"])
subprocess.run(["make"])
subprocess.run(["make", "test"])

Adding this as when I went to read the docs, the links above contradicted the accepted answer and I had to do some research. Adding my 2 cents to hopefully save someone else a bit of time.

Joe Jacobs
  • 291
  • 3
  • 9
2

In EasyBuild, we rely on GitPython, and that's working out fine.

See here, for examples of how to use it.

bd808
  • 1,781
  • 1
  • 22
  • 31
Kenneth Hoste
  • 2,816
  • 20
  • 14
2

If GitPython package doesn't work for you there are also the PyGit and Dulwich packages. These can be easily installed through pip.

But, I have personally just used the subprocess calls. Works perfect for what I needed, which was just basic git calls. For something more advanced, I'd recommend a git package.

Trishayyyy
  • 31
  • 2
0

I had to use shlex on top of the run call because my command was too complex for the subprocess alone to understand.

import subprocess
import shlex
git_command = "git <command>"
subprocess.run(shlex.split(git_command))
-8

If you're on Linux or Mac, why use python at all for this task? Write a shell script.

#!/bin/sh
set -e
git pull
make
./your_test #change this line to actually launch the thing that does your test