Example #1
0
static int remote_mirror_cb(git_remote **out, git_repository *repo,
                            const char *name, const char *url, void *payload)
{
    int error;
    git_remote *remote;
    git_remote_callbacks *callbacks = (git_remote_callbacks *) payload;


    if ((error = git_remote_create(&remote, repo, name, url)) < 0)
        return error;

    if ((error = git_remote_set_callbacks(remote, callbacks)) < 0) {
        git_remote_free(remote);
        return error;
    }

    git_remote_clear_refspecs(remote);

    if ((error = git_remote_add_fetch(remote, "+refs/*:refs/*")) < 0) {
        git_remote_free(remote);
        return error;
    }

    *out = remote;
    return 0;
}
Example #2
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;

	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);

	if(fetchspec != NULL) {
		git_remote_clear_refspecs(remote);
		git_remote_add_fetch(remote, fetchspec);
	}

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote));
	cl_git_pass(git_remote_update_tips(remote, NULL, NULL));
	git_remote_disconnect(remote);
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_free(&fetchhead_buf);

	cl_assert(equals);
}
Example #3
0
void test_network_remote_remotes__query_refspecs(void)
{
	git_remote *remote;
	git_strarray array;
	int i;

	cl_git_pass(git_remote_create_with_fetchspec(&remote, _repo, "query", "git://github.com/libgit2/libgit2", NULL));
	git_remote_free(remote);

	for (i = 0; i < 3; i++) {
		cl_git_pass(git_remote_add_fetch(_repo, "query", fetch_refspecs[i]));
		cl_git_pass(git_remote_add_push(_repo, "query", push_refspecs[i]));
	}

	cl_git_pass(git_remote_lookup(&remote, _repo, "query"));

	cl_git_pass(git_remote_get_fetch_refspecs(&array, remote));
	for (i = 0; i < 3; i++) {
		cl_assert_equal_s(fetch_refspecs[i], array.strings[i]);
	}
	git_strarray_free(&array);

	cl_git_pass(git_remote_get_push_refspecs(&array, remote));
	for (i = 0; i < 3; i++) {
		cl_assert_equal_s(push_refspecs[i], array.strings[i]);
	}
	git_strarray_free(&array);

	git_remote_free(remote);
	git_remote_delete(_repo, "test");
}
Example #4
0
emacs_value egit_remote_add_refspec(
    emacs_env *env, emacs_value _repo, emacs_value _name,
    emacs_value _refspec, emacs_value direction)
{
    EGIT_ASSERT_REPOSITORY(_repo);
    EM_ASSERT_STRING(_name);
    EM_ASSERT_STRING(_refspec);

    bool push;
    if (EM_EQ(direction, em_push))
        push = true;
    else if (EM_EQ(direction, em_fetch))
        push = false;
    else {
        em_signal_wrong_value(env, direction);
        return em_nil;
    }

    git_repository *repo = EGIT_EXTRACT(_repo);
    char *name = EM_EXTRACT_STRING(_name);
    char *refspec = EM_EXTRACT_STRING(_refspec);

    int retval = push ? git_remote_add_push(repo, name, refspec) :
                 git_remote_add_fetch(repo, name, refspec);
    free(name);
    free(refspec);
    EGIT_CHECK_ERROR(retval);

    return em_nil;
}
Example #5
0
void test_network_fetchlocal__clone_into_mirror(void)
{
	git_buf path = GIT_BUF_INIT;
	git_repository *repo;
	git_remote *remote;
	git_reference *head;

	cl_git_pass(git_repository_init(&repo, "./foo.git", true));
	cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));

	git_remote_clear_refspecs(remote);
	cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));

	cl_git_pass(git_clone_into(repo, remote, NULL, NULL, NULL));

	cl_git_pass(git_reference_lookup(&head, repo, "HEAD"));
	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));

	git_remote_free(remote);
	git_reference_free(head);
	git_repository_free(repo);
	git_buf_free(&path);
	cl_fixture_cleanup("./foo.git");
}
Example #6
0
void test_online_clone__clone_mirror(void)
{
	git_buf path = GIT_BUF_INIT;
	git_remote *remote;
	git_reference *head;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

	bool fetch_progress_cb_was_called = false;

	cl_git_pass(git_repository_init(&g_repo, "./foo.git", true));
	cl_git_pass(git_remote_create(&remote, g_repo, "origin", LIVE_REPO_URL));

	callbacks.transfer_progress = &fetch_progress;
	callbacks.payload = &fetch_progress_cb_was_called;
	git_remote_set_callbacks(remote, &callbacks);

	git_remote_clear_refspecs(remote);
	cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*"));

	cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, NULL));

	cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
	cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head));
	cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));

	cl_assert_equal_i(true, fetch_progress_cb_was_called);

	git_remote_free(remote);
	git_reference_free(head);
	git_buf_free(&path);
	git_repository_free(g_repo);
	g_repo = NULL;

	cl_fixture_cleanup("./foo.git");
}
Example #7
0
void test_network_remote_remotes__add_fetchspec(void)
{
	size_t size;

	size = git_remote_refspec_count(_remote);

	cl_git_pass(git_remote_add_fetch(_repo, "test", "refs/*:refs/*"));
	size++;

	git_remote_free(_remote);
	cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));

	cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));

	_refspec = git_remote_get_refspec(_remote, size - 1);
	cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
	cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
	cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
	cl_assert_equal_b(_refspec->push, false);

	cl_git_fail_with(GIT_EINVALIDSPEC, git_remote_add_fetch(_repo, "test", "refs/*/foo/*:refs/*"));
}
Example #8
0
PyObject *
Remote_add_fetch(Remote *self, PyObject *args)
{
    git_remote *remote;
    char *refspec = NULL;
    int err = 0;

    if (!PyArg_ParseTuple(args, "s", &refspec))
        return NULL;

    remote = self->remote;
    err = git_remote_add_fetch(remote, refspec);
    if (err < 0)
        return Error_set(err);

    Py_RETURN_NONE;
}
Example #9
0
static VALUE rb_git_remote_add_refspec(VALUE self, VALUE rb_refspec, git_direction direction)
{
	git_remote *remote;
	int error = 0;

	Data_Get_Struct(self, git_remote, remote);

	Check_Type(rb_refspec, T_STRING);

	if (direction == GIT_DIRECTION_FETCH)
		error = git_remote_add_fetch(remote, StringValueCStr(rb_refspec));
	else
		error = git_remote_add_push(remote, StringValueCStr(rb_refspec));

	rugged_exception_check(error);

	return Qnil;
}
Example #10
0
static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
{
	int error;
	git_buf reflog_message = GIT_BUF_INIT;
	git_remote *remote;
	const git_remote_callbacks *callbacks;

	assert(repo && _remote);

	if (!git_repository_is_empty(repo)) {
		giterr_set(GITERR_INVALID, "the repository is not empty");
		return -1;
	}

	if ((error = git_remote_dup(&remote, _remote)) < 0)
		return error;

	callbacks = git_remote_get_callbacks(_remote);
	if (!giterr__check_version(callbacks, 1, "git_remote_callbacks") &&
	    (error = git_remote_set_callbacks(remote, callbacks)) < 0)
		goto cleanup;

	if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
		goto cleanup;

	git_remote_set_update_fetchhead(remote, 0);
	git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));

	if ((error = git_remote_fetch(remote, signature, git_buf_cstr(&reflog_message))) != 0)
		goto cleanup;

	error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));

