2011-11-21 10 views
8

Al utilizar Autoconf en un proyecto administrado por Subversion, me gustaría poner este código en configure.ac:¿Cómo puedo usar AC_REVISION con Git?

AC_REVISION($Revision: 1234 $) 

Con svn:keywords Revision, AC_REVISION gustaría insertar el número de revisión de configure.ac en el configure script generado.

¿Cómo puedo hacer algo similar en un proyecto administrado con Git?

Git no tiene palabras clave como $Revision$, y no tiene números de revisión como tales. Pero tiene SHA1 para confirmaciones y git describe. Simplemente no estoy seguro de cómo incorporar eso en configure.ac.

+0

Si está utilizando un sistema de tipo Unix, se podría escribir un git- gancho para realizar un 'sed -i 's/\ $ Revision/$ REVISION/g' configure.ac' (solo un ejemplo). La varilla '$ REVISION' puede contener el resultado de' git describe' si lo desea. Suena plausible? De lo contrario, puede usar '$ Id: $', que será reemplazado por el sha1 del blob (no el commit). Ver [esta pregunta] (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent). – jweyrich

+1

Lea también [por qué esta no es una buena idea] (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent/384640#384640) cuando se utiliza un SCM distribuido. – jweyrich

+1

Ver http://stackoverflow.com/questions/3593003/injecting-mercurial-changeset-as-version-information-in-ac-executable/3607158 –

Respuesta

3

adl's answer no era exactamente lo que quería, pero me indicó la dirección correcta. Esto es lo que ocurrió:

Pon esto en configure.ac:

AC_REVISION([m4_esyscmd([./tools/configure.commit])]) 

Guardar esto como tools/configure.commit (y hacerlo ejecutable):

#! /bin/sh 
# Display the SHA1 of the commit in which configure.ac was last modified. 
# If it's not checked in yet, use the SHA1 of HEAD plus -dirty. 

if [ ! -d .git ] ; then 
    # if no .git directory, assume they're not using Git 
    printf 'unknown commit' 
elif git diff --quiet HEAD -- configure.ac ; then 
    # configure.ac is not modified 
    printf 'commit %s' `git rev-list --max-count=1 HEAD -- configure.ac` 
else # configure.ac is modified 
    printf 'commit %s-dirty' `git rev-parse HEAD` 
fi 

Esa combinación pondrá el SHA-1 de el compromiso en el que configure.ac se modificó por última vez en configure, que es lo que estaba buscando. Pero hay un problema. Git no toca el tiempo de modificación de los archivos cuando los comete. Esto significa que configure continuará conteniendo el valor OLDSHA-dirty en lugar de actualizarse, porque autoconf no se dará cuenta de que está desactualizado.

Puede resolver eso con un enganche post-commit. Guardar como .git/hooks/post-commit (y asegúrese de chmod como ejecutable o no se ejecutará):

#!/bin/sh 
# 
# Copy this to .git/hooks/post-commit 

# If configure.ac was just checked in, touch it, 
# so that configure will be regenerated and 
# AC_REVISION will reflect the new commit. 
# 
# For some reason, --quiet isn't actually quiet, 
# so redirect output to /dev/null 

git diff-tree --quiet HEAD -- configure.ac >/dev/null \ 
|| touch -c configure.ac 
0

Git tiene algo similar, pero tiene que habilitarlo específicamente para las rutas relevantes a través del archivo .gitattributes.

ident 
     When the attribute ident is set for a path, git replaces $Id$ in 
     the blob object with $Id:, followed by the 40-character hexadecimal 
     blob object name, followed by a dollar sign $ upon checkout. Any 
     byte sequence that begins with $Id: and ends with $ in the worktree 
     file is replaced with $Id$ upon check-in. 
+1

No estoy seguro de cuán útil sería SHA1 del blob. Dado el SHA1 del blob, ¿cómo encuentras el commit que lo incluye? Prefiero algo como 'git describe'. – cjm

0
  • antiguo, pero útil answer about Git and keywords
  • Pro Git, consulte "expansión Palabras clave" para obtener ayuda con filtros (con buen ejemplo del uso de filtros para la construcción de $ Fecha $ palabra clave)
3

Puede realmente ejecuta cualquier comando con M4 cuando se ejecuta Autoconf. Por lo tanto tal vez quiere algo como:

AC_REVISION([m4_esyscmd_s([git describe --always])]) 

Tenga en cuenta que a diferencia de las cadenas $Revision$ su configure.ac no va a cambiar cada vez que actualice su árbol. Por lo tanto, configure no se regenerará después de cada actualización y la revisión incluida en configure será simplemente la última versión para la que se generó configure.

0

yo estaba tratando de lograr algo similar a la OP; Quería incrustar Git commit-id en la cadena de versión de Postgres. El código en la configuración de Postgres.en, en la misma línea que tenía la intención de modificar, ya tenía un ejemplo.

El quid de la cuestión es que se puede incrustar fragmento de concha en los literales de cadena en configure.in y el configure archivo resultante (la cáscara de ejecutar el script de shell, en realidad) siempre ejecutar ese fragmento de concha para construir la cadena resultante.

Consulte el patch. Los siguientes son los parches para configure.in y la sección correspondiente del archivo resultante configure.

AC_DEFINE_UNQUOTED(PG_VERSION_STR, 
-     ["PostgreSQL $PACKAGE_VERSION on $host, compiled by $cc_string, `expr $ac_cv_sizeof_void_p \* 8`-bit"], 
+     ["PostgreSQL $PACKAGE_VERSION (commit `cd $srcdir && git log -1 --format=format:%h`) on $host, compiled by $cc_string, `expr $ac_cv_sizeof_void_p \* 8`-bit"], 
        [A string containing the version number, platform, and C compiler]) 

resultante configure código:

cat >>confdefs.h <<_ACEOF 
-#define PG_VERSION_STR "PostgreSQL $PACKAGE_VERSION on $host, compiled by $cc_string, `expr $ac_cv_sizeof_void_p \* 8`-bit" 
+#define PG_VERSION_STR "PostgreSQL $PACKAGE_VERSION (commit `cd $srcdir && git log -1 --format=format:%h`) on $host, compiled by $cc_string, `expr $ac_cv_sizeof_void_p \* 8`-bit" 
_ACEOF 

Postgres versión de cadena antes y después de la revisión de seguridad:

PostgreSQL 9.3.0 on x86_64-unknown-linux-gnu, compiled by ... 
PostgreSQL 9.3.0 (commit 2cf9dac) on x86_64-unknown-linux-gnu, compiled by ... 
+0

El gran problema con este parche es que ya no puedes 'hacer dist', porque tu script' configure' supone que se está ejecutando dentro de un repositorio de Git. Si alguien desempaqueta un tarball y ejecuta './Configure', terminará con una cadena de versión de aspecto extraño. – cjm

+0

El enfoque general puede funcionar, pero necesita un código de shell más complejo que maneje el caso "not a Git repo". Sugiero que 'make dist' genere un archivo GITREVISION en el archivo tar y lea la confirmación de eso si' $ srcdir/.git' no existe. – cjm

+0

En una nota lateral, esto no resuelve el mismo problema. Estoy intentando grabar la versión del script 'configure', y estás tratando de registrar la versión del código que se está configurando. Es por eso que mi solución se ejecuta en el tiempo 'autoconf', y la suya se ejecuta en el momento' configure'. – cjm

Cuestiones relacionadas