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

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


当前回答

如果你想要比哈希多一点的数据,你可以使用git-log:

import subprocess

def get_git_hash():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%H']).strip()

def get_git_short_hash():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%h']).strip()

def get_git_short_hash_and_commit_date():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%h-%ad', '--date=short']).strip()

关于格式化选项的完整列表-查看git log——help

其他回答

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

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

下面是格雷格更完整的回答:

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

或者,如果脚本从repo外部被调用:

import subprocess, os
print(subprocess.check_output(["git", "describe", "--always"], cwd=os.path.dirname(os.path.abspath(__file__))).strip().decode())

或者,如果脚本是从repo外部调用的,而你喜欢pathlib:

import subprocess
from pathlib import Path
print(subprocess.check_output(["git", "describe", "--always"], cwd=Path(__file__).resolve().parent).strip().decode())

如果你想要比哈希多一点的数据,你可以使用git-log:

import subprocess

def get_git_hash():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%H']).strip()

def get_git_short_hash():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%h']).strip()

def get_git_short_hash_and_commit_date():
    return subprocess.check_output(['git', 'log', '-n', '1', '--pretty=tformat:%h-%ad', '--date=short']).strip()

关于格式化选项的完整列表-查看git log——help

本文包含该命令,Greg的回答包含subprocess命令。

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

运行时

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

你得到输出:

fd1cd173fc834f62fa7db3034efc5b8e0f3b43fe
fd1cd17

如果你像我一样:

多平台,所以子进程可能有一天崩溃 使用Python 2.7,所以GitPython不可用 不要仅仅为了这个而使用Numpy 已经使用哨兵(旧贬值版本:乌鸦)

然后(这将不会在shell上工作,因为shell不检测当前文件路径,将BASE_DIR替换为当前文件路径):

import os
import raven

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(raven.fetch_git_sha(BASE_DIR))

就是这样。

我正在寻找另一种解决方案,因为我想迁移到sentry_sdk并离开raven,但可能有些人想继续使用raven一段时间。

下面是让我陷入stackoverflow问题的讨论

所以使用raven的代码而不使用raven也是可能的(见讨论):

from __future__ import absolute_import

import os.path

__all__ = 'fetch_git_sha'


def fetch_git_sha(path, head=None):
    """
    >>> fetch_git_sha(os.path.dirname(__file__))
    """
    if not head:
        head_path = os.path.join(path, '.git', 'HEAD')

        with open(head_path, 'r') as fp:
            head = fp.read().strip()

        if head.startswith('ref: '):
            head = head[5:]
            revision_file = os.path.join(
                path, '.git', *head.split('/')
            )
        else:
            return head
    else:
        revision_file = os.path.join(path, '.git', 'refs', 'heads', head)

    if not os.path.exists(revision_file):
        # Check for Raven .git/packed-refs' file since a `git gc` may have run
        # https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery
        packed_file = os.path.join(path, '.git', 'packed-refs')
        if os.path.exists(packed_file):
            with open(packed_file) as fh:
                for line in fh:
                    line = line.rstrip()
                    if line and line[:1] not in ('#', '^'):
                        try:
                            revision, ref = line.split(' ', 1)
                        except ValueError:
                            continue
                        if ref == head:
                            return revision

    with open(revision_file) as fh:
        return fh.read().strip()

我把这个文件命名为version .py,我导入“fetch_git_sha”,我需要它作为参数传递文件路径。

希望它能对你们中的一些人有所帮助;)