cleanup:
	git_remote_free(remote);
	git_buf_free(&reflog_message);

	return error;
}
Example #11
0
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch)
{
	int error = 0, old_fetchhead;
	size_t nspecs;

	assert(repo && remote);

	if (!git_repository_is_empty(repo)) {
		giterr_set(GITERR_INVALID, "the repository is not empty");
		return -1;
	}

	if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
		return error;

	old_fetchhead = git_remote_update_fetchhead(remote);
	git_remote_set_update_fetchhead(remote, 0);

	if ((error = git_remote_fetch(remote)) < 0)
		goto cleanup;

	if (branch)
		error = update_head_to_branch(repo, git_remote_name(remote), branch);
	/* Point HEAD to the same ref as the remote's head */
	else
		error = update_head_to_remote(repo, remote);

	if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
		error = git_checkout_head(repo, co_opts);

cleanup:
	git_remote_set_update_fetchhead(remote, old_fetchhead);
	/* Remove the tags refspec */
	nspecs = git_remote_refspec_count(remote);
	git_remote_remove_refspec(remote, nspecs);

	return error;
}
Example #12
0
/*
 *  call-seq:
 *    remote.fetch(refspecs = nil, options = {}) -> hash
 *
 *  Downloads new data from the remote for the given +refspecs+ and updates tips.
 *
 *  You can optionally pass in an alternative list of +refspecs+ to use instead of the fetch
 *  refspecs already configured for +remote+.
 *
 *  Returns a hash containing statistics for the fetch operation.
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :credentials ::
 *    The credentials to use for the fetch 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.
 *
 *  :progress ::
 *    A callback that will be executed with the textual progress received from the remote.
 *    This is the text send over the progress side-band (ie. the "counting objects" output).
 *
 *  :transfer_progress ::
 *    A callback that will be executed to report clone progress information. It will be passed
 *    the amount of +total_objects+, +indexed_objects+, +received_objects+, +local_objects+,
 *    +total_deltas+, +indexed_deltas+ and +received_bytes+.
 *
 *  :update_tips ::
 *    A callback that will be executed each time a reference is updated locally. It will be
 *    passed the +refname+, +old_oid+ and +new_oid+.
 *
 *  :message ::
 *    The message to insert into the reflogs. Defaults to "fetch".
 *
 *  :signature ::
 *    The signature to be used for updating the reflogs.
 *
 *  Example:
 *
 *    remote = Rugged::Remote.lookup(@repo, 'origin')
 *    remote.fetch({
 *      transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes|
 *        # ...
 *      }
 *    })
 */
