/** * Create and populate a vector of git_annotated_commit objects from * the given fetch head data. * * @param out Pointer the vector of git_annotated_commit objects. * @param repository The repository. * @param fetch_heads List of S4 class git_fetch_head objects. * @param n Length of fetch_heads list. * @return 0 on success, or error code */ static int git2r_merge_heads_from_fetch_heads( git_annotated_commit ***merge_heads, git_repository *repository, SEXP fetch_heads, size_t n) { int err = GIT_OK; size_t i; *merge_heads = calloc(n, sizeof(git_annotated_commit*)); if (!(*merge_heads)) { giterr_set_str(GITERR_NONE, git2r_err_alloc_memory_buffer); return GIT_ERROR; } for (i = 0; i < n; i++) { int err; git_oid oid; SEXP fh = VECTOR_ELT(fetch_heads, i); err = git_oid_fromstr( &oid, CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("sha")), 0))); if (err) goto cleanup; err = git_annotated_commit_from_fetchhead( &((*merge_heads)[i]), repository, CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("ref_name")), 0)), CHAR(STRING_ELT(GET_SLOT(fh, Rf_install("remote_url")), 0)), &oid); if (err) goto cleanup; } cleanup: if (err) { if (*merge_heads) git2r_merge_heads_free(*merge_heads, n); *merge_heads = NULL; } return err; }
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); }