Відповіді:
git describeКоманда є хорошим способом створення людини-презентабельно «номер версії» коду. З прикладів у документації:
З чимось на зразок поточного дерева git.git, я отримую:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721тобто поточний керівник моєї "батьківської" гілки базується на v1.0.4, але оскільки у неї є кілька комірок поверх цього, опис додав кількість додаткових комітів ("14") та скорочене ім'я об'єкта для комітів себе ("2414721") наприкінці.
Зсередини Python ви можете зробити щось на кшталт наступного:
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --alwaysповернеться до останнього комітету, якщо не знайдено тегів
git describeзазвичай потрібен принаймні один тег. Якщо у вас немає тегів, скористайтеся --alwaysопцією. Додаткову інформацію див. У документації з опису git .
Не потрібно зловживати отриманням даних з gitкоманди самостійно. GitPython - це дуже приємний спосіб зробити це та багато іншогоgit . Навіть має підтримку Windows.
Після pip install gitpythonтого, як ви можете зробити
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython. Ви не можете розраховувати на встановлення кінцевим користувачем gitpythonі вимагати від нього встановити його до того, як ваш код зробить його не портативним. Якщо ви не збираєтеся включати протоколи автоматичної установки, тоді вже це не є чистим рішенням.
pip/ requirements.txt) на всіх платформах. Що не "чисто"?
import numpy as npце можна вважати протягом усього потокового потоку, але встановлення gitpython виходить за рамки "чистого" та "портативного". Я думаю, що це, безумовно, найкраще рішення, тому що воно не винаходить колесо, приховує негарну реалізацію і не обходить хакерську відповідь git з підпроцесу.
pipможливістю легкої установки pip. У цих сучасних сценаріях pipрішення настільки ж портативне, як і рішення «стандартної бібліотеки».
Цей пост містить команду, відповідь Грега містить команду підпроцесу.
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'])
.decode('ascii').strip()для декодування двійкового рядка (та усуньте розрив рядка).
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
envдиктату необхідна для функціонування між платформ. Відповідь Юджі не відповідає, але, можливо, це працює і в UNIX, і в Windows.
.decode('ascii')працює - інакше кодування невідомо.
Якщо підпроцес не є портативним і ви не хочете встановлювати пакет, щоб зробити щось таке просте, ви також можете це зробити.
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()
Я тестував це лише на своїх репостах, але, здається, він працює досить сумлінно.
Ось більш повна версія відповіді Грега :
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
Або, якщо скрипт викликається з-за меж repo:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir, то cwd=аргумент може бути використаний в check_outputтимчасові зміни в робочому каталозі перед виконанням.
Якщо у вас з якихось причин немає git, але у вас є git repo (папка .git знайдена), ви можете отримати хеш фіксації з .git / fetch / heads / [гілка]
Наприклад, я використовував наступний швидкий і брудний фрагмент Python у корені сховища, щоб отримати ідентифікатор фіксації:
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]
git rev-parse HEADкомандного рядка. Синтаксис виводу повинен бути очевидним.