Beispiel #1
0
static int check_remote_status(git_repository *repo, git_remote *origin, const char *branch, enum remote_transport rt)
{
	int error = 0;

	git_reference *local_ref, *remote_ref;

	if (git_branch_lookup(&local_ref, repo, branch, GIT_BRANCH_LOCAL))
		return report_error("Git cache branch %s no longer exists", branch);

	if (git_branch_upstream(&remote_ref, local_ref)) {
		/* so there is no upstream branch for our branch; that's a problem.
		 * let's push our branch */
		git_strarray refspec;
		git_reference_list(&refspec, repo);
#if USE_LIBGIT23_API
		git_push_options opts = GIT_PUSH_OPTIONS_INIT;
		if (rt == RT_SSH)
			opts.callbacks.credentials = credential_ssh_cb;
		else if (rt == RT_HTTPS)
			opts.callbacks.credentials = credential_https_cb;
		opts.callbacks.certificate_check = certificate_check_cb;
		error = git_remote_push(origin, &refspec, &opts);
#else
		error = git_remote_push(origin, &refspec, NULL);
#endif
	} else {
		error = try_to_update(repo, origin, local_ref, remote_ref, rt);
		git_reference_free(remote_ref);
	}
	git_reference_free(local_ref);
	return error;
}
Beispiel #2
0
void test_network_remote_local__push_delete(void)
{
    git_repository *src_repo;
    git_repository *dst_repo;
    git_remote *remote;
    git_reference *ref;
    char *spec_push[] = { "refs/heads/master" };
    char *spec_delete[] = { ":refs/heads/master" };
    git_strarray specs = {
        spec_push,
        1,
    };

    src_repo = cl_git_sandbox_init("testrepo.git");
    cl_git_pass(git_repository_init(&dst_repo, "target.git", 1));

    cl_git_pass(git_remote_create(&remote, src_repo, "origin", "./target.git"));

    /* Push the master branch and verify it's there */
    cl_git_pass(git_remote_push(remote, &specs, NULL));
    cl_git_pass(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
    git_reference_free(ref);

    specs.strings = spec_delete;
    cl_git_pass(git_remote_push(remote, &specs, NULL));
    cl_git_fail(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));

    git_remote_free(remote);
    git_repository_free(dst_repo);
    cl_fixture_cleanup("target.git");
    cl_git_sandbox_cleanup();
}
Beispiel #3
0
void QGit::push()
{
    git_repository *repo = nullptr;
    git_remote *remote = nullptr;
    int res = 0;

    QGitError error;

    try {

        res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData());
        if (res)
        {
            throw QGitError("git_repository_open", res);
        }

        res = git_remote_lookup(&remote, repo, "origin");
        if (res)
        {
            throw QGitError("git_remote_lookup", res);
        }

#if LIBGIT2_SOVERSION > 22
        res = git_remote_push(remote, nullptr, nullptr);
#else
        res = git_remote_push(remote, nullptr, nullptr, nullptr, "push");
#endif
        if (res)
        {
            throw QGitError("git_remote_push", res);
        }

    } catch(const QGitError &ex) {
        error = ex;
    }

    emit pushReply(error);

    if (remote)
    {
        git_remote_free(remote);
        remote = nullptr;
    }

    if (repo)
    {
        git_repository_free(repo);
        repo = nullptr;
    }
}
Beispiel #4
0
static int update_remote(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt)
{
	UNUSED(repo);
	UNUSED(remote);

	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
	git_strarray refspec;
	const char *name = git_reference_name(local);

	if (verbose)
		fprintf(stderr, "git storage: update remote\n");

	refspec.count = 1;
	refspec.strings = (char **)&name;

	auth_attempt = 0;
	opts.callbacks.push_transfer_progress = &push_transfer_progress_cb;
	if (rt == RT_SSH)
		opts.callbacks.credentials = credential_ssh_cb;
	else if (rt == RT_HTTPS)
		opts.callbacks.credentials = credential_https_cb;
	opts.callbacks.certificate_check = certificate_check_cb;

	if (git_remote_push(origin, &refspec, &opts)) {
		if (is_subsurface_cloud)
			return report_error(translate("gettextFromC", "Could not update Subsurface cloud storage, try again later"));
		else
			return report_error("Unable to update remote with current local cache state (%s)", giterr_last()->message);
	}
	return 0;
}
Beispiel #5
0
/*
 *  call-seq:
 *    remote.push(refspecs = nil, options = {}) -> hash
 *
 *  Pushes the given +refspecs+ to the given +remote+. Returns a hash that contains
 *  key-value pairs that reflect pushed refs and error messages, if applicable.
 *
 *  You can optionally pass in an alternative list of +refspecs+ to use instead of the push
 *  refspecs already configured for +remote+.
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :credentials ::
 *    The credentials to use for the push operation. Can be either an instance of one
 *    of the Rugged::Credentials types, or a proc returning one of the former.
 *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
 *    a list of applicable credential types.
 *
 *  :update_tips ::
 *    A callback that will be executed each time a reference is updated remotely. It will be
 *    passed the +refname+, +old_oid+ and +new_oid+.
 *
 *  Example:
 *
 *    remote = Rugged::Remote.lookup(@repo, 'origin')
 *    remote.push(["refs/heads/master", ":refs/heads/to_be_deleted"])
 */
