Câu trả lời:
Các git describelệnh là một cách tốt để tạo ra một "số phiên bản" con người-đoan của mã này. Từ các ví dụ trong tài liệu:
Với một cái gì đó như git.git cây hiện tại, tôi nhận được:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721tức là người đứng đầu hiện tại của nhánh "cha mẹ" của tôi dựa trên v1.0.4, nhưng vì nó có một vài cam kết trên đó, mô tả đã thêm số lần xác nhận bổ sung ("14") và tên đối tượng viết tắt cho cam kết chính nó ("2414721") ở cuối.
Từ bên trong Python, bạn có thể làm một cái gì đó như sau:
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --alwayssẽ chuyển sang cam kết cuối cùng nếu không tìm thấy thẻ nào
git describethường yêu cầu ít nhất một thẻ. Nếu bạn không có bất kỳ thẻ nào, hãy sử dụng --alwaystùy chọn. Xem tài liệu mô tả git để biết thêm thông tin.
Không cần phải hack xung quanh để lấy dữ liệu từ gitlệnh. GitPython là một cách rất hay để làm điều này và rất nhiều gitthứ khác . Nó thậm chí còn có hỗ trợ "nỗ lực tốt nhất" cho Windows.
Sau khi pip install gitpythonbạn có thể làm
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython. Bạn không thể dựa vào người dùng cuối đã gitpythoncài đặt và yêu cầu họ cài đặt nó trước khi mã của bạn hoạt động khiến nó không thể di động được. Trừ khi bạn sẽ bao gồm các giao thức cài đặt tự động, tại thời điểm đó, nó không còn là một giải pháp sạch.
pip/ requirements.txt) trên tất cả các nền tảng. Cái gì không "sạch"?
import numpy as npcó thể được giả sử trong toàn bộ stackoverflow nhưng cài đặt gitpython vượt quá 'sạch' và 'di động'. Tôi nghĩ rằng đây là giải pháp tốt nhất, bởi vì nó không phát minh lại bánh xe, che giấu việc thực hiện xấu xí và không đi vòng quanh việc hack câu trả lời của git từ quy trình con.
piphoặc khả năng dễ dàng cài đặt pip. Trong các kịch bản hiện đại này, một pipgiải pháp cũng dễ mang theo như một giải pháp "thư viện chuẩn".
Bài đăng này chứa lệnh, câu trả lời của Greg chứa lệnh quy trình con.
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()để giải mã chuỗi nhị phân (và loại bỏ ngắt dòng).
numpycó một thói quen đa nền tảng đẹp mắt trong 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
numpythấy cần thiết phải "xây dựng một môi trường tối thiểu" không? (giả sử họ có lý do chính đáng)
envlà cần thiết cho chức năng đa nền tảng. Câu trả lời của Yuji thì không, nhưng có lẽ nó hoạt động trên cả UNIX và Windows.
.decode('ascii')hoạt động - nếu không thì mã hóa không xác định.
Nếu quy trình con không thể di động và bạn không muốn cài đặt một gói để làm điều gì đó đơn giản, bạn cũng có thể làm điều này.
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()
Tôi chỉ thử nghiệm điều này trên repos của mình nhưng có vẻ như nó hoạt động khá ổn định.
Đây là phiên bản hoàn chỉnh hơn của câu trả lời của Greg :
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
Hoặc, nếu tập lệnh đang được gọi từ bên ngoài repo:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir, cwd=arg có thể được sử dụng check_outputđể thay đổi tạm thời thư mục làm việc trước khi thực thi.
Nếu bạn không có sẵn git vì một số lý do, nhưng bạn có git repo (thư mục .git được tìm thấy), bạn có thể tìm nạp hàm băm từ .git / fetch / Heads / [Branch]
Ví dụ: tôi đã sử dụng đoạn mã Python nhanh và bẩn sau đây chạy ở thư mục gốc của kho lưu trữ để lấy id xác nhận:
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 HEADtừ dòng lệnh. Cú pháp đầu ra phải rõ ràng.