답변:
이 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 describe 설명서 를 참조하십시오.
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
솔루션은 "표준 라이브러리"솔루션만큼 이식성이 뛰어납니다.
이 게시물 에는 명령 이 포함되어 있으며 Greg의 답변 에는 하위 프로세스 명령이 포함되어 있습니다.
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
크로스 플랫폼 기능에 dict 설정 이 필요 하다고 가정했습니다 . Yuji의 대답은 그렇지 않지만 아마도 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()
나는 이것을 repos에서만 테스트했지만 꽤 일관되게 작동하는 것 같습니다.
다음은 Greg의 답변에 대한 완전한 버전입니다 .
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
또는 리포지토리 외부에서 스크립트를 호출하는 경우 :
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 / [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]
git rev-parse HEAD
명령 행에서 시작하십시오 . 출력 구문은 분명해야합니다.