static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
{
	VALUE rb_refspecs, rb_options;

	git_remote *remote;
	git_strarray refspecs;
	git_push_options opts = GIT_PUSH_OPTIONS_INIT;

	int error = 0;

	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };

	rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);

	rugged_rb_ary_to_strarray(rb_refspecs, &refspecs);

	Data_Get_Struct(self, git_remote, remote);

	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &opts.callbacks, &payload);

	error = git_remote_push(remote, &refspecs, &opts);

	xfree(refspecs.strings);

	if (payload.exception)
		rb_jump_tag(payload.exception);

	rugged_exception_check(error);

	return payload.result;
}
Beispiel #6
0
void test_network_remote_local__update_tips_for_new_remote(void) {
    git_repository *src_repo;
    git_repository *dst_repo;
    git_remote *new_remote;
    git_reference* branch;

    /* Copy test repo */
    cl_fixture_sandbox("testrepo.git");
    cl_git_pass(git_repository_open(&src_repo, "testrepo.git"));

    /* Set up an empty bare repo to push into */
    cl_git_pass(git_repository_init(&dst_repo, "./localbare.git", 1));

    /* Push to bare repo */
    cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git"));
    cl_git_pass(git_remote_push(new_remote, &push_array, NULL));
    /* Make sure remote branch has been created */
    cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE));

    git_reference_free(branch);
    git_remote_free(new_remote);
    git_repository_free(dst_repo);
    cl_fixture_cleanup("localbare.git");
    git_repository_free(src_repo);
    cl_fixture_cleanup("testrepo.git");
}
Beispiel #7
0
int main()
{
    git_libgit2_init();

    git_repository* rep = nullptr;

    git_remote* remote = nullptr;
    git_push_options opts = GIT_PUSH_OPTIONS_INIT;

    int error = 0;

    // git open
    git_repository_open(&rep, path);

    // take remote
    git_remote_lookup(&remote, rep, "origin");

    const char *refs[] = {"refs/heads/master:refs/heads/master"};
    git_strarray strarr = {(char**)refs, 1};

    opts.callbacks.credentials = cred_acquire_cb;
    error = git_remote_push(remote, &strarr, &opts);
    if (error < 0)
    {
        const git_error *e = giterr_last();
        std::cout << "Error: " << error << " / " << e->klass << " : " << e->message << std::endl;

        goto SHUTDOWN;
    }

SHUTDOWN:
    git_repository_free(rep);
    git_libgit2_shutdown();
}
Beispiel #8
0
/**
 * ggit_remote_push:
 * @remote: a #GgitRemote.
 * @specs: (array zero-terminated=1) (allow-none): the ref specs.
 * @push_options: a #GgitPushOptions.
 * @error: a #GError for error reporting, or %NULL.
 *
 * Connect to the remote if not yet connected, negotiate with the remote
 * about which objects are missing, create a packfile with the missing
 * objects and send it.
 *
 * Returns: %TRUE if successful, %FALSE otherwise.
 */
