The Python Oracle

Get the current git hash in a Python script

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Civilization

--

Chapters
00:00 Get The Current Git Hash In A Python Script
00:18 Accepted Answer Score 128
00:59 Answer 2 Score 201
01:24 Answer 3 Score 323
02:22 Answer 4 Score 19
02:43 Thank you

--

Full question
https://stackoverflow.com/questions/1498...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #git #githash

#avk47



ANSWER 1

Score 323


No need to hack around getting data from the git command yourself. GitPython is a very nice way to do this and a lot of other git stuff. It even has "best effort" support for Windows.

After pip install gitpython you can do

import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha

Something to consider when using this library. The following is taken from gitpython.readthedocs.io

Leakage of System Resources

GitPython is not suited for long-running processes (like daemons) as it tends to leak system resources. It was written in a time where destructors (as implemented in the __del__ method) still ran deterministically.

In case you still want to use it in such a context, you will want to search the codebase for __del__ implementations and call these yourself when you see fit.

Another way assure proper cleanup of resources is to factor out GitPython into a separate process which can be dropped periodically




ANSWER 2

Score 201


This post contains the command, Greg's answer contains the subprocess command.

import subprocess

def get_git_revision_hash() -> str:
    return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode('ascii').strip()

def get_git_revision_short_hash() -> str:
    return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).decode('ascii').strip()

when running

print(get_git_revision_hash())
print(get_git_revision_short_hash())

you get output:

fd1cd173fc834f62fa7db3034efc5b8e0f3b43fe
fd1cd17



ACCEPTED ANSWER

Score 128


The git describe command is a good way of creating a human-presentable "version number" of the code. From the examples in the documentation:

With something like git.git current tree, I get:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

i.e. the current head of my "parent" branch is based on v1.0.4, but since it has a few commits on top of that, describe has added the number of additional commits ("14") and an abbreviated object name for the commit itself ("2414721") at the end.

From within Python, you can do something like the following:

import subprocess
label = subprocess.check_output(["git", "describe"]).strip()



ANSWER 4

Score 19


If subprocess isn't portable and you don't want to install a package to do something this simple you can also do this.

import pathlib

def get_git_revision(base_path):
    git_dir = pathlib.Path(base_path) / '.git'
    with (git_dir / 'HEAD').open('r') as head:
        ref = head.readline().split(' ')[-1].strip()

    with (git_dir / ref).open('r') as git_hash:
        return git_hash.readline().strip()

I've only tested this on my repos but it seems to work pretty consistantly.