Відповіді:
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
командного рядка. Синтаксис виводу повинен бути очевидним.