gboolean
ggit_remote_push (GgitRemote          *remote,
                  const gchar * const *specs,
                  GgitPushOptions     *push_options,
                  GError             **error)
{
	gint ret;
	git_strarray gspecs;

	g_return_val_if_fail (GGIT_IS_REMOTE (remote), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	ggit_utils_get_git_strarray_from_str_array (specs, &gspecs);

	ret = git_remote_push (_ggit_native_get (remote), &gspecs,
	                       _ggit_push_options_get_push_options (push_options));

	if (ret != GIT_OK)
	{
		_ggit_error_set (error, ret);
		return FALSE;
	}

	return TRUE;
}
Beispiel #9
0
/**
 * Pushes the master branch to the server.
 */
int sync_push(git_repository *repo,
              const char *server)
{
    int e = 0;
    git_remote *remote = NULL;
    git_push_options options = GIT_PUSH_OPTIONS_INIT;
    char *refspec[] = {SYNC_PUSH_REFSPEC};
    git_strarray refspecs = {refspec, 1};

    git_check(git_remote_create_anonymous(&remote, repo, server));
    git_check(git_remote_push(remote, &refspecs, &options));

exit:
    if (remote)     git_remote_free(remote);
    return e;
}
Beispiel #10
0
static int update_remote(git_repository *repo, git_remote *origin, git_reference *local, git_reference *remote, enum remote_transport rt)
{
	git_push_options opts = GIT_PUSH_OPTIONS_INIT;
	git_strarray refspec;
	const char *name = git_reference_name(local);

	refspec.count = 1;
	refspec.strings = (char **)&name;

#if USE_LIBGIT23_API
	if (rt == RT_SSH)
		opts.callbacks.credentials = credential_ssh_cb;
	else if (rt == RT_HTTPS)
		opts.callbacks.credentials = credential_https_cb;
	opts.callbacks.certificate_check = certificate_check_cb;
#endif
	if (git_remote_push(origin, &refspec, &opts))
		return report_error("Unable to update remote with current local cache state (%s)", giterr_last()->message);

	return 0;
}
Beispiel #11
0
/*
 *  call-seq:
 *    remote.push(refspecs = nil, options = {}) -> hash
 *
 *  Pushes the given +refspecs+ to the given +remote+. Returns a hash that contains
 *  key-value pairs that reflect pushed refs and error messages, if applicable.
 *
 *  You can optionally pass in an alternative list of +refspecs+ to use instead of the push
 *  refspecs already configured for +remote+.
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :credentials ::
 *    The credentials to use for the push operation. Can be either an instance of one
 *    of the Rugged::Credentials types, or a proc returning one of the former.
 *    The proc will be called with the +url+, the +username+ from the url (if applicable) and
 *    a list of applicable credential types.
 *
 *  :update_tips ::
 *    A callback that will be executed each time a reference is updated remotely. It will be
 *    passed the +refname+, +old_oid+ and +new_oid+.
 *
 *  Example:
 *
 *    remote = Rugged::Remote.lookup(@repo, 'origin')
 *    remote.push(["refs/heads/master", ":refs/heads/to_be_deleted"])
 */
static VALUE rb_git_remote_push(int argc, VALUE *argv, VALUE self)
{
	VALUE rb_refspecs, rb_options;
	VALUE rb_repo = rugged_owner(self);

	git_repository *repo;
	git_remote *remote;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	git_strarray refspecs;
	git_push_options opts = GIT_PUSH_OPTIONS_INIT;

	int error = 0;

	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, rb_hash_new(), 0 };

	rb_scan_args(argc, argv, "01:", &rb_refspecs, &rb_options);

	rugged_rb_ary_to_strarray(rb_refspecs, &refspecs);

	rugged_check_repo(rb_repo);
	Data_Get_Struct(rb_repo, git_repository, repo);
	Data_Get_Struct(self, git_remote, remote);

	rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);

	if ((error = git_remote_set_callbacks(remote, &callbacks)))
	    goto cleanup;

	error = git_remote_push(remote, &refspecs, &opts);