static VALUE rb_git_remote_fetch(int argc, VALUE *argv, VALUE self)
{
	git_remote *remote, *tmp_remote = NULL;
	git_repository *repo;
	git_signature *signature = NULL;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	struct rugged_remote_cb_payload payload = { Qnil, Qnil, Qnil, Qnil, Qnil, 0 };

	char *log_message = NULL;
	int error, i;

	VALUE rb_options, rb_refspecs, rb_result = Qnil, rb_repo = rugged_owner(self);

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

	if (!NIL_P(rb_refspecs)) {
		Check_Type(rb_refspecs, T_ARRAY);
		for (i = 0; i < RARRAY_LEN(rb_refspecs); ++i) {
			VALUE rb_refspec = rb_ary_entry(rb_refspecs, i);
			Check_Type(rb_refspec, T_STRING);
		}
	}

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

	if (!NIL_P(rb_options)) {
		VALUE rb_val = rb_hash_aref(rb_options, CSTR2SYM("signature"));
		if (!NIL_P(rb_val))
			signature = rugged_signature_get(rb_val, repo);

		rb_val = rb_hash_aref(rb_options, CSTR2SYM("message"));
		if (!NIL_P(rb_val))
			log_message = StringValueCStr(rb_val);

		rugged_remote_init_callbacks_and_payload_from_options(rb_options, &callbacks, &payload);
	}

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

	if (!NIL_P(rb_refspecs)) {
		git_remote_clear_refspecs(tmp_remote);
		for (i = 0; !error && i < RARRAY_LEN(rb_refspecs); ++i) {
			VALUE rb_refspec = rb_ary_entry(rb_refspecs, i);

			if ((error = git_remote_add_fetch(tmp_remote, StringValueCStr(rb_refspec))))
				goto cleanup;
		}
	}

	if ((error = git_remote_fetch(tmp_remote, signature, log_message)) == GIT_OK) {
		const git_transfer_progress *stats = git_remote_stats(tmp_remote);

		rb_result = rb_hash_new();
		rb_hash_aset(rb_result, CSTR2SYM("total_objects"),    UINT2NUM(stats->total_objects));
		rb_hash_aset(rb_result, CSTR2SYM("indexed_objects"),  UINT2NUM(stats->indexed_objects));
		rb_hash_aset(rb_result, CSTR2SYM("received_objects"), UINT2NUM(stats->received_objects));
		rb_hash_aset(rb_result, CSTR2SYM("local_objects"),    UINT2NUM(stats->local_objects));
		rb_hash_aset(rb_result, CSTR2SYM("total_deltas"),     UINT2NUM(stats->total_deltas));
		rb_hash_aset(rb_result, CSTR2SYM("indexed_deltas"),   UINT2NUM(stats->indexed_deltas));
		rb_hash_aset(rb_result, CSTR2SYM("received_bytes"),   INT2FIX(stats->received_bytes));
	}

	cleanup:

	git_signature_free(signature);
	git_remote_free(tmp_remote);

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

	rugged_exception_check(error);

	return rb_result;
}
Example #13
0
bool FetchProgressCommand::Run(CGitProgressList* list, CString& sWindowTitle, int& /*m_itemCountTotal*/, int& /*m_itemCount*/)
{
	if (!g_Git.UsingLibGit2(CGit::GIT_CMD_FETCH))
	{
		// should never run to here
		ASSERT(0);
		return false;
	}

	list->SetWindowTitle(IDS_PROGRS_TITLE_FETCH, g_Git.m_CurrentDir, sWindowTitle);
	list->SetBackgroundImage(IDI_UPDATE_BKG);
	list->ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_TITLE_FETCH)) + L' ' + m_url.GetGitPathString() + L' ' + m_RefSpec);

	CStringA url = CUnicodeUtils::GetUTF8(m_url.GetGitPathString());

	CSmartAnimation animate(list->m_pAnimate);

	CAutoRepository repo(g_Git.GetGitRepository());
	if (!repo)
	{
		list->ReportGitError();
		return false;
	}

	CAutoRemote remote;
	// first try with a named remote (e.g. "origin")
	if (git_remote_lookup(remote.GetPointer(), repo, url) < 0)
	{
		// retry with repository located at a specific url
		if (git_remote_create_anonymous(remote.GetPointer(), repo, url) < 0)
		{
			list->ReportGitError();
			return false;
		}
	}

	git_fetch_options fetchopts = GIT_FETCH_OPTIONS_INIT;
	git_remote_callbacks& callbacks = fetchopts.callbacks;
	callbacks.update_tips = RemoteUpdatetipsCallback;
	callbacks.sideband_progress = RemoteProgressCallback;
	callbacks.transfer_progress = FetchCallback;
	callbacks.completion = RemoteCompletionCallback;
	callbacks.credentials = CAppUtils::Git2GetUserPassword;
	callbacks.certificate_check = CAppUtils::Git2CertificateCheck;
	CGitProgressList::Payload cbpayload = { list, repo };
	callbacks.payload = &cbpayload;

	git_remote_set_autotag(repo, git_remote_name(remote), (git_remote_autotag_option_t)m_AutoTag);

	if (!m_RefSpec.IsEmpty() && git_remote_add_fetch(repo, git_remote_name(remote), CUnicodeUtils::GetUTF8(m_RefSpec)))
		goto error;

	if (git_remote_fetch(remote, nullptr, &fetchopts, nullptr) < 0)
		goto error;

	// Not setting m_PostCmdCallback here, as clone is only called from AppUtils.cpp

	return true;

error:
	list->ReportGitError();
	return false;
}