Python 스크립트에서 현재 git 해시를 가져옵니다.
Python 스크립트의 출력에 현재의 git 해시를 포함시키고 싶습니다(그 출력을 생성한 코드의 버전 번호).
Python 스크립트의 현재 git 해시에 어떻게 액세스 할 수 있습니까?
데이터 취득을 위해 해킹을 할 필요가 없습니다.git
자신을 통제하라.GitPython은 이것을 하기 위한 매우 좋은 방법이고 다른 많은 방법들도 있습니다.git
Windows 를 「최고의 노력」으로 서포트하고 있습니다.
끝나고pip install gitpython
할수있습니다
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
이 라이브러리를 사용할 때 고려해야 할 사항.다음은 gitpython.readtheadocs에서 가져온 것입니다.이오
시스템 리소스 누출
GitPython은 시스템 리소스가 누출되는 경향이 있기 때문에 (데몬과 같은) 장기 실행 프로세스에는 적합하지 않습니다.이것은 파괴자들이 (에 실장되어 있는) 시대에 쓰여졌다.
__del__
method)는 여전히 결정적으로 실행되었습니다.이러한 컨텍스트에서 계속 사용하고 싶은 경우 코드베이스에서
__del__
도입이 적절하다고 판단되면 직접 전화하십시오.리소스의 적절한 정리를 보장하는 또 다른 방법은 GitPython을 주기적으로 폐기할 수 있는 별도의 프로세스로 인수하는 것입니다.
이 게시물에는 명령어가 포함되어 있으며, Greg의 답변에는 하위 프로세스 명령이 포함되어 있습니다.
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
이 명령어는 인간이 표시할 수 있는 코드의 "버전 번호"를 작성하는 좋은 방법입니다.문서의 예에서 다음 항목을 참조하십시오.
git.git current tree를 사용하면 다음과 같이 됩니다.
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
즉, 현재 "부모" 브랜치 헤드는 v1.0.4에 기반하고 있지만, 그 위에 몇 개의 커밋이 있기 때문에 description에서는 커밋의 수('14')와 커밋 자체의 약어 오브젝트 이름('2414721')이 끝에 추가되었습니다.
Python 내에서 다음과 같은 작업을 수행할 수 있습니다.
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
다음은 Greg의 답변의 보다 완전한 버전입니다.
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
또는 스크립트를 repo 외부에서 호출하는 경우:
import subprocess, os
print(subprocess.check_output(["git", "describe", "--always"], cwd=os.path.dirname(os.path.abspath(__file__))).strip().decode())
또는 스크립트를 외부에서 호출하고 있는 경우pathlib
:
import subprocess
from pathlib import Path
print(subprocess.check_output(["git", "describe", "--always"], cwd=Path(__file__).resolve().parent).strip().decode())
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
하위 프로세스가 이식 가능하지 않고 이렇게 간단한 작업을 수행하기 위해 패키지를 설치하지 않으려면 이 작업을 수행할 수도 있습니다.
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
def get_git_revision_hash():
full_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
full_hash = str(full_hash, "utf-8").strip()
return full_hash
def get_git_revision_short_hash():
short_hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
short_hash = str(short_hash, "utf-8").strip()
return short_hash
print(get_git_revision_hash())
print(get_git_revision_short_hash())
더'해시하다'를 사용할 수 .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을 수 repoGit repo)가(Git repo(Git repo)가 있습니다..git
found), folder found에서 수 .)을 사용하다.git/fetch/heads/[branch]
.
예를 들어 commit id를 얻기 위해 저장소 루트에서 실행되는 다음과 같은 빠르고 더러운 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]
당신이 나와 같다면:
- 언젠가 하위 프로세스가 충돌할 수 있도록 멀티플랫폼
- Python 2.7을 사용하여 GitPython을 사용할 수 없습니다.
- 그것만으로 Numpy를 사용하고 싶지 않다.
- 이미 Sentry를 사용하고 있습니다(감가상각된 이전 버전: raven).
다음으로 (셸에서는 현재 파일 경로가 검출되지 않기 때문에 셸에서는 동작하지 않습니다.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을 계속 사용하고 싶은 분도 있을 것입니다.
따라서 까마귀 없는 까마귀 코드를 사용할 수도 있습니다(토론 참조).
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()
이 파일의 이름을 versioning.py로 지정하고 "files_path_sha"를 Import합니다.여기서 인수로 파일 경로를 전달해야 합니다.
도움이 되시길 바랍니다;)
저는 이 문제를 우연히 발견하고 이 기능을 구현하여 해결했습니다.https://gist.github.com/NaelsonDouglas/9bc3bfa26deec7827cb87816cad88d59
from pathlib import Path
def get_commit(repo_path):
git_folder = Path(repo_path,'.git')
head_name = Path(git_folder, 'HEAD').read_text().split('\n')[0].split(' ')[-1]
head_ref = Path(git_folder,head_name)
commit = head_ref.read_text().replace('\n','')
return commit
r = get_commit('PATH OF YOUR CLONED REPOSITORY')
print(r)
OP와 같은 문제가 있었습니다만, 제 경우는 소스코드를 zip 파일로 클라이언트에 전달하고 있습니다만, python이 인스톨 되어 있는 것은 알고 있습니다만, git가 있다고는 생각할 수 없습니다.OP에 그의 운영체제가 명시되어 있지 않기 때문에 git이 설치되어 있다면 여기에 기여할 수 있을 것 같습니다.
커밋의 해시만 얻으려면 닐슨 더글러스의 답변은 완벽했지만 태그 이름을 얻으려면 둘리치 파이썬 패키지를 사용합니다.python의 단순화된 git 클라이언트입니다.
후 " " " " 가 포함된 패키지 설치 후pip install dulwich --global-option="--pure"
을 사용하다
from dulwich import porcelain
def get_git_revision(base_path):
return porcelain.describe(base_path)
r = get_git_revision("PATH OF YOUR REPOSITORY's ROOT FOLDER")
print(r)
를 여기 하나의 은 " " " 입니다.v0.1.2-1-gfb41223
git description에 의해 반환되는 것과 비슷합니다.즉, 태그 v0.1.2 뒤에 1 commit 이며 commit의 7자리 해시는 fb41223 입니다.
현재 저장소가 더럽고 항상 7자리 해시를 표시하는 옵션이 없지만 git을 설치할 필요가 없기 때문에 트레이드오프를 선택할 수 있습니다.
편집: 명령어에 오류가 있는 경우pip install
--pure
(이 문제에 대해서는, 다음의 2개의 해결 방법 중 하나를 선택합니다).
- 을 설치합니다.Dulwich는 Dulwich를 사용합니다.
pip install urllib3 certifi && pip install dulwich --global-option="--pure"
- pure 합니다: pure: pure pure pure pure pure이 install install 。
pip install dulwich
. 그러면 시스템에 플랫폼에 의존하는 파일이 설치되지만 패키지의 성능이 향상됩니다.
언급URL : https://stackoverflow.com/questions/14989858/get-the-current-git-hash-in-a-python-script
'programing' 카테고리의 다른 글
CTE를 사용한 MariaDB 10.3.14 DELETE 스테이트먼트에서 구문 오류가 발생함 (0) | 2022.10.18 |
---|---|
테이블 작성 시 MARIADB 오류 1064(42000) (0) | 2022.10.18 |
MySQL의 트리 구조 테이블을 한 번에 조회할 수 있습니까? (0) | 2022.10.18 |
os/path 형식에 관계없이 경로에서 파일 이름 추출 (0) | 2022.10.18 |
MySQL 데이터베이스의 모든 테이블에 대한 레코드 수 가져오기 (0) | 2022.10.18 |