コード例 #1
0
ファイル: git2r_arg.c プロジェクト: wanghaiquan/git2r
/**
 * Check string argument
 *
 * Compared to git2r_arg_check_string_vec, also checks that length of vector
 * is one and non-NA.
 * @param arg the arg to check
 * @return 0 if OK, else 1
 */
int git2r_arg_check_string(SEXP arg)
{
    if (git2r_arg_check_string_vec(arg))
        return 1;
    if (1 != length(arg) || NA_STRING == STRING_ELT(arg, 0))
        return 1;
    return 0;
}
コード例 #2
0
ファイル: git2r_arg.c プロジェクト: wanghaiquan/git2r
/**
 * Check credentials argument
 *
 * @param arg the arg to check
 * @return 0 if OK, else 1
 */
int git2r_arg_check_credentials(SEXP arg)
{
    SEXP class_name;

    /* It's ok if the credentials is R_NilValue */
    if (R_NilValue == arg)
        return 0;

    if (S4SXP != TYPEOF(arg))
        return 1;

    class_name = getAttrib(arg, R_ClassSymbol);
    if (0 == strcmp(CHAR(STRING_ELT(class_name, 0)), "cred_plaintext")) {
        /* Check username and password */
        if (git2r_arg_check_string(GET_SLOT(arg, Rf_install("username")))
            || git2r_arg_check_string(GET_SLOT(arg, Rf_install("password"))))
            return 1;
    } else if (0 == strcmp(CHAR(STRING_ELT(class_name, 0)), "cred_ssh_key")) {
        SEXP passphrase;

        /* Check public and private key */
        if (git2r_arg_check_string(GET_SLOT(arg, Rf_install("publickey")))
            || git2r_arg_check_string(GET_SLOT(arg, Rf_install("privatekey"))))
            return 1;

        /* Check that passphrase is a character vector */
        passphrase = GET_SLOT(arg, Rf_install("passphrase"));
        if (git2r_arg_check_string_vec(passphrase))
            return 1;

        /* Check that length of passphrase < 2, i.e. it's either
         * character(0) or some "passphrase" */
        switch (length(passphrase)) {
        case 0:
            break;
        case 1:
            if (NA_STRING == STRING_ELT(passphrase, 0))
                return 1;
            break;
        default:
            return 1;
        }
    } else {
        return 1;
    }

    return 0;
}
コード例 #3
0
ファイル: git2r_remote.c プロジェクト: jennybc/git2r
/**
 * Get the remote's url
 *
 * @param repo S4 class git_repository
 * @param remote Character vector with name of remote. NA values are
 * ok and give NA values as result at corresponding index in url
 * vector
 * @return Character vector with url for each remote
 */
SEXP git2r_remote_url(SEXP repo, SEXP remote)
{
    int err = GIT_OK;
    SEXP url;
    size_t len;
    size_t i = 0;
    git_remote *tmp_remote;
    git_repository *repository = NULL;

    if (git2r_arg_check_string_vec(remote))
        git2r_error(__func__, NULL, "'remote'", git2r_err_string_vec_arg);

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

    len = LENGTH(remote);
    PROTECT(url = allocVector(STRSXP, len));

    for (; i < len; i++) {
        if (NA_STRING == STRING_ELT(remote, i)) {
            SET_STRING_ELT(url, i, NA_STRING);
        } else {
            err = git_remote_lookup(
                &tmp_remote,
                repository,
                CHAR(STRING_ELT(remote, i)));
            if (err)
                goto cleanup;

            SET_STRING_ELT(url, i, mkChar(git_remote_url(tmp_remote)));
            git_remote_free(tmp_remote);
        }
    }

cleanup:
    if (repository)
        git_repository_free(repository);

    UNPROTECT(1);

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

    return url;
}
コード例 #4
0
ファイル: git2r_reset.c プロジェクト: ropensci/git2r
/**
 * Updates some entries in the index from the HEAD commit tree.
 *
 * @param repo S3 class git_repository
 * @param path The paths to reset
 * @return R_NilValue
 */
