Пример #1
0
/**
 * 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;
}
Пример #2
0
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);
}