2013-07-29 51 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報道:

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 

我與-lgit2標誌編譯。從根提交開始,是否可以快速完成所有提交?

更新 新的代碼如下所示:

#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創建了一個工作版本。 CarlosMartínNieto指出了正確的方向,下面的例子對libgit2 0.16有效。我花了一些時間來研究我在github的libgit2-examples存儲庫中找到的general.cgit revwalk正是我所期待的。

我注意到git在我的提交消息的末尾添加了一個換行符,可能是因爲我總是使用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

我已經下面的代碼位,但它不編譯

A 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); 
相關問題