Exemple #1
0
/**
 * Lookup an object in a repository
 *
 * @param repo S4 class git_repository
 * @param hex 4 to 40 char hexadecimal string
 * @return S4 object with lookup
 */
SEXP git2r_object_lookup(SEXP repo, SEXP hex)
{
    int err;
    size_t len;
    SEXP result = R_NilValue;
    git_object *object = NULL;
    git_oid oid;
    git_repository *repository = NULL;

    if (git2r_error_check_hex_arg(hex))
        error("Invalid arguments to git2r_object_lookup");

    repository = git2r_repository_open(repo);
    if (!repository)
        error(git2r_err_invalid_repository);

    len = LENGTH(STRING_ELT(hex, 0));
    if (GIT_OID_HEXSZ == len) {
        git_oid_fromstr(&oid, CHAR(STRING_ELT(hex, 0)));
        err = git_object_lookup(&object, repository, &oid, GIT_OBJ_ANY);
        if (err < 0)
            goto cleanup;
    } else {
        git_oid_fromstrn(&oid, CHAR(STRING_ELT(hex, 0)), len);
        err = git_object_lookup_prefix(&object, repository, &oid, len, GIT_OBJ_ANY);
        if (err < 0)
            goto cleanup;
    }

    switch (git_object_type(object)) {
    case GIT_OBJ_COMMIT:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit")));
        git2r_commit_init((git_commit*)object, repo, result);
        break;
    case GIT_OBJ_TREE:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree")));
        git2r_tree_init((git_tree*)object, repo, result);
        break;
    case GIT_OBJ_BLOB:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_blob")));
        git2r_blob_init((git_blob*)object, repo, result);
        break;
    case GIT_OBJ_TAG:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tag")));
        git2r_tag_init((git_tag*)object, repo, result);
        break;
    default:
        error("Unimplemented");
    }

cleanup:
    if (object)
        git_object_free(object);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (err < 0)
        error("Error: %s\n", giterr_last()->message);

    return result;
}
Exemple #2
0
/**
 * Invoked 'callback' for each tag
 *
 * @param name The name of the tag
 * @param oid The id of the tag
 * @param payload Payload data passed to 'git_tag_foreach'
 * @return 0 on success, else error code
 */
static int git2r_tag_foreach_cb(const char *name, git_oid *oid, void *payload)
{
    int err = 0;
    git_object *object = NULL;
    git2r_tag_foreach_cb_data *cb_data = (git2r_tag_foreach_cb_data*)payload;

    /* Check if we have a list to populate */
    if (R_NilValue != cb_data->tags) {
        int skip = 0;
        SEXP item;

        err = git_object_lookup(&object, cb_data->repository, oid, GIT_OBJ_ANY);
        if (err)
            goto cleanup;

        switch (git_object_type(object)) {
        case GIT_OBJ_COMMIT:
            SET_VECTOR_ELT(
                cb_data->tags,
                cb_data->n,
                item = NEW_OBJECT(MAKE_CLASS("git_commit")));
            git2r_commit_init((git_commit*)object, cb_data->repo, item);
            break;
        case GIT_OBJ_TREE:
            SET_VECTOR_ELT(
                cb_data->tags,
                cb_data->n,
                item = NEW_OBJECT(MAKE_CLASS("git_tree")));
            git2r_tree_init((git_tree*)object, cb_data->repo, item);
            break;
        case GIT_OBJ_BLOB:
            SET_VECTOR_ELT(
                cb_data->tags,
                cb_data->n,
                item = NEW_OBJECT(MAKE_CLASS("git_blob")));
            git2r_blob_init((git_blob*)object, cb_data->repo, item);
            break;
        case GIT_OBJ_TAG:
            SET_VECTOR_ELT(
                cb_data->tags,
                cb_data->n,
                item = NEW_OBJECT(MAKE_CLASS("git_tag")));
            git2r_tag_init((git_tag*)object, cb_data->repo, item);
            break;
        default:
            git2r_error(__func__, NULL, git2r_err_object_type, NULL);
        }


        if (git__prefixcmp(name, "refs/tags/") == 0)
            skip = strlen("refs/tags/");
        SET_STRING_ELT(
            getAttrib(cb_data->tags, R_NamesSymbol),
            cb_data->n,
            mkChar(name + skip));

        if (object)
            git_object_free(object);
        object = NULL;
    }

    cb_data->n += 1;

cleanup:
    if (object)
        git_object_free(object);

    return err;
}
Exemple #3
0
/**
 * Create tag targeting HEAD commit in repository.
 *
 * @param repo S4 class git_repository
 * @param name Name for the tag.
 * @param message The tag message.
 * @param tagger The tagger (author) of the tag
 * @return S4 object of class git_tag
 */
