2011-11-21 23 views
8

Khi sử dụng Autoconf trong một dự án được quản lý với Subversion, tôi sẽ đặt mã này trong configure.ac:Tôi có thể sử dụng AC_REVISION bằng Git bằng cách nào?

AC_REVISION($Revision: 1234 $) 

Với svn:keywords Revision, AC_REVISION sẽ chèn số phiên bản của configure.ac vào tạo configure kịch bản.

Tôi có thể làm điều gì đó tương tự trong một dự án được quản lý với Git?

Git không có từ khóa như $Revision$ và không có số sửa đổi như vậy. Nhưng nó có SHA1 cho các cam kết, và git describe. Tôi chỉ không chắc chắn làm thế nào để kết hợp nó vào configure.ac.

+0

Nếu bạn đang sử dụng một hệ thống unix-like, bạn có thể viết một git- hook để thực hiện 'sed -i 's/\ $ Revision/$ REVISION/g' configure.ac' (chỉ là một ví dụ). '$ REVISION' var có thể chứa kết quả của' git describe' nếu bạn muốn. Nghe có vẻ hợp lý? Nếu không, bạn có thể sử dụng '$ Id: $', mà sẽ được thay thế bằng sha1 của blob (không phải là cam kết). Xem [câu hỏi này] (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent). – jweyrich

+1

Cũng đọc [lý do tại sao đây không phải là một ý tưởng hay] (http://stackoverflow.com/questions/384108/moving-from-cvs-to-git-id-equivalent/384640#384640) khi sử dụng SCM phân tán. – jweyrich

+1

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

Trả lời

3

adl's answer không hoàn toàn là những gì tôi muốn, nhưng nó chỉ cho tôi đi đúng hướng. Dưới đây là những gì tôi đã đưa ra:

Đặt này trong configure.ac:

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

Lưu này như tools/configure.commit (và làm cho nó thực thi):

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

Sự kết hợp sẽ đặt SHA-1 trong tổng số cam kết trong đó configure.ac được sửa đổi lần cuối thành configure, đó là những gì tôi đang tìm kiếm. Nhưng có một vấn đề. Git không chạm vào thời gian sửa đổi tệp khi nó cam kết. Điều này có nghĩa là configure sẽ tiếp tục chứa giá trị OLDSHA-dirty thay vì được cập nhật vì autoconf sẽ không nhận ra rằng nó đã lỗi thời.

Bạn có thể giải quyết điều đó bằng móc hậu sau. Lưu này như .git/hooks/post-commit (và chắc chắn rằng bạn chmod nó như là thực thi, hoặc nó sẽ không chạy):

#!/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 có điều gì đó tương tự, nhưng bạn phải bật cụ thể nó cho các đường dẫn có liên quan thông qua tệp .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

Tôi không chắc chắn về cách hữu ích của SHA1 của blob. Với SHA1 của blob, làm cách nào bạn tìm thấy cam kết bao gồm nó? Tôi thích thứ gì đó giống như 'git describe'. – cjm

0
  • Cũ, nhưng hữu ích answer about Git and keywords
  • Pro Git, xem "Từ khoá mở rộng" để được giúp đỡ với các bộ lọc (với ví dụ tốt đẹp của việc sử dụng các bộ lọc để xây dựng $ Ngày $ từ khóa)
3

Bạn có thể thực sự thực thi bất kỳ lệnh nào với M4 khi Autoconf chạy. Như vậy có lẽ bạn muốn một cái gì đó như:

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

Lưu ý rằng không giống như với $Revision$ dây của bạn configure.ac sẽ không thay đổi mỗi khi bạn cập nhật cây của bạn. Do đó configure sẽ không được tạo lại sau mỗi lần cập nhật và bản sửa đổi được đưa vào configure sẽ đơn giản là phiên bản cuối cùng mà configure được tạo.

0

Tôi đã cố gắng để đạt được một cái gì đó tương tự như OP; Tôi muốn nhúng Git commit-id trong chuỗi phiên bản Postgres. Mã trong cấu hình của Postgres.trong cùng một dòng mà tôi dự định sửa đổi, đã có một ví dụ.

Ý chính của nó là bạn có thể nhúng đoạn mã trong chuỗi ký tự trong configure.in và kết quả là tệp configure (trình bao thực thi shell script) sẽ luôn thực thi đoạn mã đó để tạo chuỗi kết quả.

Vui lòng xem patch. Sau đây là các bản vá lỗi cho configure.in và phần có liên quan từ kết quả configure tệp.

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]) 

Kết quả configure mã:

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 chuỗi phiên bản trước và sau khi vá:

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

Vấn đề lớn với bản vá này là bạn không còn có thể 'làm dist' nữa, vì kịch bản' configure' của bạn giả định nó đang chạy bên trong một repo Git. Nếu ai đó mở gói tarball và chạy './Configure', họ sẽ kết thúc với chuỗi phiên bản tìm kiếm lạ. – cjm

+0

Cách tiếp cận chung có thể hoạt động, nhưng bạn cần mã shell phức tạp hơn để xử lý trường hợp "không phải là Git repo". Tôi đề nghị có 'làm cho dist' tạo ra một tập tin GITREVISION trong tarball, và đọc cam kết từ đó nếu' $ srcdir/.git' không tồn tại. – cjm

+0

Một lưu ý phụ, điều này không giải quyết được vấn đề tương tự. Tôi đang cố gắng ghi lại phiên bản của tập lệnh 'configure' và bạn đang cố ghi lại phiên bản của mã đang được định cấu hình. Đó là lý do tại sao giải pháp của tôi chạy ở thời gian 'autoconf', và giải pháp của bạn chạy ở thời gian' configure'. – cjm

Các vấn đề liên quan