cleanup:
	xfree(refspecs.strings);

	if (payload.exception)
		rb_jump_tag(payload.exception);

	rugged_exception_check(error);

	return payload.result;
}
Beispiel #12
0
static int check_remote_status(git_repository *repo, git_remote *origin, const char *remote, const char *branch, enum remote_transport rt)
{
	int error = 0;

	git_reference *local_ref, *remote_ref;

	if (verbose)
		fprintf(stderr, "git storage: check remote status\n");

	if (git_branch_lookup(&local_ref, repo, branch, GIT_BRANCH_LOCAL)) {
		if (is_subsurface_cloud)
			return cleanup_local_cache(remote, branch);
		else
			return report_error("Git cache branch %s no longer exists", branch);
	}
	if (git_branch_upstream(&remote_ref, local_ref)) {
		/* so there is no upstream branch for our branch; that's a problem.
		 * let's push our branch */
		git_strarray refspec;
		git_reference_list(&refspec, repo);
		git_push_options opts = GIT_PUSH_OPTIONS_INIT;
		opts.callbacks.transfer_progress = &transfer_progress_cb;
		auth_attempt = 0;
		if (rt == RT_SSH)
			opts.callbacks.credentials = credential_ssh_cb;
		else if (rt == RT_HTTPS)
			opts.callbacks.credentials = credential_https_cb;
		opts.callbacks.certificate_check = certificate_check_cb;
		git_storage_update_progress(translate("gettextFromC", "Store data into cloud storage"));
		error = git_remote_push(origin, &refspec, &opts);
	} else {
		error = try_to_update(repo, origin, local_ref, remote_ref, remote, branch, rt);
		git_reference_free(remote_ref);
	}
	git_reference_free(local_ref);
	return error;
}
Beispiel #13
0
emacs_value egit_remote_push(emacs_env *env, emacs_value _remote, emacs_value _refspecs, emacs_value opts)
{
    EGIT_ASSERT_REMOTE(_remote);

    git_strarray refspecs;
    if (!egit_strarray_from_list(&refspecs, env, _refspecs))
        return em_nil;

    git_push_options options;
    egit_push_options_parse(env, opts, &options);
    if (env->non_local_exit_check(env)) {
        egit_strarray_dispose(&refspecs);
        return em_nil;
    }

    git_remote *remote = EGIT_EXTRACT(_remote);
    int retval = git_remote_push(remote, &refspecs, &options);

    egit_strarray_dispose(&refspecs);
    egit_push_options_release(&options);

    EGIT_CHECK_ERROR(retval);
    return em_nil;
}
Beispiel #14
0
int cmd_push(git_repository *repo, int argc, char **argv)
{
	int err = GIT_OK;
	int i;
	int rc = EXIT_FAILURE;
	git_strarray refs = {NULL, 0};
	git_push_options push_options = GIT_PUSH_OPTIONS_INIT;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	char *ref_fullname = NULL;

	git_remote *r = NULL;

	for (i=1;i<argc;i++)
	{
		if (argv[i][0] == '-')
		{
			fprintf(stderr,"Unknown option \"%s\"\n",argv[i]);
			goto out;
		}

		if (r)
		{
			git_reference *ref;

			if (refs.count) {
				fprintf(stderr, "USAGE: %s <remote> <refspec>\n", argv[0]);
				goto out;
			}

			if (!git_reference_dwim(&ref, repo, argv[i]))
			{
				ref_fullname = strdup(git_reference_name(ref));
				refs.strings = &ref_fullname;
				git_reference_free(ref);
			} else
			{
				refs.strings = &argv[i];
			}
			refs.count = 1;
		} else
		{
			if ((err = git_remote_lookup(&r,repo,argv[i])) != GIT_OK)
				goto out;
		}
	}

	if (!r)
	{
		fprintf(stderr,"No remote given!\n");
		goto out;
	}

	if (refs.count == 0)
	{
		git_strarray cfg_refs;

		if ((err = git_remote_get_push_refspecs(&cfg_refs, r)))
			goto out;

		if (!cfg_refs.count)
		{
			fprintf(stderr, "No refspec given and no refspec configured. "
					"Pushing is probably a noop.\n");
		}
		git_strarray_free(&cfg_refs);
	}
	callbacks.credentials = cred_acquire_cb;
	callbacks.push_update_reference = push_update_reference_callback;
	callbacks.certificate_check = certificate_check;
	push_options.callbacks = callbacks;

	if ((err = git_remote_push(r, &refs, &push_options)))
		goto out;

out:
	if (err != GIT_OK)
		libgit_error();
	free(ref_fullname);
	if (r) git_remote_free(r);
	return rc;
}