Odpowiedzi:
git describe
Polecenia jest dobrym sposobem na stworzenie „numeru wersji” człowieka-reprezentacyjny kodu. Z przykładów w dokumentacji:
W przypadku aktualnego drzewa git.git otrzymuję:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
tzn. obecna nagłówek mojej gałęzi "macierzystej" jest oparta na wersji 1.0.4, ale ponieważ ma kilka zatwierdzeń, opis dodał liczbę dodatkowych zatwierdzeń ("14") i skróconą nazwę obiektu dla zatwierdzenia („2414721”) na końcu.
Z poziomu Pythona możesz wykonać następujące czynności:
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --always
powróci do ostatniego zatwierdzenia, jeśli nie zostaną znalezione żadne tagi
git describe
zwykle wymaga co najmniej jednego tagu. Jeśli nie masz żadnych tagów, użyj --always
opcji. Zobacz dokumentację opisującą git, aby uzyskać więcej informacji.
Nie ma potrzeby samodzielnego pobierania danych z git
polecenia. GitPython to bardzo fajny sposób na zrobienie tego i wielu innych git
rzeczy. Obsługuje nawet system Windows „do najlepszych starań”.
Po tym, jak pip install gitpython
możesz to zrobić
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython
. Nie możesz polegać na gitpython
zainstalowaniu przez użytkownika końcowego i wymaganie od niego zainstalowania go, zanim kod zacznie działać, sprawia, że nie jest on przenośny. Chyba że zamierzasz dołączyć protokoły automatycznej instalacji, w którym to momencie nie jest to już czyste rozwiązanie.
pip
/ requirements.txt
) na wszystkich platformach. Co nie jest „czyste”?
import numpy as np
można założyć, że w całym stosie przepełnienia stosu, ale instalacja gitpythona wykracza poza „czysty” i „przenośny”. Myślę, że jest to zdecydowanie najlepsze rozwiązanie, ponieważ nie wymyśla koła na nowo, ukrywa brzydką implementację i nie hakuje odpowiedzi gita z podprocesu.
pip
możliwością łatwej instalacji pip
. W tych nowoczesnych scenariuszach pip
rozwiązanie jest tak samo przenośne, jak rozwiązanie „biblioteki standardowej”.
Ten post zawiera polecenie, odpowiedź Grega zawiera polecenie podprocesu.
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()
aby zdekodować ciąg binarny (i usuń podział wiersza).
numpy
ma ładnie wyglądającą wieloplatformową procedurę w swoim 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
dyktu jest konieczne dla funkcjonalności międzyplatformowej. Odpowiedź Yuji nie działa, ale być może to działa zarówno w systemie UNIX, jak i Windows.
.decode('ascii')
- w przeciwnym razie kodowanie jest nieznane.
Jeśli podproces nie jest przenośny i nie chcesz instalować pakietu, aby zrobić coś tak prostego, możesz również to zrobić.
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()
Testowałem to tylko na moich repozytoriach, ale wydaje się, że działa dość konsekwentnie.
Oto pełniejsza wersja odpowiedzi Grega :
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
Lub, jeśli skrypt jest wywoływany spoza repozytorium:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir
The cwd=
Arg może być stosowany w check_output
zmian tymczasowych katalogu roboczego przed wykonaniem.
Jeśli z jakiegoś powodu nie masz dostępnego gita, ale masz repozytorium git (znaleziono folder .git), możesz pobrać skrót zatwierdzenia z .git / fetch / heads / [branch]
Na przykład użyłem następującego szybkiego i nieczytelnego fragmentu kodu Pythona uruchomionego w katalogu głównym repozytorium, aby uzyskać identyfikator zatwierdzenia:
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
od z wiersza poleceń. Składnia wyjściowa powinna być oczywista.