SEXP git2r_reset_default(SEXP repo, SEXP path)
{
    int error = 0;
    git_strarray pathspec = {0};
    git_reference *head = NULL;
    git_object *head_commit = NULL;
    git_repository *repository = NULL;

    if (git2r_arg_check_string_vec(path))
        git2r_error(__func__, NULL, "'path'", git2r_err_string_vec_arg);

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

    error = git2r_copy_string_vec(&pathspec, path);
    if (error || !pathspec.count)
        goto cleanup;

    error = git_repository_head(&head, repository);
    if (error)
        goto cleanup;

    error = git_reference_peel(&head_commit, head, GIT2R_OBJECT_COMMIT);
    if (error)
        goto cleanup;

    error = git_reset_default(repository, head_commit, &pathspec);

cleanup:
    git_reference_free(head);
    git_object_free(head_commit);
    free(pathspec.strings);
    git_repository_free(repository);

    if (error)
        git2r_error(__func__, GIT2R_ERROR_LAST(), NULL, NULL);

    return R_NilValue;
}
コード例 #5
0
ファイル: git2r_remote.c プロジェクト: jennybc/git2r
/**
 * Fetch new data and update tips
 *
 * @param repo S4 class git_repository
 * @param name The name of the remote to fetch from
 * @param credentials The credentials for remote repository access.
 * @param msg The one line long message to be appended to the reflog
 * @param verbose Print information each time a reference is updated locally.
 * @param refspecs The refspecs to use for this fetch. Pass R_NilValue
 *        to use the base refspecs.
 * @return R_NilValue
 */
SEXP git2r_remote_fetch(
    SEXP repo,
    SEXP name,
    SEXP credentials,
    SEXP msg,
    SEXP verbose,
    SEXP refspecs)
{
    int err;
    SEXP result = R_NilValue;
    const git_transfer_progress *stats;
    git_remote *remote = NULL;
    git_repository *repository = NULL;
    git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
    git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT;
    git_strarray refs = {0};

    if (git2r_arg_check_string(name))
        git2r_error(__func__, NULL, "'name'", git2r_err_string_arg);
    if (git2r_arg_check_credentials(credentials))
        git2r_error(__func__, NULL, "'credentials'", git2r_err_credentials_arg);
    if (git2r_arg_check_string(msg))
        git2r_error(__func__, NULL, "'msg'", git2r_err_string_arg);
    if (git2r_arg_check_logical(verbose))
        git2r_error(__func__, NULL, "'verbose'", git2r_err_logical_arg);
    if (refspecs != R_NilValue && git2r_arg_check_string_vec(refspecs))
        git2r_error(__func__, NULL, "'refspecs'", git2r_err_string_vec_arg);

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

    err = git_remote_lookup(&remote, repository, CHAR(STRING_ELT(name, 0)));
    if (err)
        goto cleanup;

    if (refspecs != R_NilValue) {
        size_t i, len;

        /* Count number of non NA values */
        len = length(refspecs);
        for (i = 0; i < len; i++)
            if (NA_STRING != STRING_ELT(refspecs, i))
                refs.count++;

        if (refs.count) {
            /* Allocate the strings in refs */
            refs.strings = malloc(refs.count * sizeof(char*));
            if (!refs.strings) {
                giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer);
                err = GIT_ERROR;
                goto cleanup;
            }

            /* Populate the strings in refs */
            for (i = 0; i < refs.count; i++)
                if (NA_STRING != STRING_ELT(refspecs, i))
                    refs.strings[i] = (char *)CHAR(STRING_ELT(refspecs, i));
        }
    }

    if (LOGICAL(verbose)[0])
        payload.verbose = 1;
    payload.credentials = credentials;
    fetch_opts.callbacks.payload = &payload;
    fetch_opts.callbacks.credentials = &git2r_cred_acquire_cb;
    fetch_opts.callbacks.update_tips = &git2r_update_tips_cb;
    err = git_remote_fetch(remote, &refs, &fetch_opts, CHAR(STRING_ELT(msg, 0)));
    if (err)
        goto cleanup;

    stats = git_remote_stats(remote);
    PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_transfer_progress")));
    git2r_transfer_progress_init(stats, result);

cleanup:
    if (refs.strings)
        free(refs.strings);

    if (remote) {
        if (git_remote_connected(remote))
            git_remote_disconnect(remote);
        git_remote_free(remote);
    }

    if (repository)
        git_repository_free(repository);

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

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

    return result;
}