SEXP git2r_tag_create(SEXP repo, SEXP name, SEXP message, SEXP tagger)
{
    SEXP result = R_NilValue;
    int err;
    git_oid oid;
    git_repository *repository = NULL;
    git_signature *sig_tagger = NULL;
    git_tag *tag = NULL;
    git_object *target = NULL;

    if (git2r_arg_check_string(name))
        git2r_error(__func__, NULL, "'name'", git2r_err_string_arg);
    if (git2r_arg_check_string(message))
        git2r_error(__func__, NULL, "'message'", git2r_err_string_arg);
    if (git2r_arg_check_signature(tagger))
        git2r_error(__func__, NULL, "'tagger'", git2r_err_signature_arg);

    repository = git2r_repository_open(repo);
    if (!repository)
        git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL);

    err = git2r_signature_from_arg(&sig_tagger, tagger);
    if (err)
        goto cleanup;

    err = git_revparse_single(&target, repository, "HEAD^{commit}");
    if (err)
        goto cleanup;

    err = git_tag_create(
        &oid,
        repository,
        CHAR(STRING_ELT(name, 0)),
        target,
        sig_tagger,
        CHAR(STRING_ELT(message, 0)),
        0);
    if (err)
        goto cleanup;

    err = git_tag_lookup(&tag, repository, &oid);
    if (err)
        goto cleanup;

    PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tag")));
    git2r_tag_init(tag, repo, result);

cleanup:
    if (tag)
        git_tag_free(tag);

    if (sig_tagger)
        git_signature_free(sig_tagger);

    if (target)
        git_object_free(target);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (err)
        git2r_error(__func__, giterr_last(), NULL, NULL);

    return result;
}
Exemple #4
0
/**
 * Find object specified by revision
 *
 * @param repo S4 class git_repository
 * @param revision The revision string, see
 * http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions
 * @return S4 object of class git_commit, git_tag or git_tree.
 */
SEXP git2r_revparse_single(SEXP repo, SEXP revision)
{
    int err;
    SEXP result = R_NilValue;
    git_repository *repository = NULL;
    git_object *treeish = NULL;

    if (git2r_arg_check_string(revision))
        git2r_error(git2r_err_string_arg, __func__, "revision");

    repository = git2r_repository_open(repo);
    if (!repository)
        git2r_error(git2r_err_invalid_repository, __func__, NULL);

    err = git_revparse_single(
        &treeish,
        repository,
        CHAR(STRING_ELT(revision, 0)));
    if (GIT_OK != err)
        goto cleanup;

    switch (git_object_type(treeish)) {
    case GIT_OBJ_COMMIT:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit")));
        git2r_commit_init((git_commit*)treeish, repo, result);
        break;
    case GIT_OBJ_TAG:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tag")));
        git2r_tag_init((git_tag*)treeish, repo, result);
        break;
    case GIT_OBJ_TREE:
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree")));
        git2r_tree_init((git_tree*)treeish, repo, result);
        break;
    default:
        giterr_set_str(GITERR_NONE, git2r_err_revparse_single);
        err = GIT_ERROR;
        break;
    }

cleanup:
    if (treeish)
        git_object_free(treeish);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (GIT_OK != err) {
        if (GIT_ENOTFOUND == err) {
            git2r_error(
                git2r_err_from_libgit2,
                __func__,
                "Requested object could not be found");
        } else {
            git2r_error(
                git2r_err_from_libgit2,
                __func__,
                giterr_last()->message);
        }
    }

    return result;
}