Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Get list of tags of remote repository without cloning using libgit2

Using this git command I can get all of the available tags of a remote repository without having to clone it:

git ls-remote --tags https://github.com/blender/blender.git

I want to replicate this using libgit2.

I can use git_tag_list (https://libgit2.org/libgit2/#HEAD/group/tag/git_tag_list) to get a list of tags, but it requires a git_repository object. I can use git_repository_open to create a git_repository object, but that only works if the repository has been cloned and exists locally on the disk. I can’t seem to find any way to create a git_repository object using a remote repository URL.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The libgit2 examples have an implementation for the ls-remote command, so it must be possible somehow:

static int use_remote(git_repository *repo, char *name)
{
    git_remote *remote = NULL;
    int error;
    const git_remote_head **refs;
    size_t refs_len, i;
    git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

    /* Find the remote by name */
    error = git_remote_lookup(&remote, repo, name);
    if (error < 0) {
        error = git_remote_create_anonymous(&remote, repo, name);
        if (error < 0)
            goto cleanup;
    }

    /**
     * Connect to the remote and call the printing function for
     * each of the remote references.
     */
    callbacks.credentials = cred_acquire_cb;

    error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL, NULL);
    if (error < 0)
        goto cleanup;

    /**
     * Get the list of references on the remote and print out
     * their name next to what they point to.
     */
    if (git_remote_ls(&refs, &refs_len, remote) < 0)
        goto cleanup;

    for (i = 0; i < refs_len; i++) {
        char oid[GIT_OID_SHA1_HEXSIZE + 1] = {0};
        git_oid_fmt(oid, &refs[i]->oid);
        printf("%s\t%s\n", oid, refs[i]->name);
    }

cleanup:
    git_remote_free(remote);
    return error;
}

/** Entry point for this command */
int lg2_ls_remote(git_repository *repo, int argc, char **argv)
{
    int error;

    if (argc < 2) {
        fprintf(stderr, "usage: %s ls-remote <remote>\n", argv[-1]);
        return EXIT_FAILURE;
    }

    error = use_remote(repo, argv[1]);

    return error;
}

(https://github.com/libgit2/libgit2/blob/ac0f2245510f6c75db1b1e7af7ca01c15dec26bc/examples/ls-remote.c)

Unfortunately this command also requires a git_repository object, so I’m at a bit of a loss. Is this currently not possible without cloning first?

>Solution :

You can utilize git_remote_create_anonymous() to create a remote object and fetch the tag list without cloning the repository locally.

Here is a sample code:

#include <git2.h>
#include <iostream>
#include <string>

int main() {
    // Initialize the libgit2 library
    git_libgit2_init();

    git_remote *remote = nullptr;
    const char *url = "https://github.com/libgit2/libgit2.git";

    // Create an anonymous remote object with the specified URL
    git_remote_create_anonymous(&remote, nullptr, url);

    // Initialize the remote callbacks structure
    git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

    // Connect to the remote repository
    git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, nullptr, nullptr);

    const git_remote_head **refs;
    size_t refs_len;

    // Get the list of remote references
    git_remote_ls(&refs, &refs_len, remote);

    // Iterate through the references and print the tags
    for (size_t i = 0; i < refs_len; ++i) {
        std::string ref_name(refs[i]->name);
        if (ref_name.find("refs/tags/") == 0) {
            std::cout << "Tag: " << ref_name.substr(10) << std::endl;
        }
    }

    // Free the resources and shut down the libgit2 library
    git_remote_free(remote);
    git_libgit2_shutdown();

    return 0;
}

This code will help you obtain the tag list of a remote repository without the need to clone it locally. Please note that this code retrieves tags only for publicly accessible repositories, as we’re not providing an authentication function.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading