static int just_return_origin(git_remote **out, git_repository *repo, const char *name, const char *url, void *payload) { GIT_UNUSED(url); GIT_UNUSED(payload); return git_remote_lookup(out, repo, name); }
/** * 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 * @return R_NilValue */ SEXP git2r_remote_fetch( SEXP repo, SEXP name, SEXP credentials, SEXP msg) { 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; 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); 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; 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, NULL, &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 (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; }
void test_clone_nonetwork__defaults(void) { cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", NULL)); cl_assert(g_repo); cl_git_pass(git_remote_lookup(&g_remote, g_repo, "origin")); }
void SyncState::sync() { m_timer.restart(); // Set up directory structure, if necessary std::string tmpPath = cpp3ds::FileSystem::getFilePath("sdmc:/3ds/BrewMan/tmp"); std::string cachePath = cpp3ds::FileSystem::getFilePath("sdmc:/3ds/BrewMan/cache"); std::string installedPath = cpp3ds::FileSystem::getFilePath("sdmc:/3ds/BrewMan/installed"); if (pathExists(tmpPath.c_str(), false)) removeDirectory(tmpPath.c_str()); mkdir(tmpPath.c_str(), 0777); if (!pathExists(cachePath.c_str(), false)) mkdir(cachePath.c_str(), 0777); if (!pathExists(installedPath.c_str(), false)) mkdir(installedPath.c_str(), 0777); // If auto-dated, boot into newest BrewMan if (autoUpdate()) { char buf[256]; size_t len; FILE *src = fopen("sdmc:/3ds/BrewMan/tmp/update.3dsx", "rb"); FILE *dst = fopen("sdmc:/3ds/BrewMan/tmp/update-copy.3dsx", "wb"); while ((len = fread(buf, 1, sizeof(buf), src)) > 0) fwrite(buf, 1, sizeof(buf), dst); fclose(src); fclose(dst); bootApp("/3ds/BrewMan/tmp/update.3dsx", ""); requestStackClear(); return; } git_repository *repo = NULL; const char *repoUrl = "git://github.com/Repo3DS/ideal-enigma.git"; const std::string path = cpp3ds::FileSystem::getFilePath(REPO_DIR); git_clone_options opts = GIT_CLONE_OPTIONS_INIT; setStatus("Fetching git repo..."); int error = git_clone(&repo, repoUrl, path.c_str(), NULL); if (error < 0) { if (error == GIT_EEXISTS) { error = git_repository_open(&repo, path.c_str()); if (error == 0) { git_remote *remote; error = git_remote_lookup(&remote, repo, "origin"); if (error == 0) { error = git_remote_fetch(remote, NULL, NULL, "pull"); if (error == 0) { git_annotated_commit *our_head, *their_heads[1]; if (git_repository_fetchhead_foreach(repo, find_master, NULL) == 0) { git_annotated_commit_from_fetchhead(&their_heads[0], repo, "master", repoUrl, &m_git_oid); git_merge_analysis_t analysis; git_merge_preference_t prefs; git_merge_analysis(&analysis, &prefs, repo, (const git_annotated_commit**)their_heads, 1); if (analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) printf("up to date\n"); else if (analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) { printf("fast-forwarding\n"); // if (git_merge(repo, (const git_annotated_commit **)their_heads, 1, NULL, NULL) == 0) { git_reference *ref; git_reference *newref; if (git_reference_lookup(&ref, repo, "refs/heads/master") == 0) git_reference_set_target(&newref, ref, &m_git_oid, "BrewMan pull: Fast-forward"); git_reset_from_annotated(repo, their_heads[0], GIT_RESET_HARD, NULL); git_reference_free(ref); git_repository_state_cleanup(repo); } git_annotated_commit_free(their_heads[0]); } } } } git_repository_free(repo); const git_error *e = giterr_last(); if (e) { setStatus(_("Error %d/%d\n%s\nCloning repo again...", error, e->klass, e->message)); if (!removeDirectory(path.c_str())) { cpp3ds::sleep(cpp3ds::seconds(2.f)); sync(); } else { setStatus("Repo failure. Please report this error.\nAnd delete /3ds/BrewMan/repo/ and try again."); } return; } } const git_error *e = giterr_last(); if (e) { setStatus(_("Error %d/%d: %s", error, e->klass, e->message)); return; } } setStatus("Everything up-to-date!"); // Give the Title animation time to finish if necessary while (m_timer.getElapsedTime() < cpp3ds::seconds(5.f)) cpp3ds::sleep(cpp3ds::milliseconds(50)); requestStackClear(); requestStackPush(States::Browse); }
int sync_with_remote(git_repository *repo, const char *remote, const char *branch, enum remote_transport rt) { int error; git_remote *origin; char *proxy_string; git_config *conf; if (git_local_only) { if (verbose) fprintf(stderr, "don't sync with remote - read from cache only\n"); return 0; } if (verbose) fprintf(stderr, "sync with remote %s[%s]\n", remote, branch); git_storage_update_progress(translate("gettextFromC", "Sync with cloud storage")); git_repository_config(&conf, repo); if (rt == RT_HTTPS && getProxyString(&proxy_string)) { if (verbose) fprintf(stderr, "set proxy to \"%s\"\n", proxy_string); git_config_set_string(conf, "http.proxy", proxy_string); free(proxy_string); } else { if (verbose) fprintf(stderr, "delete proxy setting\n"); git_config_delete_entry(conf, "http.proxy"); } /* * NOTE! Remote errors are reported, but are nonfatal: * we still successfully return the local repository. */ error = git_remote_lookup(&origin, repo, "origin"); if (error) { if (!is_subsurface_cloud) report_error("Repository '%s' origin lookup failed (%s)", remote, giterr_last()->message); return 0; } if (is_subsurface_cloud && !canReachCloudServer()) { // this is not an error, just a warning message, so return 0 report_error("Cannot connect to cloud server, working with local copy"); git_storage_update_progress(translate("gettextFromC", "Can't reach cloud server, working with local data")); return 0; } if (verbose) fprintf(stderr, "git storage: fetch remote\n"); git_fetch_options opts = GIT_FETCH_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", "Successful cloud connection, fetch remote")); error = git_remote_fetch(origin, NULL, &opts, NULL); // NOTE! A fetch error is not fatal, we just report it if (error) { if (is_subsurface_cloud) report_error("Cannot sync with cloud server, working with offline copy"); else report_error("Unable to fetch remote '%s'", remote); if (verbose) // If we returned GIT_EUSER during authentication, giterr_last() returns NULL fprintf(stderr, "remote fetch failed (%s)\n", giterr_last() ? giterr_last()->message : "authentication failed"); // Since we failed to sync with online repository, enter offline mode git_local_only = true; error = 0; } else { error = check_remote_status(repo, origin, remote, branch, rt); } git_remote_free(origin); git_storage_update_progress(translate("gettextFromC", "Done syncing with cloud storage")); return error; }
/** 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; }
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; }
int sync_with_remote(git_repository *repo, const char *remote, const char *branch, enum remote_transport rt) { int error; git_remote *origin; char *proxy_string; git_config *conf; if (verbose) fprintf(stderr, "sync with remote %s[%s]\n", remote, branch); git_repository_config(&conf, repo); if (rt == RT_HTTPS && getProxyString(&proxy_string)) { if (verbose) fprintf(stderr, "set proxy to \"%s\"\n", proxy_string); git_config_set_string(conf, "http.proxy", proxy_string); free(proxy_string); } else { if (verbose) fprintf(stderr, "delete proxy setting\n"); git_config_delete_entry(conf, "http.proxy"); } /* * NOTE! Remote errors are reported, but are nonfatal: * we still successfully return the local repository. */ error = git_remote_lookup(&origin, repo, "origin"); if (error) { if (!is_subsurface_cloud) report_error("Repository '%s' origin lookup failed (%s)", remote, giterr_last()->message); return 0; } if (rt == RT_HTTPS && !canReachCloudServer()) { // this is not an error, just a warning message, so return 0 report_error("Cannot connect to cloud server, working with local copy"); return 0; } if (verbose) fprintf(stderr, "git storage: fetch remote\n"); #if USE_LIBGIT23_API git_fetch_options opts = GIT_FETCH_OPTIONS_INIT; opts.callbacks.transfer_progress = &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; error = git_remote_fetch(origin, NULL, &opts, NULL); #else error = git_remote_fetch(origin, NULL, NULL, NULL); #endif // NOTE! A fetch error is not fatal, we just report it if (error) { if (is_subsurface_cloud) report_error("Cannot sync with cloud server, working with offline copy"); else report_error("Unable to fetch remote '%s'", remote); if (verbose) fprintf(stderr, "remote fetch failed (%s)\n", giterr_last()->message); error = 0; } else { error = check_remote_status(repo, origin, remote, branch, rt); } git_remote_free(origin); return error; }
void test_network_fetchlocal__prune(void) { git_repository *repo; git_remote *origin; int callcount = 0; git_strarray refnames = {0}; git_reference *ref; git_repository *remote_repo = cl_git_sandbox_init("testrepo.git"); const char *url = cl_git_path_url(git_repository_path(remote_repo)); git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; callbacks.transfer_progress = transfer_cb; callbacks.payload = &callcount; cl_set_cleanup(&cleanup_local_repo, "foo"); cl_git_pass(git_repository_init(&repo, "foo", true)); cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(19, (int)refnames.count); cl_assert(callcount > 0); git_strarray_free(&refnames); git_remote_free(origin); cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2")); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, NULL)); cl_git_pass(git_remote_prune(origin)); cl_git_pass(git_remote_update_tips(origin, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(18, (int)refnames.count); git_strarray_free(&refnames); git_remote_free(origin); cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed")); cl_git_pass(git_reference_delete(ref)); git_reference_free(ref); cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN)); git_remote_set_callbacks(origin, &callbacks); cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_download(origin, NULL)); cl_git_pass(git_remote_prune(origin)); cl_git_pass(git_remote_update_tips(origin, NULL, NULL)); cl_git_pass(git_reference_list(&refnames, repo)); cl_assert_equal_i(17, (int)refnames.count); git_strarray_free(&refnames); git_remote_free(origin); git_repository_free(repo); }
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; }
// Clone the module currently highlighted in the QListWidget. void RTXIWizard::Panel::cloneModule(void) { cloneButton->setEnabled(false); availableListWidget->setDisabled(true); installedListWidget->setDisabled(true); QString name; switch(button_mode) { case DOWNLOAD: name = availableListWidget->currentItem()->text(); break; case UPDATE: name = installedListWidget->currentItem()->text(); break; default: std::cout<<"ERROR: default in switch block in cloneModule()"<<std::endl; break; } /* * Two QByteArray variables are needed due to the way Qt stores binary data. * Calling module->getCloneUrl().toString().toLatin1().data() will produce * an error. */ QByteArray temp = modules[name].clone_url.toString().toLatin1(); const char *url = temp.data(); QByteArray temp2 = modules[name].location.toString().toLatin1(); const char *path = temp2.data(); int error = 0; // If the repo already exists, pull from master. If not, clone it. if ( (QDir(modules[name].location.toString())).exists() ) { git_repository *repo = NULL; git_remote *remote = NULL; git_repository_open(&repo, path); #if LIBGIT2_SOVERSION >= 22 printGitError(git_remote_lookup(&remote, repo, "origin")); #else printGitError(git_remote_load(&remote, repo, "origin")); #endif #if LIBGIT2_SOVERSION >= 24 printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL)); //printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL)); #else printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH)); #endif #if LIBGIT2_SOVERSION >= 24 printGitError(git_remote_download(remote, NULL, NULL)); #elif LIBGIT2_SOVERSION >= 22 printGitError(git_remote_download(remote, NULL)); #elif LIBGIT2_SOVERSION >= 21 printGitError(git_remote_download(remote)); #else printGitError(git_remote_download(remote, NULL, NULL)); #endif git_remote_disconnect(remote); git_remote_free(remote); git_repository_free(repo); } else { git_repository *repo = NULL; printGitError(git_clone(&repo, url, path, NULL)); git_repository_free(repo); } if (error) { std::cout<<"git ERROR"<<std::endl; } else { // Add module to list of already installed modules. modules[name].installed = true; // Define the commands to be run. QString make_cmd = "/usr/bin/make -j2 -C " + modules[name].location.toString(); QString make_install_cmd; // If RTXI is root, no need to call gksudo. if (getuid()) make_install_cmd = "gksudo \"/usr/bin/make install -C" + modules[name].location.toString() + "\""; else make_install_cmd = "/usr/bin/make install -C" + modules[name].location.toString(); // Compile and instal handled by QProcess. QProcess *make = new QProcess(); QProcess *make_install = new QProcess(); make->start(make_cmd); if (!make->waitForFinished()) { std::cout<<"make -C "<<path<<" failed"<<std::endl; } else { make_install->start(make_install_cmd); if (!make_install->waitForFinished()) { std::cout<<"make install -C"<<path<<" failed..."<<std::endl; std::cout<<"...despite make -C succeeding."<<std::endl; } } make->close(); make_install->close(); } // Re-enable buttons only after compilation is done. Otherwise you get race // conditions if buttons are pressed before modules are done compiling. cloneButton->setEnabled(true); rebuildListWidgets(); availableListWidget->setDisabled(false); installedListWidget->setDisabled(false); }
/** 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; }