2011-11-21 4 views
8

Podczas korzystania Autoconf w projekcie zarządzanym z Subversion, chciałbym umieścić ten kod w configure.ac:Jak mogę używać AC_REVISION z Git?

AC_REVISION($Revision: 1234 $) 

Z svn:keywords Revision, AC_REVISION by wstawić numer wersji configure.ac do wygenerowanego configure skryptu.

Jak mogę zrobić coś podobnego w projekcie zarządzanym przy pomocy Git?

Git nie ma słów kluczowych, takich jak $Revision$, i nie ma numerów wersji jako takich. Ale ma SHA1 dla commitów i git describe. Po prostu nie jestem pewien, jak włączyć to do configure.ac.

+0

Jeśli używasz systemu uniksowego, można napisać git- hook do wykonania 'sed -i 's/\ $ Revision/$ REVISION/g' configure.ac' (tylko przykład). Zmienna '$ REVISION' może zawierać wynik' git description', jeśli będziesz. Brzmi prawdopodobny? W przeciwnym razie możesz użyć '$ Id: $', które zostanie zastąpione przez sha1 obiektu blob (nie commit). Zobacz [to pytanie] (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent). – jweyrich

+1

Przeczytaj również (dlaczego to nie jest dobry pomysł) (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent/384640#384640) podczas korzystania z rozproszonego SCM. – jweyrich

+1

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

Odpowiedz

3

adl's answer nie był tym, czego chciałem, ale wskazał mi właściwy kierunek. Oto co wymyśliłem:

umieścić to w configure.ac:

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

Zapisz jako tools/configure.commit (i uczynić go wykonywalnym):

#! /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 

To połączenie będzie umieścić SHA-1 z zatwierdzenie, w którym configure.ac została ostatnio zmodyfikowana do configure, czego właśnie szukałem. Ale jest problem. Git nie dotyka czasu modyfikacji plików po ich zatwierdzeniu. Oznacza to, że configure będzie nadal zawierać wartość OLDSHA-dirty zamiast aktualizować, ponieważ autoconf nie będzie wiedział, że jest nieaktualny.

Można to rozwiązać za pomocą haka po zatwierdzeniu. Zapisz jako .git/hooks/post-commit (i upewnij się, że chmod go jako plik wykonywalny, albo nie będzie działać):

#!/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 ma coś podobnego, ale musisz włączyć go specjalnie dla odpowiednich ścieżek poprzez plik .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

Nie jestem pewien, jak przydatne będzie SHA1 obiektu blob. Biorąc pod uwagę SHA1 BLOBa, jak znaleźć zatwierdzenie, które go obejmuje? Wolałbym coś takiego jak "git opisać". – cjm

3

Można właściwie wykonuje dowolne polecenie za pomocą M4, gdy działa Autoconf. W ten sposób może chcesz coś takiego:

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

Należy zauważyć, że w przeciwieństwie do $Revision$ strun swojej configure.ac nie zmieni się za każdym razem aktualizować swoje drzewo. W związku z tym configure nie zostanie zregenerowane po każdej aktualizacji, a wersja wprowadzona do configure będzie po prostu ostatnią wersją, dla której wygenerowano configure.

0

starałem się osiągnąć coś podobnego jak OP; Chciałem osadzić commit-id Git w ciągu znaków PostgreSQL. Kod w konfiguracji PostgreSta.w tej samej linii, którą zamierzałem zmodyfikować, już miałem przykład.

Istotą jest to, że można osadzić fragment powłoki w napisowych w configure.in i otrzymaną configure plik (powłoka wykonywania skryptu powłoki, faktycznie) będą zawsze wykonać ten fragment powłoki na budowę wynikowy ciąg.

Patrz: patch. Poniżej znajdują się łatki do configure.in i odpowiednią sekcję z otrzymanego pliku 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]) 

kod wynikowy configure:

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 

PostgreSQL wersji ciąg przed i po patch:

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

Duży problem z tą poprawką polega na tym, że nie można już "make dist", ponieważ skrypt 'configure' zakłada, że ​​działa on wewnątrz repozytorium Git. Jeśli ktoś rozpakuje plik tarballa i uruchomi './Configure', to skończy się dziwnym wyglądem. – cjm

+0

Ogólne podejście może działać, ale potrzebujesz bardziej złożonego kodu powłoki, który obsługuje przypadek "nie jest to Git repo". Proponuję, żeby 'make dist' wygenerował plik GITREVISION w archiwum tar i przeczytał zatwierdzenie, jeśli' $ srcdir/.git' nie istnieje. – cjm

+0

Na marginesie, to nie rozwiązuje tego samego problemu. Próbuję nagrać wersję skryptu 'configure' i próbujesz nagrać wersję konfigurowanego kodu. Dlatego moje rozwiązanie działa w czasie 'autoconf', a twoje działa w' configure' time. – cjm