2013-07-29 3 views
3

libgit2를 사용하여 분기의 모든 커밋을 처리하려면 어떻게해야합니까?libgit2를 사용하여 분기의 모든 커밋을 나열하십시오.

이미 다음 코드 비트가 있지만 컴파일되지 않습니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <git2.h> 

int main(int argc, char *argv[]){ 
    git_repository *repo; 
    git_repository_open(&repo, "."); 

    git_odb *obj_db; 
    obj_db = git_repository_database(repo); 

    git_object commit; 
    git_revparse_single(&commit, repo, "HEAD"); 


    git_repository_free(repo); 
    return 0; 
} 

GCC 보고서 다음 -lgit2 플래그로 컴파일

log.c: In function ‘main’: 
log.c:11:9: warning: assignment makes pointer from integer without a cast [enabled by default] 
log.c:13:13: error: storage size of ‘commit’ isn’t known 

I. 루트 커밋을 시작으로 모든 커밋을 빠르게 처리 할 수 ​​있습니까?

업데이트 새로운 코드는 다음과 같습니다 :

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <git2.h> 

int main(int argc, char *argv[]){ 
    git_repository *repo; 
    git_repository_open(&repo, "."); 

    git_odb *obj_db; 
    obj_db = git_repository_database(repo); 

    git_object *commit; 
    git_revparse_single(&commit, repo, "HEAD"); 


    git_repository_free(repo); 
    return 0; 
} 

나는 다음과 같은 오류 메시지를 얻을 :

log.c:11: undefined reference to `git_repository_database' 
log.c:14: undefined reference to `git_revparse_single' 
+2

것이 확인 최신 라이브러리를 사용하고 해당 버전의 설명서를보고 있습니다. 'git_repository_database'는 존재하지 않습니다. 아마도 당신은'git_repository_odb'을 원할 것입니다. 'git_revparse_single'는 버전 0.18에서 소개되었습니다. 이것은 여러분의 시스템에 고대 라이브러리가 설치되어 있음을 암시합니다. –

답변

2

마지막으로 libgit2를 사용하여 작업 버전을 만들었습니다. Carlos Martín Nieto는 올바른 방향으로 지적했는데 다음 예제는 libgit2 0.16과 잘 작동합니다. libgit2-examples 저장소에있는 general.cgithub에 대해 공부하는 데 시간이 걸렸습니다. git revwalk 정확히 내가 찾고있는 것이었다.

필자는 커밋 메시지가 끝나면 newline을 추가했다는 것을 알아 냈다. 왜냐하면 나는 항상 nano을 쓰기 때문에 내 예제 코드에서 마지막 문자를 출력하지 않기 때문이다. 사람이를 읽고 내가 가진 같은 문제가있는 경우

, 여기에 작업 코드는 다음과 같습니다

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <git2.h> 

#define REPO ".git" 

int main(void){ 
    git_repository *repo; 
    if(git_repository_open(&repo, REPO) != GIT_SUCCESS){ 
     fprintf(stderr, "Failed opening repository: '%s'\n", REPO); 
     return 1; 
    } 

    // Read HEAD on master 
    char head_filepath[512]; 
    FILE *head_fileptr; 
    char head_rev[41]; 

    strcpy(head_filepath, REPO); 

    if(strrchr(REPO, '/') != (REPO+strlen(REPO))) 
     strcat(head_filepath, "/refs/heads/master"); 
    else 
     strcat(head_filepath, "refs/heads/master"); 


    if((head_fileptr = fopen(head_filepath, "r")) == NULL){ 
     fprintf(stderr, "Error opening '%s'\n", head_filepath); 
     return 1; 
    } 

    if(fread(head_rev, 40, 1, head_fileptr) != 1){ 
     fprintf(stderr, "Error reading from '%s'\n", head_filepath); 
     fclose(head_fileptr); 
     return 1; 
    } 

    fclose(head_fileptr); 


    git_oid oid; 
    git_revwalk *walker; 
    git_commit *commit; 

    if(git_oid_fromstr(&oid, head_rev) != GIT_SUCCESS){ 
     fprintf(stderr, "Invalid git object: '%s'\n", head_rev); 
     return 1; 
    } 

    git_revwalk_new(&walker, repo); 
    git_revwalk_sorting(walker, GIT_SORT_TOPOLOGICAL); 
    git_revwalk_push(walker, &oid); 

    const char *commit_message; 
    const git_signature *commit_author; 

    while(git_revwalk_next(&oid, walker) == GIT_SUCCESS) { 
     if(git_commit_lookup(&commit, repo, &oid)){ 
      fprintf(stderr, "Failed to lookup the next object\n"); 
      return 1; 
     } 

     commit_message = git_commit_message(commit); 
     commit_author = git_commit_committer(commit); 

     // Don't print the \n in the commit_message 
     printf("'%.*s' by %s <%s>\n", strlen(commit_message)-1, commit_message, commit_author->name, commit_author->email); 

     git_commit_free(commit); 
    } 

    git_revwalk_free(walker); 

    return 0; 

} 

