我想在Python脚本的输出中包含当前的git散列(作为生成该输出的代码的版本号)。
如何在我的Python脚本中访问当前的git哈希?
我想在Python脚本的输出中包含当前的git散列(作为生成该输出的代码的版本号)。
如何在我的Python脚本中访问当前的git哈希?
当前回答
如果你像我一样:
多平台,所以子进程可能有一天崩溃 使用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”,我需要它作为参数传递文件路径。
希望它能对你们中的一些人有所帮助;)
其他回答
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
如果你想要比哈希多一点的数据,你可以使用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
如果您由于某些原因没有可用的Git,但您有Git repo(。),你可以从. Git /fetch/heads/[branch]中获取提交哈希。
例如,我在存储库根运行了下面的Python代码片段来获得提交id:
git_head = '.git\\HEAD'
# Open .git\HEAD file:
with open(git_head, 'r') as git_head_file:
# Contains e.g. ref: ref/heads/master if on "master"
git_head_data = str(git_head_file.read())
# Open the correct file in .git\ref\heads\[branch]
git_head_ref = '.git\\%s' % git_head_data.split(' ')[1].replace('/', '\\').strip()
# Get the commit hash ([:7] used to get "--short")
with open(git_head_ref, 'r') as git_head_ref_file:
commit_id = git_head_ref_file.read().strip()[:7]
本文包含该命令,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”,我需要它作为参数传递文件路径。
希望它能对你们中的一些人有所帮助;)