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; }
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); }
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"); }
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; }
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"); }
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"); }
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/*")); }
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; }
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; }
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; }
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; }
/* * 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; }
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; }