감사합니다!

+2

안녕하세요. 저는이 목록을 찾았습니다. 정확히 똑같은 문제가있어 큰 감사하다고 말하고 싶습니다. 좋은 사람, 공유 주셔서 감사합니다! –

+0

듣기 좋아요. 여전히 작동합니다. 이 문제가 해결 된 후에 나는 C.libgit2가 어쨌든 몇 가지 API를 변경했기 때문에 다른 언어로 제 물건을 구현하려고 시도 했었고 실제로 몇 가지 기본적인 것들이 변경됨에 따라 그 사실을 알고 있어야했습니다. 또한 나는이 시간에 도서관이 매우 개발자 친화적이지 않았다고 생각합니다. 다행스럽게도 당신을 도울 수있었습니다! – pentix

+0

안녕하세요, 당신이 잘하고 있기를 바랍니다. 나는 보행 보조기가 가지에서 걸어서 나가는 것을 관찰했다. A를 다시 주인에게 말하자. 즉, 하나의 고리에 나열 될 것이고, 지점 A와 주인에게서 커밋된다. 지점 A에서만 커밋을 표시하는 방법이 있습니까? 고맙습니다. –

3

나는 그것이 아무튼 코드 이미 다음 비트를했지만, 컴파일하지 않음

git_commit은 불투명 한 유형입니다. 즉, 컴파일러는 내용이 무엇인지 모르고 존재한다는 것을 의미합니다. 따라서 스택에 git_commit을 할당 할 수 없습니다. 라이브러리는 그것을 힙에 할당합니다.

its documentation과 예 : links to에서 볼 수 있듯이 코드에서 포인터를 사용하여 포인터를 라이브러리의 함수에 전달해야합니다.

루트 커밋부터 모든 커밋을 빠르게 처리 할 수 ​​있습니까? 다른 도보 전략을 보여주는

revwalk tests

는 도움을 제공 할 수 있습니다.

+0

예제의 모든 헤더를 사용하여 여전히 컴파일되지 않습니다. 컴파일러 플래그는'-lgit2'입니다. 그렇지 않습니까? – pentix

+0

* 여전히 컴파일되지 않습니다 * -> 오류 메시지를 제공하는 것이 독자에게 상당히 도움이 될 수 있다고 확신합니다. – nulltoken

+0

헤더가 문제가되지 않을 것입니다. 사용하지 않거나 사용하지 않는 것입니다. 포인터. 새로운 코드로 답변을 업데이트한다면 아마도 도움이 될 것입니다. –

0

위의 펜탁스의 답변에 추가하십시오.당신은 단지로 워커를 초기화 머리에 이전을 얻기 위해 '도보'머리 대신 모든 일을하려는 경우

git_revwalk_push(walker, &oid); 

하나는 간단하게 사용할 수 있습니다

git_revwalk_push_head(walker); 
관련 문제