web-dev-qa-db-fra.com

Récupère le hash actuel de git dans un script Python

Je voudrais inclure le hachage git actuel dans la sortie d'un script Python (en tant que numéro de version du code qui a généré cette sortie).

Comment puis-je accéder au hachage git actuel dans mon script Python?

126
Victor

Le git describe La commande est un bon moyen de créer un "numéro de version" du code pouvant être présenté par l'homme. Parmi les exemples de la documentation:

Avec quelque chose comme l'arbre actuel de git.git, je reçois:

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

c'est-à-dire que la tête actuelle de ma branche "parent" est basée sur la v1.0.4, mais comme elle comporte quelques commits, elle a ajouté le nombre de commits supplémentaires ("14") et un nom d'objet abrégé pour la validation. lui-même ("2414721") à la fin.

À partir de Python, vous pouvez effectuer les opérations suivantes:

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

Inutile de chercher des données dans la commande git. GitPython est une très bonne manière de faire ceci et beaucoup d’autres choses git. Il prend même en charge "au mieux" Windows.

Après pip install gitpython tu peux faire

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

Ce post contient la commande, La réponse de Greg contient la commande de sous-processus.

import subprocess

def get_git_revision_hash():
    return subprocess.check_output(['git', 'rev-parse', 'HEAD'])

def get_git_revision_short_hash():
    return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
84
Yuji 'Tomita' Tomita

numpy a un joli look routine multiplateforme dans son setup.py:

import os
import subprocess

# Return the git revision as a string
def git_version():
    def _minimal_ext_cmd(cmd):
        # construct minimal environment
        env = {}
        for k in ['SYSTEMROOT', 'PATH']:
            v = os.environ.get(k)
            if v is not None:
                env[k] = v
        # LANGUAGE is used on win32
        env['LANGUAGE'] = 'C'
        env['LANG'] = 'C'
        env['LC_ALL'] = 'C'
        out = subprocess.Popen(cmd, stdout = subprocess.PIPE, env=env).communicate()[0]
        return out

    try:
        out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
        GIT_REVISION = out.strip().decode('ascii')
    except OSError:
        GIT_REVISION = "Unknown"

    return GIT_REVISION
9
ryanjdillon

Si le sous-processus n'est pas portable et que vous ne voulez pas installer de paquet pour faire quelque chose d'aussi simple, vous pouvez également le faire.

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()

Je n'ai testé cela que sur mon dépôt mais cela semble fonctionner assez régulièrement.

2
kagronick

Voici une version plus complète de réponse de Greg :

import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())

Ou, si le script est appelé de l'extérieur du référentiel:

import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
0
AndyP