es decir, el encabezado actual de mi rama "principal" se basa en v1.0.4, pero dado que tiene algunas confirmaciones además de eso, describe ha agregado el número de confirmaciones adicionales ("14") y un nombre de objeto abreviado para la confirmación en sí ("2414721") al final.
Esto tiene el inconveniente de que el código de impresión de la versión se romperá si el código se ejecuta sin el repositorio git presente. Por ejemplo, en producción. :)
JosefAssad
55
@JosefAssad: si necesita un identificador de versión en producción, entonces su procedimiento de implementación debe ejecutar el código anterior y el resultado debe "integrarse" en el código implementado en producción.
Greg Hewgill
14
Tenga en cuenta que git describe fallará si no hay etiquetas presentes:fatal: No names found, cannot describe anything.
kynan
40
git describe --alwaysrecurrirá a la última confirmación si no se encuentran etiquetas
Leonardo
55
@CharlieParker: git describenormalmente requiere al menos una etiqueta. Si no tiene ninguna etiqueta, use la --alwaysopción. Consulte la documentación de git describe para obtener más información.
Greg Hewgill
189
No es necesario hackear para obtener datos del gitcomando usted mismo. GitPython es una muy buena manera de hacer esto y muchas otras gitcosas. Incluso tiene soporte de "mejor esfuerzo" para Windows.
@crishoj No sabe cómo se le puede llamar portátil cuando esto sucede: ImportError: No module named gitpython. No puede confiar en que el usuario final haya gitpythoninstalado, y exigirles que lo instalen antes de que su código funcione no lo hace portátil. A menos que vaya a incluir protocolos de instalación automática, en ese momento ya no es una solución limpia.
user5359531
39
@ user5359531 Le ruego que difiera. GitPython proporciona una implementación pura de Python, abstrayendo detalles específicos de la plataforma, y es instalable usando herramientas de paquete estándar ( pip/ requirements.txt) en todas las plataformas. ¿Qué no es "limpio"?
crishoj
22
Esta es la forma normal de hacer cosas en Python. Si el OP necesita esos requisitos, entonces lo habrían dicho. No somos lectores de la mente, no podemos predecir cada eventualidad en cada pregunta. De esa manera se encuentra la locura.
OldTinfoil
14
@ user5359531, no estoy claro por qué import numpy as npse puede suponer en todo el stackoverflow, pero la instalación de gitpython está más allá de 'clean' y 'portable'. Creo que esta es, con mucho, la mejor solución, porque no reinventa la rueda, oculta la implementación fea y no anda pirateando la respuesta de git del subproceso.
Jblasco
77
@ user5359531 Si bien estoy de acuerdo en general en que no debe arrojar una nueva biblioteca brillante a cada pequeño problema, su definición de "portabilidad" parece descuidar los escenarios modernos en los que los desarrolladores tienen control total sobre todos los entornos en los que se ejecutan dichas aplicaciones. En 2018 tenemos Contenedores Docker, entornos virtuales e imágenes de máquinas (por ejemplo, AMI) con pipla capacidad de instalarse fácilmente pip. En estos escenarios modernos, una pipsolución es tan portátil como una solución de "biblioteca estándar".
import os
import subprocess
# Return the git revision as a stringdef git_version():def _minimal_ext_cmd(cmd):# construct minimal environment
env ={}for k in['SYSTEMROOT','PATH']:
v = os.environ.get(k)if v isnotNone:
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')exceptOSError:
GIT_REVISION ="Unknown"return GIT_REVISION
Me gusta esto, bastante limpio y sin bibliotecas externas
13aal
La respuesta de Yuji proporciona una solución similar en una sola línea de código que produce el mismo resultado. ¿Puede explicar por qué numpyconsideró necesario "construir un entorno mínimo"? (suponiendo que tenían una buena razón para hacerlo)
MD004
Acabo de notar esto en su repositorio y decidí agregarlo a esta pregunta para las personas interesadas. No desarrollo en Windows, así que no he probado esto, pero asumí que configurar el envdict era necesario para la funcionalidad multiplataforma. La respuesta de Yuji no, pero quizás eso funcione tanto en UNIX como en Windows.
ryanjdillon
Mirando la culpa de git, hicieron esto como una corrección de errores para SVN hace 11 años: github.com/numpy/numpy/commit/… Es posible que la corrección de errores ya no sea necesaria para git.
gparent
@ MD004 @ryanjdillon Establecen la configuración regional para que .decode('ascii')funcione; de lo contrario, la codificación es desconocida.
z0r
7
Si el subproceso no es portátil y no desea instalar un paquete para hacer algo así de simple, también puede hacerlo.
En lugar de usar os.chdir, el cwd=argumento puede usarse check_outputpara realizar cambios temporales en el directorio de trabajo antes de ejecutarlo.
Marc
0
Si no tiene git disponible por alguna razón, pero tiene el repositorio git (se encuentra la carpeta .git), puede obtener el hash de confirmación de .git / fetch / heads / [branch]
Por ejemplo, he usado un siguiente fragmento de Python rápido y sucio en la raíz del repositorio para obtener la identificación de confirmació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
desde la línea de comando. La sintaxis de salida debería ser obvia.Respuestas:
El
git describe
comando es una buena forma de crear un "número de versión" del código presentable por humanos. De los ejemplos en la documentación:Desde Python, puede hacer algo como lo siguiente:
fuente
fatal: No names found, cannot describe anything.
git describe --always
recurrirá a la última confirmación si no se encuentran etiquetasgit describe
normalmente requiere al menos una etiqueta. Si no tiene ninguna etiqueta, use la--always
opción. Consulte la documentación de git describe para obtener más información.No es necesario hackear para obtener datos del
git
comando usted mismo. GitPython es una muy buena manera de hacer esto y muchas otrasgit
cosas. Incluso tiene soporte de "mejor esfuerzo" para Windows.Después de
pip install gitpython
que puedas hacerfuente
ImportError: No module named gitpython
. No puede confiar en que el usuario final hayagitpython
instalado, y exigirles que lo instalen antes de que su código funcione no lo hace portátil. A menos que vaya a incluir protocolos de instalación automática, en ese momento ya no es una solución limpia.pip
/requirements.txt
) en todas las plataformas. ¿Qué no es "limpio"?import numpy as np
se puede suponer en todo el stackoverflow, pero la instalación de gitpython está más allá de 'clean' y 'portable'. Creo que esta es, con mucho, la mejor solución, porque no reinventa la rueda, oculta la implementación fea y no anda pirateando la respuesta de git del subproceso.pip
la capacidad de instalarse fácilmentepip
. En estos escenarios modernos, unapip
solución es tan portátil como una solución de "biblioteca estándar".Esta publicación contiene el comando, la respuesta de Greg contiene el comando de subproceso.
fuente
.decode('ascii').strip()
para decodificar la cadena binaria (y elimine el salto de línea).numpy
tiene una bonita rutina multiplataforma en susetup.py
:fuente
numpy
consideró necesario "construir un entorno mínimo"? (suponiendo que tenían una buena razón para hacerlo)env
dict era necesario para la funcionalidad multiplataforma. La respuesta de Yuji no, pero quizás eso funcione tanto en UNIX como en Windows..decode('ascii')
funcione; de lo contrario, la codificación es desconocida.Si el subproceso no es portátil y no desea instalar un paquete para hacer algo así de simple, también puede hacerlo.
Solo he probado esto en mis repositorios, pero parece funcionar de manera bastante consistente.
fuente
Aquí hay una versión más completa de la respuesta de Greg :
O, si el script se llama desde fuera del repositorio:
fuente
os.chdir
, elcwd=
argumento puede usarsecheck_output
para realizar cambios temporales en el directorio de trabajo antes de ejecutarlo.Si no tiene git disponible por alguna razón, pero tiene el repositorio git (se encuentra la carpeta .git), puede obtener el hash de confirmación de .git / fetch / heads / [branch]
Por ejemplo, he usado un siguiente fragmento de Python rápido y sucio en la raíz del repositorio para obtener la identificación de confirmación:
fuente