如何使用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;
}
海湾合作委员会报告:
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
标志编译。从root-commit开始,是否有可能快速完成所有提交?
更新 新代码如下所示:
#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'
答案 0 :(得分:3)
我已经有了以下一些代码,但它没有编译
git_commit
是一种opaque类型,这意味着您的编译器不知道它是什么,只知道它存在。因此,您无法在堆栈上分配git_commit
。库会为你在堆上分配它。
您必须在代码中使用指针并将指针传递给库的函数,如its documentation及其示例links to中所示。
从root-commit开始,是否有可能快速完成所有提交?
那些 revwalk tests ,展示不同的步行策略,可能会为您提供一些帮助。
答案 1 :(得分:3)
最后,我使用libgit2创建了一个工作版本。 CarlosMartínNieto指出了正确的方向,以下示例适用于libgit2 0.16 。我花了一些时间研究general.c在github上的libgit2-examples存储库中找到的{{3}}。 git revwalk 正是我所寻找的。 p>
我注意到git在我的提交消息末尾添加了一个换行符,可能是因为我总是使用nano
来编写它们,所以我不打印出示例代码中的最后一个字符。 / p>
如果有人读到这个并且遇到了和我一样的问题,那么这就是工作代码:
#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)
在上面添加Pentax的答案。如果你只是想走路&#39;头部,而不是做所有的工作,让老头到头来初始化助行器:
git_revwalk_push(walker, &oid);
可以简单地使用:
git_revwalk_push_head(walker);