static void connect_to_local_repository(const char *local_repository) { git_buf_sets(&file_path_buf, cl_git_path_url(local_repository)); cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf))); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL)); }
void test_network_remote_local__push_to_non_bare_remote(void) { char *refspec_strings[] = { "master:master", }; git_strarray array = { refspec_strings, 1, }; /* Shouldn't be able to push to a non-bare remote */ git_remote *localremote; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; /* Get some commits */ connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_fetch(remote, &array, &fetch_opts, NULL)); /* Set up an empty non-bare repo to push into */ { git_repository *remoterepo = NULL; cl_git_pass(git_repository_init(&remoterepo, "localnonbare", 0)); git_repository_free(remoterepo); } /* Connect to the bare repo */ cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localnonbare")); cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL)); /* Try to push */ cl_git_fail_with(GIT_EBAREREPO, git_remote_upload(localremote, &push_array, NULL)); /* Clean up */ git_remote_free(localremote); cl_fixture_cleanup("localbare.git"); }
void test_network_remote_remotes__error_when_no_push_available(void) { git_remote *r; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; char *specs = { "refs/heads/master", }; git_strarray arr = { &specs, 1, }; cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git"))); callbacks.transport = git_transport_local; cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH, &callbacks, NULL)); /* Make sure that push is really not available */ r->transport->push = NULL; cl_git_fail_with(-1, git_remote_upload(r, &arr, NULL)); git_remote_free(r); }
void test_network_remote_local__push_to_bare_remote(void) { char *refspec_strings[] = { "master:master", }; git_strarray array = { refspec_strings, 1, }; /* Should be able to push to a bare remote */ git_remote *localremote; /* Get some commits */ connect_to_local_repository(cl_fixture("testrepo.git")); cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL)); /* Set up an empty bare repo to push into */ { git_repository *localbarerepo; cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1)); git_repository_free(localbarerepo); } /* Connect to the bare repo */ cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localbare.git")); cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL)); /* Try to push */ cl_git_pass(git_remote_upload(localremote, &push_array, NULL)); /* Clean up */ git_remote_free(localremote); cl_fixture_cleanup("localbare.git"); }
void do_update_repo(char *url, char *path) { git_repository *repo; git_remote *remote = NULL; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; const git_transfer_progress *stats; char textfield_final_string[MAXLINE]; memset(textfield_final_string, 0, sizeof(textfield_final_string)); int error = git_repository_open(&repo, path); if (error != 0) git_error_handling(); if (git_remote_lookup(&remote, repo, url) != 0) { error = git_remote_create_anonymous(&remote, repo, url); if (error != 0) git_error_handling(); } fetch_opts.callbacks.update_tips = &update_tips; fetch_opts.callbacks.sideband_progress = sideband_progress; fetch_opts.callbacks.transfer_progress = fetch_progress; error = git_remote_fetch(remote, NULL, &fetch_opts, "fetch"); if (error != 0) git_error_handling(); stats = git_remote_stats(remote); int receive_kbyte = stats->received_bytes / 1024; if (stats->local_objects > 0) { snprintf(textfield_final_string, sizeof(textfield_final_string), _("Fetched: (%d/%d) %d kB (used %d local objects)"), stats->indexed_objects, stats->total_objects, receive_kbyte, stats->local_objects); write_info_msg(textfield_final_string); } else { snprintf(textfield_final_string, sizeof(textfield_final_string), _("Fetched: (%d/%d) %d kB"), stats->indexed_objects, stats->total_objects, receive_kbyte); write_info_msg(textfield_final_string); } out: if (remote) git_remote_free(remote); if (repo) git_repository_free(repo); }
void test_network_remote_delete__cannot_delete_an_anonymous_remote(void) { git_remote *remote; cl_git_pass(git_remote_create_anonymous(&remote, _repo, "git://github.com/libgit2/libgit2", NULL)); cl_git_fail(git_remote_delete(remote)); git_remote_free(remote); }
void test_network_remote_local__retrieve_advertised_before_connect(void) { const git_remote_head **refs; size_t refs_len = 0; git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git"))); cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf))); cl_git_fail(git_remote_ls(&refs, &refs_len, remote)); }
/** Entry point for this command */ int fetch(git_repository *repo, int argc, char **argv) { git_remote *remote = NULL; const git_transfer_progress *stats; struct dl_data data; git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT; if (argc < 2) { fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]); return EXIT_FAILURE; } // Figure out whether it's a named remote or a URL printf("Fetching %s for repo %p\n", argv[1], repo); if (git_remote_lookup(&remote, repo, argv[1]) < 0) { if (git_remote_create_anonymous(&remote, repo, argv[1]) < 0) return -1; } // Set up the callbacks (only update_tips for now) fetch_opts.callbacks.update_tips = &update_cb; fetch_opts.callbacks.sideband_progress = &progress_cb; fetch_opts.callbacks.transfer_progress = transfer_progress_cb; fetch_opts.callbacks.credentials = cred_acquire_cb; /** * Perform the fetch with the configured refspecs from the * config. Update the reflog for the updated references with * "fetch". */ if (git_remote_fetch(remote, NULL, &fetch_opts, "fetch") < 0) return -1; /** * If there are local objects (we got a thin pack), then tell * the user how many objects we saved from having to cross the * network. */ stats = git_remote_stats(remote); if (stats->local_objects > 0) { printf("\rReceived %d/%d objects in %" PRIuZ " bytes (used %d local objects)\n", stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects); } else{ printf("\rReceived %d/%d objects in %" PRIuZ "bytes\n", stats->indexed_objects, stats->total_objects, stats->received_bytes); } git_remote_free(remote); return 0; on_error: git_remote_free(remote); return -1; }
void test_remote_insteadof__anonymous_remote(void) { cl_git_pass(git_repository_open(&g_repo, cl_fixture(REPO_PATH))); cl_git_pass(git_remote_create_anonymous(&g_remote, g_repo, "http://example.com/libgit2/libgit2")); cl_assert_equal_s( git_remote_url(g_remote), "http://github.com/libgit2/libgit2"); cl_assert_equal_p(git_remote_pushurl(g_remote), NULL); }
/** * 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; }
static int use_remote(git_repository *repo, char *name) { git_remote *remote = NULL; int error; const git_remote_head **refs; size_t refs_len, i; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; // Find the remote by name error = git_remote_lookup(&remote, repo, name); if (error < 0) { error = git_remote_create_anonymous(&remote, repo, name); if (error < 0) goto cleanup; } /** * Connect to the remote and call the printing function for * each of the remote references. */ callbacks.credentials = cred_acquire_cb; callbacks.certificate_check = certificate_check; error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL); if (error < 0) goto cleanup; /** * Get the list of references on the remote and print out * their name next to what they point to. */ if (git_remote_ls(&refs, &refs_len, remote) < 0) goto cleanup; for (i = 0; i < refs_len; i++) { char oid[GIT_OID_HEXSZ + 1] = {0}; git_oid_fmt(oid, &refs[i]->oid); printf("%s\t%s\n", oid, refs[i]->name); } cleanup: git_remote_free(remote); return error; }
/* * call-seq: * Remote.new(repository, url) -> remote * * Return a new remote with +url+ in +repository+ , the remote is not persisted: * - +url+: a valid remote url * * Returns a new Rugged::Remote object * * Rugged::Remote.new(@repo, 'git://github.com/libgit2/libgit2.git') #=> #<Rugged::Remote:0x00000001fbfa80> */ static VALUE rb_git_remote_new(VALUE klass, VALUE rb_repo, VALUE rb_url) { git_remote *remote; git_repository *repo; int error; rugged_check_repo(rb_repo); rugged_validate_remote_url(rb_url); Data_Get_Struct(rb_repo, git_repository, repo); error = git_remote_create_anonymous( &remote, repo, StringValueCStr(rb_url), NULL); rugged_exception_check(error); return rugged_remote_new(klass, rb_repo, remote); }
/* * call-seq: * remotes.create_anonymous(url) -> remote * * Return a new remote with +url+ in +repository+ , the remote is not persisted: * - +url+: a valid remote url * * Returns a new Rugged::Remote object. * * @repo.remotes.create_anonymous('git://github.com/libgit2/libgit2.git') #=> #<Rugged::Remote:0x00000001fbfa80> */ static VALUE rb_git_remote_collection_create_anonymous(VALUE self, VALUE rb_url) { git_remote *remote; git_repository *repo; int error; VALUE rb_repo = rugged_owner(self); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); Check_Type(rb_url, T_STRING); error = git_remote_create_anonymous( &remote, repo, StringValueCStr(rb_url), NULL); rugged_exception_check(error); return rugged_remote_new(rb_repo, remote); }
/** * ggit_remote_new_anonymous: * @repository: a #GgitRepository. * @url: the remote repository's URL. * @error: a #GError for error reporting, or %NULL. * * Creates a remote with the specified refspec in memory. You can use * this when you have a URL instead of a remote's name. * * Returns: (transfer full) (nullable): a newly allocated #GgitRemote or %NULL. */ GgitRemote * ggit_remote_new_anonymous (GgitRepository *repository, const gchar *url, GError **error) { gint ret; git_remote *remote; g_return_val_if_fail (GGIT_IS_REPOSITORY (repository), NULL); g_return_val_if_fail (url != NULL, NULL); ret = git_remote_create_anonymous (&remote, _ggit_native_get (repository), url); if (ret != GIT_OK) { _ggit_error_set (error, ret); return NULL; } return _ggit_remote_wrap (remote); }
/** * Get the remote's url * * Based on https://github.com/libgit2/libgit2/blob/babdc376c7/examples/network/ls-remote.c * @param repo S4 class git_repository * @param name Character vector with URL of remote. * @return Character vector for each reference with the associated commit IDs. */ SEXP git2r_remote_ls(SEXP name, SEXP repo, SEXP credentials) { const char *name_ = NULL; SEXP result = R_NilValue; SEXP names = R_NilValue; git_remote *remote = NULL; int err; const git_remote_head **refs; size_t refs_len, i; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT; git_repository *repository = NULL; 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); repository = git2r_repository_open(repo); if (!repository) git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL); name_ = CHAR(STRING_ELT(name, 0)); err = git_remote_lookup(&remote, repository, name_); if (err) { err = git_remote_create_anonymous(&remote, repository, name_); if (err) goto cleanup; } payload.credentials = credentials; callbacks.payload = &payload; callbacks.credentials = &git2r_cred_acquire_cb; err = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks, NULL, NULL); if (err) goto cleanup; err = git_remote_ls(&refs, &refs_len, remote); if (err) goto cleanup; PROTECT(result = allocVector(STRSXP, refs_len)); setAttrib(result, R_NamesSymbol, names = allocVector(STRSXP, refs_len)); for (i = 0; i < refs_len; i++) { char oid[GIT_OID_HEXSZ + 1] = {0}; git_oid_fmt(oid, &refs[i]->oid); SET_STRING_ELT(result, i, mkChar(oid)); SET_STRING_ELT(names, i, mkChar(refs[i]->name)); } cleanup: if (repository) git_repository_free(repository); if (result != R_NilValue) UNPROTECT(1); if (err) git2r_error(__func__, giterr_last(), NULL, NULL); return(result); }
/** Entry point for this command */ int fetch(git_repository *repo, int argc, char **argv) { int err = GIT_OK; int rc = EXIT_FAILURE; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; const git_transfer_progress *stats; git_remote *remote = NULL; if (argc < 2) { fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]); return EXIT_FAILURE; } // Figure out whether it's a named remote or a URL printf("Fetching %s for repo at %s\n", argv[1], git_repository_path(repo)); if (git_remote_lookup(&remote, repo, argv[1]) < 0) { if ((err = git_remote_create_anonymous(&remote, repo, argv[1], NULL)) < 0) goto out; } // Set up the callbacks (only update_tips for now) callbacks.update_tips = &update_cb; callbacks.sideband_progress = &progress_cb; callbacks.credentials = cred_acquire_cb; callbacks.certificate_check = certificate_check; git_remote_set_callbacks(remote, &callbacks); stats = git_remote_stats(remote); if ((err = git_remote_connect(remote, GIT_DIRECTION_FETCH) < 0)) goto out; // Download the packfile and index it. This function updates the // amount of received data and the indexer stats which lets you // inform the user about progress. if ((err = git_remote_download(remote, NULL) < 0)) goto out; /** * If there are local objects (we got a thin pack), then tell * the user how many objects we saved from having to cross the * network. */ if (stats->local_objects > 0) { printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n", stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects); } else{ printf("\rReceived %d/%d objects in %zu bytes\n", stats->indexed_objects, stats->total_objects, stats->received_bytes); } // Disconnect the underlying connection to prevent from idling. git_remote_disconnect(remote); // Update the references in the remote's namespace to point to the // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been // changed but all the needed objects are available locally. if ((err = git_remote_update_tips(remote, NULL, NULL)) < 0) goto out; rc = EXIT_SUCCESS; out: if (err != GIT_OK) libgit_error(); if (remote) git_remote_free(remote); return rc; }
/** Entry point for this command */ int fetch(git_repository *repo, int argc, char **argv) { git_remote *remote = NULL; const git_transfer_progress *stats; struct dl_data data; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; #ifndef _WIN32 pthread_t worker; #endif if (argc < 2) { fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]); return EXIT_FAILURE; } // Figure out whether it's a named remote or a URL printf("Fetching %s for repo %p\n", argv[1], repo); if (git_remote_lookup(&remote, repo, argv[1]) < 0) { if (git_remote_create_anonymous(&remote, repo, argv[1], NULL) < 0) return -1; } // Set up the callbacks (only update_tips for now) callbacks.update_tips = &update_cb; callbacks.sideband_progress = &progress_cb; callbacks.credentials = cred_acquire_cb; git_remote_set_callbacks(remote, &callbacks); // Set up the information for the background worker thread data.remote = remote; data.ret = 0; data.finished = 0; stats = git_remote_stats(remote); #ifdef _WIN32 download(&data); #else pthread_create(&worker, NULL, download, &data); // Loop while the worker thread is still running. Here we show processed // and total objects in the pack and the amount of received // data. Most frontends will probably want to show a percentage and // the download rate. do { usleep(10000); if (stats->received_objects == stats->total_objects) { printf("Resolving deltas %d/%d\r", stats->indexed_deltas, stats->total_deltas); } else if (stats->total_objects > 0) { printf("Received %d/%d objects (%d) in %" PRIuZ " bytes\r", stats->received_objects, stats->total_objects, stats->indexed_objects, stats->received_bytes); } } while (!data.finished); if (data.ret < 0) goto on_error; pthread_join(worker, NULL); #endif /** * If there are local objects (we got a thin pack), then tell * the user how many objects we saved from having to cross the * network. */ if (stats->local_objects > 0) { printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n", stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects); } else{ printf("\rReceived %d/%d objects in %zu bytes\n", stats->indexed_objects, stats->total_objects, stats->received_bytes); } // Disconnect the underlying connection to prevent from idling. git_remote_disconnect(remote); // Update the references in the remote's namespace to point to the // right commits. This may be needed even if there was no packfile // to download, which can happen e.g. when the branches have been // changed but all the needed objects are available locally. if (git_remote_update_tips(remote, NULL) < 0) return -1; git_remote_free(remote); return 0; on_error: git_remote_free(remote); return -1; }
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; }