Câu trả lời:
Các git describe
lệ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-g2414721
tứ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 --always
sẽ chuyển sang cam kết cuối cùng nếu không tìm thấy thẻ nào
git describe
thườ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 --always
tù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ừ git
lệnh. GitPython là một cách rất hay để làm điều này và rất nhiều git
thứ khác . Nó thậm chí còn có hỗ trợ "nỗ lực tốt nhất" cho Windows.
Sau khi pip install gitpython
bạ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 đã gitpython
cà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 np
có 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.
pip
hoặ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 pip
giả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).
numpy
có 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
numpy
thấ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)
env
là 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 HEAD
từ dòng lệnh. Cú pháp đầu ra phải rõ ràng.