Listing all commits in a branch using libgit2

c, git, libgit2

Solution

Finally, I created a working version using libgit2. Carlos Martín Nieto pointed in the right direction, the following example works great with libgit2 0.16. It took me some time to study the general.c I found in the libgit2-examples repository on github. git revwalk was exactly what I was looking for.

I noted that git adds an newline at the end of my commit messages, probably because I'm always using `nano` to write them, so I don't printf out the last character in my example code.

If anyone reads this and has the same problem as I had, here's the working code:

#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;

}

Thanks!

Problem

How can I walk through all the commits of a branch using libgit2? I have already the following bit of code, but it doesn't compile. ``` #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 reports: ``` 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 compiled with the `-lgit2` flag. Is there a fast possibility to walk through all the commits, beginning from the root-commit? Update The new code looks like this: ``` #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; } ``` I get the following error messages: ``` log.c:11: undefined reference to `git_repository_database' log.c:14: undefined reference to `git_revparse_single' ```

Original source