我想在Python脚本的输出中包含当前的git散列(作为生成该输出的代码的版本号)。

如何在我的Python脚本中访问当前的git哈希?


当前回答

我遇到了类似于OP的问题,但在我的情况下,我将源代码作为zip文件交付给我的客户端,尽管我知道他们将安装python,但我不能假设他们将安装git。因为OP没有指定他的操作系统,如果他安装了git,我想我可以在这里贡献一下。

为了只获得提交的散列,Naelson Douglas的答案是完美的,但为了获得标记名称,我使用了dulwich python包。这是一个用python简化的git客户端。

在使用pip install dulwich——global-option="——pure"安装包后,可以这样做:

from dulwich import porcelain

def get_git_revision(base_path):
    return porcelain.describe(base_path)

r = get_git_revision("PATH OF YOUR REPOSITORY's ROOT FOLDER")
print(r)

我刚刚在这里的一个存储库中运行了这段代码,它显示了输出v0.1.2-1-gfb41223,类似于git describe返回的结果,这意味着我在标记v0.1.2之后提交了一次,提交的7位哈希值是fb41223。

它有一些限制:目前它没有显示存储库是否脏的选项,它总是显示7位哈希,但不需要安装git,所以可以选择折衷。

编辑:如果pip install命令由于选项——pure(问题在这里解释)而出现错误,请从两个可能的解决方案中选择一个:

首先安装Dulwich包的依赖项: PIP install urllib3 certificate && PIP install Dulwich——global-option="——pure" 安装时没有选择pure: pip Install dulwich。这将在您的系统中安装一些平台相关的文件,但它将提高包的性能。

其他回答

Numpy在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

这是对富田裕治‘富田’的改进回答。

import subprocess

def get_git_revision_hash():
    full_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
    full_hash = str(full_hash, "utf-8").strip()
    return full_hash

def get_git_revision_short_hash():
    short_hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
    short_hash = str(short_hash, "utf-8").strip()
    return short_hash

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

我遇到了类似于OP的问题,但在我的情况下,我将源代码作为zip文件交付给我的客户端,尽管我知道他们将安装python,但我不能假设他们将安装git。因为OP没有指定他的操作系统,如果他安装了git,我想我可以在这里贡献一下。

为了只获得提交的散列,Naelson Douglas的答案是完美的,但为了获得标记名称,我使用了dulwich python包。这是一个用python简化的git客户端。

在使用pip install dulwich——global-option="——pure"安装包后,可以这样做:

from dulwich import porcelain

def get_git_revision(base_path):
    return porcelain.describe(base_path)

r = get_git_revision("PATH OF YOUR REPOSITORY's ROOT FOLDER")
print(r)

我刚刚在这里的一个存储库中运行了这段代码,它显示了输出v0.1.2-1-gfb41223,类似于git describe返回的结果,这意味着我在标记v0.1.2之后提交了一次,提交的7位哈希值是fb41223。

它有一些限制:目前它没有显示存储库是否脏的选项,它总是显示7位哈希,但不需要安装git,所以可以选择折衷。

编辑:如果pip install命令由于选项——pure(问题在这里解释)而出现错误,请从两个可能的解决方案中选择一个:

首先安装Dulwich包的依赖项: PIP install urllib3 certificate && PIP install Dulwich——global-option="——pure" 安装时没有选择pure: pip Install dulwich。这将在您的系统中安装一些平台相关的文件,但它将提高包的性能。

我遇到了这个问题,并通过实现这个函数解决了它。 https://gist.github.com/NaelsonDouglas/9bc3bfa26deec7827cb87816cad88d59

from pathlib import Path

def get_commit(repo_path):
    git_folder = Path(repo_path,'.git')
    head_name = Path(git_folder, 'HEAD').read_text().split('\n')[0].split(' ')[-1]
    head_ref = Path(git_folder,head_name)
    commit = head_ref.read_text().replace('\n','')
    return commit


r = get_commit('PATH OF YOUR CLONED REPOSITORY')
print(r)

如果subprocess是不可移植的,并且你不想安装一个包来做这么简单的事情,你也可以这样做。

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

我只测试了这个在我的回购,但它似乎工作相当稳定。