简体   繁体   中英

How to write a proper git pull with libgit2

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:

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.

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM