Git 버전 해시에 액세스 할 수있는 C 코드를 작성하는 쉬운 방법이 있습니까?
실험실 환경에서 과학 데이터를 수집하기 위해 C로 소프트웨어를 작성했습니다. 내 코드는 수집 한 데이터를 나중에 분석하기 위해 .yaml 파일에 기록합니다. 내 실험은 매일 바뀌고 종종 코드를 수정해야합니다. 개정을 추적하기 위해 git 저장소를 사용합니다.
내 .yaml 데이터 파일에 주석으로 Git 개정 해시를 포함하고 싶습니다. 이렇게하면 .yaml 파일을보고 해당 파일에 표시된 데이터를 생성하는 데 사용 된 코드를 정확히 알 수 있습니다. 이 작업을 자동으로 수행하는 쉬운 방법이 있습니까?
답변
내 프로그램에서 git 버전 번호와 빌드 날짜를라는 별도의 파일에 보관 version.c
합니다.
#include "version.h"
const char * build_date = "2009-11-10 11:09";
const char * build_git_sha = "6b54ea36e92d4907aba8b3fade7f2d58a921b6cd";
다음과 같은 헤더 파일도 있습니다.
#ifndef VERSION_H
#define VERSION_H
extern const char * build_date; /* 2009-11-10 11:09 */
extern const char * build_git_sha; /* 6b54ea36e92d4907aba8b3fade7f2d58a921b6cd */
#endif /* VERSION_H */
헤더 파일과 C 파일은 모두 다음과 같은 Perl 스크립트에 의해 생성됩니다.
my $git_sha = `git rev-parse HEAD`;
$git_sha =~ s/\s+//g;
# This contains all the build variables.
my %build;
$build{date} = make_date_time ();
$build{git_sha} = $git_sha;
hash_to_c_file ("version.c", \%build, "build_");
여기에 hash_to_c_file
만드는 모든 작업 수행 version.c
과 version.h
와 make_date_time
같이 문자열을 만든다.
메인 프로그램에는 루틴이 있습니다.
#include "version.h"
// The name of this program.
const char * program_name = "magikruiser";
// The version of this program.
const char * version = "0.010";
/* Print an ID stamp for the program. */
static void _program_id_stamp (FILE * output)
{
fprintf (output, "%s / %s / %s / %s\n",
program_name, version,
build_date, build_git_sha);
}
나는 git에 대해 잘 알지 못하기 때문에 더 나은 방법이 있다면 의견을 환영합니다.
답변
make 기반 빌드를 사용하는 경우 Makefile에 넣을 수 있습니다.
GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)"
( 스위치의 기능 은 man git describe 참조 )
그런 다음 CFLAGS에 다음을 추가하십시오.
-DVERSION=\"$(GIT_VERSION)\"
그런 다음 #define처럼 프로그램에서 직접 버전을 참조 할 수 있습니다.
printf("Version: %s\n", VERSION);
기본적으로 이것은 축약 된 git commit id를 인쇄하지만 선택적으로 특정 릴리스에 다음과 같은 태그를 지정할 수 있습니다.
git tag -a v1.1 -m "Release v1.1"
그러면 다음과 같이 인쇄됩니다.
Version: v1.1-2-g766d
즉, “766d”로 시작하는 git commit id로 v1.1 이전에 2 번 커밋됩니다.
트리에 커밋되지 않은 변경 사항이 있으면 “-dirty”를 추가합니다.
종속성 검사가 없으므로 make clean
버전을 강제로 업데이트 하려면 명시 적으로 수행해야합니다 . 그러나 이것은 해결할 수 있습니다 .
장점은 간단하고 perl 또는 awk와 같은 추가 빌드 종속성이 필요하지 않다는 것입니다. 이 접근 방식을 GNU automake 및 Android NDK 빌드와 함께 사용했습니다.
답변
@Kinopiko의 답변과 매우 유사한 것을 사용했지만 perl 대신 awk를 사용했습니다. 이것은 mingw의 특성상 awk가 설치되어 있지만 perl이 아닌 Windows 시스템에 붙어있는 경우 유용합니다. 작동 방식은 다음과 같습니다.
내 makefile에는 git, date 및 awk를 호출하여 ac 파일을 만드는 줄이 있습니다.
$(MyLibs)/version.c: FORCE
$(GIT) rev-parse HEAD | awk ' BEGIN {print "#include \"version.h\""} {print "const char * build_git_sha = \"" $$0"\";"} END {}' > $(MyLibs)/version.c
date | awk 'BEGIN {} {print "const char * build_git_time = \""$$0"\";"} END {} ' >> $(MyLibs)/version.c
코드를 컴파일 할 때마다 awk 명령은 다음과 같은 version.c 파일을 생성합니다.
/* version.c */
#include "version.h"
const char * build_git_sha = "ac5bffc90f0034df9e091a7b3aa12d150df26a0e";
const char * build_git_time = "Thu Dec 3 18:03:58 EST 2009";
다음과 같은 정적 version.h 파일이 있습니다.
/*version.h*/
#ifndef VERSION_H_
#define VERSION_H_
extern const char * build_git_time;
extern const char * build_git_sha;
#endif /* VERSION_H_ */
이제 나머지 코드는 단순히 version.h 헤더를 포함하여 빌드 시간과 git 해시에 액세스 할 수 있습니다. 모든 것을 마무리하기 위해 .gitignore 파일에 한 줄을 추가하여 git에게 version.c를 무시하도록 지시합니다. 이런 식으로 git은 지속적으로 병합 충돌을 일으키지 않습니다. 도움이 되었기를 바랍니다!
답변
프로그램은 git describe
런타임에 또는 빌드 프로세스의 일부로으로 쉘 아웃 할 수 있습니다 .
답변
다음 두 가지를 수행 할 수 있습니다.
-
Git 이 파일에 일부 버전 정보를 포함 하도록 만들 수 있습니다 .
간단한 방법은 사용하는 것입니다
ident
속성 (예를 들어) 퍼팅 의미,*.yaml ident
에서
.gitattributes
파일 및$Id$
적절한 장소이다. 파일 내용의 SHA-1 식별자 (blob id) 로 자동 확장됩니다 . 이것은 파일 버전이 아니거나 마지막 커밋입니다.Git은 이러한 방식으로 $ Id $ 키워드를 지원하여 분기 전환, 분기 되감기 등에서 변경되지 않은 파일을 건드리지 않도록합니다. 정말로 Git이 파일에 커밋 (버전) 식별자 또는 설명을 입력하도록하려면 (남용) 사용할 수 있습니다.
filter
결제시 일부 키워드 (예 : $ Revision $)를 확장하기 위해 clean / smudge filter를 사용하고 커밋을 위해 정리합니다. -
Linux 커널이나 Git 자체처럼 빌드 프로세스 를 만들 수 있습니다 .
봐 가지고 GIT-VERSION-GEN 스크립트 및 힘내에서의 사용 메이크 파일 이 메이크가 생성 / 구성 중에 버전 정보를 내장하는 방법, 또는 예를 들어
gitweb/gitweb.cgi
파일을.GIT-VERSION-GEN은 git describe 를 사용하여 버전 설명을 생성합니다. 프로젝트의 릴리스 / 마일스톤에 태그 (서명 / 주석 태그 사용)를 태그하는 것이 더 잘 작동해야합니다.
답변
이 작업을 수행해야 할 때 같은 태그를 사용합니다 RELEASE_1_23
. SHA-1을 몰라도 태그가 무엇인지 결정할 수 있습니다. 나는 다음 태그를 커밋합니다. 원하는대로 프로그램에 해당 태그를 저장할 수 있습니다.
답변
njd27의 답변에 따라 코드가 다른 방식으로 빌드 될 때 기본값이있는 version.h 파일과 함께 종속성 스캔이있는 버전을 사용하고 있습니다. version.h를 포함하는 모든 파일이 다시 빌드됩니다.
또한 개정 날짜를 별도의 정의로 포함합니다.
# Get git commit version and date
GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty)
GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ad" --name-only))
# recompile version.h dependants when GIT_VERSION changes, uses temporary file version~
.PHONY: force
version~: force
@echo '$(GIT_VERSION) $(GIT_DATE)' | cmp -s - $@ || echo '$(GIT_VERSION) $(GIT_DATE)' > $@
version.h: version~
@touch $@
@echo Git version $(GIT_VERSION) $(GIT_DATE)