Jawaban:
The git describe
perintah adalah cara yang baik untuk menciptakan "nomor versi" manusia-rapi kode. Dari contoh-contoh dalam dokumentasi:
Dengan sesuatu seperti pohon git.git saat ini, saya mendapatkan:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
yaitu kepala saat ini dari cabang "induk" saya didasarkan pada v1.0.4, tetapi karena memiliki beberapa commit di atas itu, jelaskan telah menambahkan jumlah komit tambahan ("14") dan nama objek singkatan untuk kom sendiri ("2414721") di akhir.
Dari dalam Python, Anda dapat melakukan sesuatu seperti berikut:
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --always
akan mundur ke komit terakhir jika tidak ada tag yang ditemukan
git describe
biasanya membutuhkan setidaknya satu tag. Jika Anda tidak memiliki tag, gunakan --always
opsi. Lihat git menjelaskan dokumentasi untuk informasi lebih lanjut.
Tidak perlu meretas mendapatkan data dari git
perintah sendiri. GitPython adalah cara yang sangat bagus untuk melakukan ini dan banyak git
hal lainnya . Bahkan memiliki dukungan "upaya terbaik" untuk Windows.
Setelah pip install gitpython
kamu bisa melakukannya
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython
. Anda tidak dapat mengandalkan pengguna akhir yang telah gitpython
diinstal, dan mengharuskan mereka untuk menginstalnya sebelum kode Anda berfungsi membuatnya tidak portabel. Kecuali jika Anda akan menyertakan protokol instalasi otomatis, pada saat itu tidak lagi merupakan solusi bersih.
pip
/ requirements.txt
) pada semua platform. Apa yang tidak "bersih"?
import numpy as np
dapat diasumsikan di seluruh stackoverflow tetapi menginstal gitpython melampaui 'bersih' dan 'portabel'. Saya pikir ini sejauh ini solusi terbaik, karena tidak menemukan kembali roda, menyembunyikan implementasi yang buruk dan tidak berkeliling meretas jawaban git dari subproses.
pip
atau kemampuan untuk menginstal dengan mudah pip
. Dalam skenario modern ini, pip
solusi sama portabelnya dengan solusi "perpustakaan standar".
Posting ini berisi perintah, jawaban Greg berisi perintah subproses.
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()
untuk mendekode string biner (dan menghapus jeda baris).
numpy
memiliki rutinitas multi-platform yang terlihat bagus di 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 diperlukan untuk fungsionalitas lintas platform. Jawaban Yuji tidak, tapi mungkin itu bekerja pada UNIX dan Windows.
.decode('ascii')
berfungsi - jika tidak pengkodean tidak diketahui.
Jika subproses tidak portabel dan Anda tidak ingin menginstal paket untuk melakukan sesuatu sesederhana ini, Anda juga dapat melakukannya.
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()
Saya hanya menguji ini pada repo saya tetapi tampaknya bekerja cukup konsisten.
Berikut versi jawaban Greg yang lebih lengkap :
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
Atau, jika skrip dipanggil dari luar repo:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir
, cwd=
arg dapat digunakan check_output
untuk mengubah sementara direktori kerja sebelum mengeksekusi.
Jika Anda tidak memiliki git karena beberapa alasan, tetapi Anda memiliki git repo (folder .git ditemukan), Anda dapat mengambil hash komit dari .git / fetch / heads / [branch]
Sebagai contoh, saya telah menggunakan snippet Python cepat dan kotor berikut yang dijalankan di root repositori untuk mendapatkan id komit:
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
dari baris perintah. Sintaks output harus jelas.