How to write a proper git pull with libgit2

感情迁移 提交于 2019-12-24 07:50:06

问题


I want to write a C++ libgit2 wrapper to perform some basic git operations because libgit2 is too much atomic to be used as is (in my opinion).
As libgit2 is written in C, it does not matter if I get a C or C++ oriented solution, I will adapt it by myself.

I encounter difficulties with the gitPull() function that is supposed to be the "git pull" equivalent.

I planned to implement it as follows:

  • git_remote_fetch()
  • git_annotated_commit_from_fetchhead()
  • git_merge() (with the previously got git_annotated_commit)
  • git_commit_create()

Considering that it is the proper way to do it (tell me if it is not), I struggle with two issues:

  • How to check if the fetched HEAD is equal or different to the local HEAD ? (in order to know if the merge + commit are needed or not, in other words, if there is something to merge or if we already are up-to-date).
  • How or where to get the git_oid * id required by git_annotated_commit_from_fetchhead() ? (the last parameter).

I know these questions may look quite basic but I could not find any exploitable information or example neither on the libgit2 API reference documentation nor in the libgit2 samples.

I already have checked the already existing stackoverflow threads about this topic but none of them provide any exploitable code sample.

I will be very grateful if someone could give me some helpful information about how to achieve it or explain what I have misunderstood.


回答1:


How to check if the fetched HEAD is equal or different to the local HEAD ?

You can call git_merge_analysis, which will tell you if you would need to do a merge. In this case, GIT_MERGE_ANALYSIS_UP_TO_DATE indicates that there is no need to merge (git merge on the command line would respond with "Already up to date").

How or where to get the git_oid * id required by git_annotated_commit_from_fetchhead()?

You can iterate the FETCH_HEAD file with git_repository_fetchhead_foreach. It will provide you all the information necessary to generate an annotated commit from whichever remote branch you want to merge.

For example:

int fetchhead_cb(const char *ref_name, const char *remote_url, const git_oid *oid, unsigned int is_merge, void *payload)
{
    if (is_merge)
    {
        printf("reference: '%s' is the reference we should merge\n");
        git_oid_cpy((git_oid *)payload, oid);
    }
}

void pull(void)
{
    /* here's the id we want to merge */
    git_oid id_to_merge;

    /* Do the fetch */

    /* Populate id with the for_merge branch from FETCH_HEAD */
    git_repository_fetchhead_foreach(repo, fetchhead_cb, &id_to_merge);
}

(Note that you'd probably want to actually capture all the details of the FETCH_HEAD information - not just the id - so that you could create an annotated commit from the data, but this is an example of how the git_repository_fetchhead_foreach function works with callbacks.)



来源:https://stackoverflow.com/questions/57791388/how-to-write-a-proper-git-pull-with-libgit2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!