Risposte:
Il git describe
comando è un buon modo per creare un "numero di versione" presentabile dall'uomo del codice. Dagli esempi nella documentazione:
Con qualcosa come git.git albero attuale, ottengo:
[torvalds@g5 git]$ git describe parent v1.0.4-14-g2414721
cioè l'attuale capo del mio ramo "genitore" si basa sulla v1.0.4, ma dato che ha alcuni commit in più, descriva ha aggiunto il numero di commit aggiuntivi ("14") e un nome oggetto abbreviato per il commit stesso ("2414721") alla fine.
Da Python puoi fare qualcosa del tipo:
import subprocess
label = subprocess.check_output(["git", "describe"]).strip()
fatal: No names found, cannot describe anything.
git describe --always
tornerà all'ultimo commit se non vengono trovati tag
git describe
normalmente richiede almeno un tag. Se non hai tag, usa l' --always
opzione. Vedi la documentazione descrittiva git per maggiori informazioni
Non c'è bisogno di hackerare per ottenere i dati dal git
comando da soli. GitPython è un modo molto carino per fare questo e molte altre git
cose. Ha anche il supporto "best effort" per Windows.
Dopo pip install gitpython
che puoi farlo
import git
repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha
ImportError: No module named gitpython
. Non puoi fare affidamento sul fatto che l'utente finale abbia gitpython
installato e che richieda l'installazione prima che il tuo codice funzioni, non lo rende portatile. A meno che non includerai protocolli di installazione automatica, a quel punto non è più una soluzione pulita.
pip
/ requirements.txt
) su tutte le piattaforme. Cosa non è "pulito"?
import numpy as np
possa presumere in tutto lo stackoverflow ma l'installazione di gitpython va oltre "clean" e "portable". Penso che questa sia di gran lunga la soluzione migliore, perché non reinventa la ruota, nasconde la brutta implementazione e non va in giro hackerando la risposta di Git dal sottoprocesso.
pip
o possibilità di installazione semplice pip
. In questi scenari moderni, una pip
soluzione è portatile come una soluzione "libreria standard".
Questo post contiene il comando, la risposta di Greg contiene il comando sottoprocesso.
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()
per decodificare la stringa binaria (e rimuovere l'interruzione di riga).
numpy
ha una bella routine multipiattaforma nel suo 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 fosse necessaria per la funzionalità multipiattaforma. La risposta di Yuji no, ma forse funziona sia su UNIX che su Windows.
.decode('ascii')
altrimenti la codifica è sconosciuta.
Se il sottoprocesso non è portatile e non vuoi installare un pacchetto per fare qualcosa di così semplice, puoi anche farlo.
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()
L'ho provato solo sui miei repository, ma sembra funzionare abbastanza coerentemente.
Ecco una versione più completa della risposta di Greg :
import subprocess
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
Oppure, se lo script viene chiamato dall'esterno del repository:
import subprocess, os
os.chdir(os.path.dirname(__file__))
print(subprocess.check_output(["git", "describe", "--always"]).strip().decode())
os.chdir
, l' cwd=
arg può essere utilizzato check_output
per modificare temporaneamente la directory di lavoro prima dell'esecuzione.
Se per qualche motivo non hai git disponibile, ma hai il repository git (viene trovata la cartella .git), puoi recuperare l'hash di commit da .git / fetch / heads / [branch]
Ad esempio, ho usato un frammento di Python veloce e sporco seguente nella radice del repository per ottenere l'ID commit:
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
dalla riga di comando. La sintassi dell'output dovrebbe essere ovvia.