Exemplo n.º 1
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__autocrlf_input_no_attrs(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_string(g_repo, "core.autocrlf", "input");

	git_checkout_head(g_repo, &opts);

	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
}
Exemplo n.º 2
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__detect_crlf_autocrlf_false(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_bool(g_repo, "core.autocrlf", false);

	git_checkout_head(g_repo, &opts);

	check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
	check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
}
Exemplo n.º 3
0
void test_checkout_tree__can_remove_untracked(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;

	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_UNTRACKED;

	cl_git_mkfile("testrepo/untracked_file", "as you wish");
	cl_assert(git_path_isfile("testrepo/untracked_file"));

	cl_git_pass(git_checkout_head(g_repo, &opts));

	cl_assert(!git_path_isfile("testrepo/untracked_file"));
}
Exemplo n.º 4
0
void test_checkout_crlf__more_crlf_autocrlf_true(void)
{
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_LF)
		check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_RAW);
	else
		check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_AS_CRLF);
}
Exemplo n.º 5
0
/**
 * Checks out the given branch.
 */
static int sync_checkout(git_repository *repo,
                         const char *name)
{
    int e = 0;

    git_check(git_repository_set_head(repo, name));

    git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
    opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
    git_check(git_checkout_head(repo, &opts));

exit:
    return e;
}
Exemplo n.º 6
0
/* git checkout beef && git rebase --merge --onto `git rev-parse master`
 *   `git rev-parse veal` `git rev-parse gravy`
 */
void test_rebase_setup__merge_onto_upstream_and_branch_by_id(void)
{
	git_rebase *rebase;
	git_oid upstream_id, branch_id, onto_id;
	git_annotated_commit *upstream_head, *branch_head, *onto_head;
	git_reference *head;
	git_commit *head_commit;
	git_oid head_id;
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	cl_git_pass(git_repository_set_head(repo, "refs/heads/beef"));
	cl_git_pass(git_checkout_head(repo, &checkout_opts));

	cl_git_pass(git_oid_fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864"));
	cl_git_pass(git_oid_fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f"));
	cl_git_pass(git_oid_fromstr(&onto_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00"));

	cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id));
	cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id));
	cl_git_pass(git_annotated_commit_lookup(&onto_head, repo, &onto_id));

	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, onto_head, NULL));

	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
	cl_git_pass(git_repository_head(&head, repo));
	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT));
	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));

	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/ORIG_HEAD");

	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));

	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/rebase-merge/cmt.1");
	cl_assert_equal_file("1\n", 2, "rebase/.git/rebase-merge/end");
	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto_name");
	cl_assert_equal_file("d616d97082eb7bb2dc6f180a7cca940993b7a56f\n", 41, "rebase/.git/rebase-merge/orig-head");

	git_commit_free(head_commit);
	git_reference_free(head);
	git_annotated_commit_free(upstream_head);
	git_annotated_commit_free(branch_head);
	git_annotated_commit_free(onto_head);
	git_rebase_free(rebase);
}
Exemplo n.º 7
0
static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature, const char *reflog_message)
{
	int error;

	if (branch)
		error = update_head_to_branch(repo, git_remote_name(remote), branch,
				signature, reflog_message);
	/* Point HEAD to the same ref as the remote's head */
	else
		error = update_head_to_remote(repo, remote, signature, reflog_message);

	if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
		error = git_checkout_head(repo, co_opts);

	return error;
}
Exemplo n.º 8
0
/* git checkout beef && git rebase --merge master */
void test_rebase_setup__merge_null_branch_uses_HEAD(void)
{
	git_rebase *rebase;
	git_reference *upstream_ref;
	git_annotated_commit *upstream_head;
	git_reference *head;
	git_commit *head_commit;
	git_oid head_id;
	git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	cl_git_pass(git_repository_set_head(repo, "refs/heads/beef"));
	cl_git_pass(git_checkout_head(repo, &checkout_opts));

	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));
	cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref));

	cl_git_pass(git_rebase_init(&rebase, repo, NULL, upstream_head, NULL, NULL));

	cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));

	git_oid_fromstr(&head_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
	cl_git_pass(git_repository_head(&head, repo));
	cl_git_pass(git_reference_peel((git_object **)&head_commit, head, GIT_OBJECT_COMMIT));
	cl_assert_equal_oid(&head_id, git_commit_id(head_commit));

	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/ORIG_HEAD");

	cl_assert_equal_file("da9c51a23d02d931a486f45ad18cda05cf5d2b94\n", 41, "rebase/.git/rebase-merge/cmt.1");
	cl_assert_equal_file("8d1f13f93c4995760ac07d129246ac1ff64c0be9\n", 41, "rebase/.git/rebase-merge/cmt.2");
	cl_assert_equal_file("3069cc907e6294623e5917ef6de663928c1febfb\n", 41, "rebase/.git/rebase-merge/cmt.3");
	cl_assert_equal_file("588e5d2f04d49707fe4aab865e1deacaf7ef6787\n", 41, "rebase/.git/rebase-merge/cmt.4");
	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/cmt.5");
	cl_assert_equal_file("5\n", 2, "rebase/.git/rebase-merge/end");
	cl_assert_equal_file("efad0b11c47cb2f0220cbd6f5b0f93bb99064b00\n", 41, "rebase/.git/rebase-merge/onto");
	cl_assert_equal_file("master\n", 7, "rebase/.git/rebase-merge/onto_name");
	cl_assert_equal_file("b146bd7608eac53d9bf9e1a6963543588b555c64\n", 41, "rebase/.git/rebase-merge/orig-head");

	git_commit_free(head_commit);
	git_reference_free(head);
	git_annotated_commit_free(upstream_head);
	git_reference_free(upstream_ref);
	git_rebase_free(rebase);
}
Exemplo n.º 9
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__autocrlf_true_no_attrs(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_CRLF) {
		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
	} else {
		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
	}
}
Exemplo n.º 10
0
PyObject *
Repository_checkout_head(Repository *self, PyObject *args)
{
    git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
    unsigned int strategy;
    int err;

    if (!PyArg_ParseTuple(args, "I", &strategy))
        return NULL;

    opts.checkout_strategy = strategy;
    err = git_checkout_head(self->repo, &opts);
    if (err < 0)
        return Error_set(err);

    Py_RETURN_NONE;
}
Exemplo n.º 11
0
int git_clone(
	git_repository **out,
	const char *url,
	const char *local_path,
	const git_clone_options *options)
{
	int retcode = GIT_ERROR;
	git_repository *repo = NULL;
	git_clone_options normOptions;
	int remove_directory_on_failure = 0;

	assert(out && url && local_path);

	normalize_options(&normOptions, options);
	GITERR_CHECK_VERSION(&normOptions, GIT_CLONE_OPTIONS_VERSION, "git_clone_options");

	if (!path_is_okay(local_path)) {
		return GIT_ERROR;
	}

	/* Only remove the directory on failure if we create it */
	remove_directory_on_failure = !git_path_exists(local_path);

	if (!(retcode = git_repository_init(&repo, local_path, normOptions.bare))) {
		if ((retcode = setup_remotes_and_fetch(repo, url, &normOptions)) < 0) {
			/* Failed to fetch; clean up */
			git_repository_free(repo);

			if (remove_directory_on_failure)
				git_futils_rmdir_r(local_path, NULL, GIT_RMDIR_REMOVE_FILES);
			else
				git_futils_cleanupdir_r(local_path);

		} else {
			*out = repo;
			retcode = 0;
		}
	}

	if (!retcode && should_checkout(repo, normOptions.bare, &normOptions.checkout_opts))
		retcode = git_checkout_head(*out, &normOptions.checkout_opts);

	return retcode;
}
Exemplo n.º 12
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__autocrlf_false_text_auto_attr(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");

	cl_repo_set_bool(g_repo, "core.autocrlf", false);

	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_CRLF) {
		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF);
		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF);
	} else {
		check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW);
		check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW);
	}
}
Exemplo n.º 13
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__can_write_empty_file(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	git_repository_set_head(g_repo, "refs/heads/empty-files");
	git_checkout_head(g_repo, &opts);

	check_file_contents("./crlf/test1.txt", "");

	if (GIT_EOL_NATIVE == GIT_EOL_LF)
		check_file_contents("./crlf/test2.txt", "test2.txt's content\n");
	else
		check_file_contents("./crlf/test2.txt", "test2.txt's content\r\n");

	check_file_contents("./crlf/test3.txt", "");
}
Exemplo n.º 14
0
void test_checkout_tree__can_remove_ignored(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	int ignored = 0;

	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_IGNORED;

	cl_git_mkfile("testrepo/ignored_file", "as you wish");

	cl_git_pass(git_ignore_add_rule(g_repo, "ignored_file\n"));

	cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ignored_file"));
	cl_assert_equal_i(1, ignored);

	cl_assert(git_path_isfile("testrepo/ignored_file"));

	cl_git_pass(git_checkout_head(g_repo, &opts));

	cl_assert(!git_path_isfile("testrepo/ignored_file"));
}
Exemplo n.º 15
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
{
	git_index *index;
	const git_index_entry *entry;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_bool(g_repo, "core.autocrlf", false);

	git_checkout_head(g_repo, &opts);

	git_repository_index(&index, g_repo);

	cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
	cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW));

	cl_assert((entry = git_index_get_bypath(index, "all-crlf", 0)) != NULL);
	cl_assert(entry->file_size == strlen(ALL_CRLF_TEXT_RAW));

	git_index_free(index);
}
Exemplo n.º 16
0
void test_checkout_tree__can_update_only(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	git_oid oid;
	git_object *obj = NULL;

	/* first let's get things into a known state - by checkout out the HEAD */

	assert_on_branch(g_repo, "master");

	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
	cl_git_pass(git_checkout_head(g_repo, &opts));

	cl_assert(!git_path_isdir("testrepo/a"));

	check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");

	/* now checkout branch but with update only */

	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;

	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
	cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));

	cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
	cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));

	assert_on_branch(g_repo, "dir");

	/* this normally would have been created (which was tested separately in
	 * the test_checkout_tree__can_switch_branches test), but with
	 * UPDATE_ONLY it will not have been created.
	 */
	cl_assert(!git_path_isdir("testrepo/a"));

	/* but this file still should have been updated */
	check_file_contents_nocr("testrepo/branch_file.txt", "hi\n");

	git_object_free(obj);
}
Exemplo n.º 17
0
int merge_branches(git_merge_result **result, git_repository *repo, const char *ours_branch, const char *theirs_branch, git_merge_opts *opts)
{
	git_reference *head_ref, *theirs_ref;
	git_merge_head *theirs_head;
	git_checkout_opts head_checkout_opts = GIT_CHECKOUT_OPTS_INIT;

	head_checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_pass(git_reference_symbolic_create(&head_ref, repo, "HEAD", ours_branch, 1));
	cl_git_pass(git_checkout_head(repo, &head_checkout_opts));

	cl_git_pass(git_reference_lookup(&theirs_ref, repo, theirs_branch));
	cl_git_pass(git_merge_head_from_ref(&theirs_head, repo, theirs_ref));

	cl_git_pass(git_merge(result, repo, (const git_merge_head **)&theirs_head, 1, opts));

	git_reference_free(head_ref);
	git_reference_free(theirs_ref);
	git_merge_head_free(theirs_head);

	return 0;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
int merge_branches(git_repository *repo,
	const char *ours_branch, const char *theirs_branch,
	git_merge_options *merge_opts, git_checkout_options *checkout_opts)
{
	git_reference *head_ref, *theirs_ref;
	git_annotated_commit *theirs_head;
	git_checkout_options head_checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

	head_checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_pass(git_reference_symbolic_create(&head_ref, repo, "HEAD", ours_branch, 1, NULL));
	cl_git_pass(git_checkout_head(repo, &head_checkout_opts));

	cl_git_pass(git_reference_lookup(&theirs_ref, repo, theirs_branch));
	cl_git_pass(git_annotated_commit_from_ref(&theirs_head, repo, theirs_ref));

	cl_git_pass(git_merge(repo, (const git_annotated_commit **)&theirs_head, 1, merge_opts, checkout_opts));

	git_reference_free(head_ref);
	git_reference_free(theirs_ref);
	git_annotated_commit_free(theirs_head);

	return 0;
}
Exemplo n.º 20
0
void GitRepository::branch(const QString& name)
{
    git_repository* repo = repository();
    git_auto<git_reference> branch;

    int err = git_branch_lookup(&branch, repo, name.toLatin1(), GIT_BRANCH_LOCAL);
    if (err == GIT_ENOTFOUND){
        git_oid parent_id;
        git_auto<git_commit> parent;

        git_eval(git_reference_name_to_id(&parent_id, repo, "HEAD"));
        git_eval(git_commit_lookup(&parent, repo, &parent_id));
        git_eval(git_branch_create(&branch, repo, name.toLocal8Bit(), parent, 1));
    }else{
        git_eval(err);
    }

    git_eval(git_repository_set_head(repo, git_reference_name(branch)));

    git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
    opts.checkout_strategy = GIT_CHECKOUT_FORCE;

    git_eval(git_checkout_head(repo, &opts));
}
Exemplo n.º 21
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__detect_crlf_autocrlf_true_utf8(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	git_repository_set_head(g_repo, "refs/heads/utf8");
	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_LF)
	{
		check_file_contents("./crlf/few-utf8-chars-lf.txt", FEW_UTF8_LF_RAW);
		check_file_contents("./crlf/many-utf8-chars-lf.txt", MANY_UTF8_LF_RAW);
	}
	else
	{
		check_file_contents("./crlf/few-utf8-chars-lf.txt", FEW_UTF8_CRLF_RAW);
		check_file_contents("./crlf/many-utf8-chars-lf.txt", MANY_UTF8_CRLF_RAW);
	}

	check_file_contents("./crlf/few-utf8-chars-crlf.txt", FEW_UTF8_CRLF_RAW);
	check_file_contents("./crlf/many-utf8-chars-crlf.txt", MANY_UTF8_CRLF_RAW);
}
Exemplo n.º 22
0
int cmd_checkout(git_repository *repo, int argc, char **argv)
{
	int i, err, rc;
	char *branch;
	git_reference *branch_ref;
	git_checkout_options checkout_opts;

	branch = NULL;
	rc = EXIT_FAILURE;

	for (i=1;i<argc;i++)
	{
		if (argv[i][0] != '-')
		{
			if (!branch) branch = argv[i];
		} else
		{
		}
	}

	if (!branch)
	{
		fprintf (stderr, "USAGE: %s <branch>\n", argv[0]);
		return -1;
	}

	/* Try local branch */
	if (git_branch_lookup(&branch_ref,repo,branch,GIT_BRANCH_LOCAL) != 0)
	{
		/* No, try remote branch */
		git_reference *remote_branch_ref;
		char remote_buf[256];
		snprintf(remote_buf,sizeof(remote_buf),"%s/%s","origin",branch);
		if (git_branch_lookup(&remote_branch_ref, repo, remote_buf, GIT_BRANCH_REMOTE) == 0)
		{
			/* Exists, now try to create a local one from that reference */
			if ((err = git2_create_branch_from_ref(&branch_ref,remote_branch_ref,repo,branch)) != 0)
			{
				fprintf(stderr,"Error code %d\n",err);
				libgit_error();
				goto out;
			}
			git_reference_free(remote_branch_ref);
		} else
		{
			branch_ref = NULL;
		}
	}

	printf("Checking out %s\n",branch_ref?git_reference_name(branch_ref):branch);
	if ((err = git_repository_set_head(repo,branch_ref?git_reference_name(branch_ref):branch)) != 0)
	{
		fprintf(stderr,"Error code %d\n",err);
		libgit_error();
		goto out;
	}

	/* Default options. Note by default we perform a dry checkout */
	memset(&checkout_opts,0,sizeof(checkout_opts));
	checkout_opts.version = GIT_CHECKOUT_OPTIONS_VERSION;
	checkout_opts.notify_cb = notify_cb;

	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE|GIT_CHECKOUT_REMOVE_UNTRACKED;//GIT_CHECKOUT_SAFE|GIT_CHECKOUT_UPDATE_UNTRACKED;
	if (git_checkout_head(repo,&checkout_opts) != 0)
	{
		libgit_error();
		goto out;
	}

	rc = EXIT_SUCCESS;
out:
	if (branch_ref)
		git_reference_free(branch_ref);

	return rc;
}
Exemplo n.º 23
0
bool Masterlist::Update(const boost::filesystem::path& path, const std::string& repoUrl, const std::string& repoBranch) {
  GitHelper git;
  fs::path repoPath = path.parent_path();
  string filename = path.filename().string();

  if (repoUrl.empty() || repoBranch.empty())
    throw std::invalid_argument("Repository URL and branch must not be empty.");

// Initialise checkout options.
  BOOST_LOG_TRIVIAL(debug) << "Setting up checkout options.";
  char * paths = new char[filename.length() + 1];
  strcpy(paths, filename.c_str());
  git.GetData().checkout_options.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_DONT_REMOVE_EXISTING;
  git.GetData().checkout_options.paths.strings = &paths;
  git.GetData().checkout_options.paths.count = 1;

  // Initialise clone options.
  git.GetData().clone_options.checkout_opts = git.GetData().checkout_options;
  git.GetData().clone_options.bare = 0;
  git.GetData().clone_options.checkout_branch = repoBranch.c_str();

  // Now try to access the repository if it exists, or clone one if it doesn't.
  BOOST_LOG_TRIVIAL(trace) << "Attempting to open the Git repository at: " << repoPath;
  if (!git.IsRepository(repoPath))
    git.Clone(repoPath, repoUrl);
  else {
      // Repository exists: check settings are correct, then pull updates.
    git.SetErrorMessage((boost::format(translate("An error occurred while trying to access the local masterlist repository. If this error happens again, try deleting the \".git\" folder in %1%.")) % repoPath.string()).str());

    // Open the repository.
    BOOST_LOG_TRIVIAL(info) << "Existing repository found, attempting to open it.";
    git.Call(git_repository_open(&git.GetData().repo, repoPath.string().c_str()));

    // Set the remote URL.
    BOOST_LOG_TRIVIAL(info) << "Using remote URL: " << repoUrl;
    git.Call(git_remote_set_url(git.GetData().repo, "origin", repoUrl.c_str()));

    // Now fetch updates from the remote.
    git.Fetch("origin");

    // Check that a local branch with the correct name exists.
    git.SetErrorMessage((boost::format(translate("An error occurred while trying to access the local masterlist repository. If this error happens again, try deleting the \".git\" folder in %1%.")) % repoPath.string()).str());
    int ret = git_branch_lookup(&git.GetData().reference, git.GetData().repo, repoBranch.c_str(), GIT_BRANCH_LOCAL);
    if (ret == GIT_ENOTFOUND)
        // Branch doesn't exist. Create a new branch using the remote branch's latest commit.
      git.CheckoutNewBranch("origin", repoBranch);
    else {
        // The local branch exists. Need to merge the remote branch
        // into it.
      git.Call(ret);  // Handle other errors from preceding branch lookup.

      // Check if HEAD points to the desired branch and set it to if not.
      if (!git_branch_is_head(git.GetData().reference)) {
        BOOST_LOG_TRIVIAL(trace) << "Setting HEAD to follow branch: " << repoBranch;
        git.Call(git_repository_set_head(git.GetData().repo, (string("refs/heads/") + repoBranch).c_str()));
      }

      // Get remote branch reference.
      git.Call(git_branch_upstream(&git.GetData().reference2, git.GetData().reference));

      BOOST_LOG_TRIVIAL(trace) << "Checking HEAD and remote branch's mergeability.";
      git_merge_analysis_t analysis;
      git_merge_preference_t pref;
      git.Call(git_annotated_commit_from_ref(&git.GetData().annotated_commit, git.GetData().repo, git.GetData().reference2));
      git.Call(git_merge_analysis(&analysis, &pref, git.GetData().repo, (const git_annotated_commit **)&git.GetData().annotated_commit, 1));

      if ((analysis & GIT_MERGE_ANALYSIS_FASTFORWARD) == 0 && (analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) == 0) {
          // The local branch can't be easily merged. Best just to delete and recreate it.
        BOOST_LOG_TRIVIAL(trace) << "Local branch cannot be easily merged with remote branch.";

        BOOST_LOG_TRIVIAL(trace) << "Deleting the local branch.";
        git.Call(git_branch_delete(git.GetData().reference));

        // Need to free ref before calling git.CheckoutNewBranch()
        git_reference_free(git.GetData().reference);
        git.GetData().reference = nullptr;
        git_reference_free(git.GetData().reference2);
        git.GetData().reference2 = nullptr;

        git.CheckoutNewBranch("origin", repoBranch);
      } else {
          // Get remote branch commit ID.
        git.Call(git_reference_peel(&git.GetData().object, git.GetData().reference2, GIT_OBJ_COMMIT));
        const git_oid * remote_commit_id = git_object_id(git.GetData().object);

        git_object_free(git.GetData().object);
        git.GetData().object = nullptr;
        git_reference_free(git.GetData().reference2);
        git.GetData().reference2 = nullptr;

        bool updateBranchHead = true;
        if ((analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE) != 0) {
            // No merge is required, but HEAD might be ahead of the remote branch. Check
            // to see if that's the case, and move HEAD back to match the remote branch
            // if so.
          BOOST_LOG_TRIVIAL(trace) << "Local branch is up-to-date with remote branch.";
          BOOST_LOG_TRIVIAL(trace) << "Checking to see if local and remote branch heads are equal.";

          // Get local branch commit ID.
          git.Call(git_reference_peel(&git.GetData().object, git.GetData().reference, GIT_OBJ_COMMIT));
          const git_oid * local_commit_id = git_object_id(git.GetData().object);

          git_object_free(git.GetData().object);
          git.GetData().object = nullptr;

          updateBranchHead = local_commit_id->id != remote_commit_id->id;

          // If the masterlist in
          // HEAD also matches the masterlist file, no further
          // action needs to be taken. Otherwise, a checkout
          // must be performed and the checked-out file parsed.
          if (!updateBranchHead) {
            BOOST_LOG_TRIVIAL(trace) << "Local and remote branch heads are equal.";
            if (!GitHelper::IsFileDifferent(repoPath, filename)) {
              BOOST_LOG_TRIVIAL(info) << "Local branch and masterlist file are already up to date.";
              return false;
            }
          } else
            BOOST_LOG_TRIVIAL(trace) << "Local branch heads is ahead of remote branch head.";
        } else
          BOOST_LOG_TRIVIAL(trace) << "Local branch can be fast-forwarded to remote branch.";

        if (updateBranchHead) {
            // The remote branch reference points to a particular
            // commit. Update the local branch reference to point
            // to the same commit.
          BOOST_LOG_TRIVIAL(trace) << "Syncing local branch head with remote branch head.";
          git.Call(git_reference_set_target(&git.GetData().reference2, git.GetData().reference, remote_commit_id, "Setting branch reference."));

          git_reference_free(git.GetData().reference2);
          git.GetData().reference2 = nullptr;
        }

        git_reference_free(git.GetData().reference);
        git.GetData().reference = nullptr;

        BOOST_LOG_TRIVIAL(trace) << "Performing a Git checkout of HEAD.";
        git.Call(git_checkout_head(git.GetData().repo, &git.GetData().checkout_options));
      }
    }
  }

  // Now whether the repository was cloned or updated, the working directory contains
  // the latest masterlist. Try parsing it: on failure, detach the HEAD back one commit
  // and try again.

  bool parsingFailed = false;
  std::string parsingError;
  git.SetErrorMessage((boost::format(translate("An error occurred while trying to read information on the updated masterlist. If this error happens again, try deleting the \".git\" folder in %1%.")) % repoPath.string()).str());
  do {
      // Get the HEAD revision's short ID.
    string revision = git.GetHeadShortId();

    //Now try parsing the masterlist.
    BOOST_LOG_TRIVIAL(debug) << "Testing masterlist parsing.";
    try {
      this->Load(path);

      parsingFailed = false;
    } catch (std::exception& e) {
      parsingFailed = true;
      if (parsingError.empty())
        parsingError = boost::locale::translate("Masterlist revision").str() +
        " " + string(revision) +
        ": " + e.what() +
        ". " +
        boost::locale::translate("The latest masterlist revision contains a syntax error, LOOT is using the most recent valid revision instead. Syntax errors are usually minor and fixed within hours.").str();

    //There was an error, roll back one revision.
      BOOST_LOG_TRIVIAL(error) << "Masterlist parsing failed. Masterlist revision " + string(revision) + ": " + e.what();
      git.CheckoutRevision("HEAD^");
    }
  } while (parsingFailed);

  if (!parsingError.empty())
    AppendMessage(Message(MessageType::error, parsingError));

  return true;
}
Exemplo n.º 24
0
void test_checkout_head__checking_out_an_orphaned_head_returns_GIT_EORPHANEDHEAD(void)
{
	make_head_orphaned(g_repo, NON_EXISTING_HEAD);

	cl_assert_equal_i(GIT_EORPHANEDHEAD, git_checkout_head(g_repo, NULL));
}
Exemplo n.º 25
0
static void
checkout(git_repository *repo)
{
	git_reference *master_ref, *remote_ref, *HEAD_ref, *tmpr;
	git_checkout_options co_opts;
	const char *remote_br_name;
	git_commit *remote_commit;
	git_object *remote_obj;
	char *remotebr;
	int rc;

	remotebr = NULL;
	xasprintf(&remotebr, "refs/remotes/%s/%s", option_origin,
	    option_trunk);

	rc = git_reference_lookup(&remote_ref, repo, remotebr);
	if (rc)
		die("git_reference_lookup(%s): %d", remotebr, rc);

	rc = git_branch_name(&remote_br_name, remote_ref);
	if (rc)
		die("git_branch_name: %d", rc);

	rc = git_reference_peel(&remote_obj, remote_ref, GIT_OBJ_COMMIT);
	if (rc)
		die("git_reference_peel");

	rc = git_commit_lookup(&remote_commit, repo,
	    git_object_id(remote_obj));
	if (rc)
		die("git_commit_lookup");

	rc = git_branch_create(&master_ref, repo, "master", remote_commit,
	    false, NULL, NULL);
	if (rc)
		die("git_branch_create: %d", rc);

	rc = git_reference_symbolic_create(&HEAD_ref, repo, "HEAD",
	    "refs/heads/master", false, NULL, NULL);
	if (rc && rc != GIT_EEXISTS)
		die("git_reference_symbolic_create: %d", rc);

	rc = git_branch_set_upstream(master_ref, remote_br_name);
	if (rc)
		/* TODO: '' is not a valid remote name */
#if 0
		die("git_branch_set_upstream: %d (%d/%s)", rc,
		    giterr_last()->klass, giterr_last()->message);
#else
		printf("XXXgit_branch_set_upstream: %d (%d/%s)\n", rc,
		    giterr_last()->klass, giterr_last()->message);
#endif

	rc = git_reference_lookup(&tmpr, repo, "refs/heads/master");
	if (rc)
		die("%s: reference_lookup: master doesn't exist?", __func__);
	if (git_reference_cmp(tmpr, master_ref) != 0)
		die("mismatched master");

	co_opts = (git_checkout_options) GIT_CHECKOUT_OPTIONS_INIT;
	co_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	rc = git_checkout_head(repo, &co_opts);
	if (rc)
		die("git_checkout_head");

	free(remotebr);
	git_commit_free(remote_commit);
	git_object_free(remote_obj);
	git_reference_free(tmpr);
	git_reference_free(HEAD_ref);
	git_reference_free(master_ref);
	git_reference_free(remote_ref);
}
Exemplo n.º 26
0
Arquivo: crlf.c Projeto: 1336/libgit2
void test_checkout_crlf__with_ident(void)
{
	git_index *index;
	git_blob *blob;
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_mkfile("crlf/.gitattributes",
		"*.txt text\n*.bin binary\n"
		"*.crlf text eol=crlf\n"
		"*.lf text eol=lf\n"
		"*.ident text ident\n"
		"*.identcrlf ident text eol=crlf\n"
		"*.identlf ident text eol=lf\n");

	cl_repo_set_bool(g_repo, "core.autocrlf", true);

	/* add files with $Id$ */

	cl_git_mkfile("crlf/lf.ident", ALL_LF_TEXT_RAW "\n$Id: initial content$\n");
	cl_git_mkfile("crlf/crlf.ident", ALL_CRLF_TEXT_RAW "\r\n$Id$\r\n\r\n");
	cl_git_mkfile("crlf/more1.identlf", "$Id$\n" MORE_LF_TEXT_RAW);
	cl_git_mkfile("crlf/more2.identcrlf", "\r\n$Id: $\r\n" MORE_CRLF_TEXT_RAW);

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_add_bypath(index, "lf.ident"));
	cl_git_pass(git_index_add_bypath(index, "crlf.ident"));
	cl_git_pass(git_index_add_bypath(index, "more1.identlf"));
	cl_git_pass(git_index_add_bypath(index, "more2.identcrlf"));
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "Some ident files\n");

	git_checkout_head(g_repo, &opts);

	/* check that blobs have $Id$ */

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "lf.ident", 0)->id));
	cl_assert_equal_s(
		ALL_LF_TEXT_RAW "\n$Id$\n", git_blob_rawcontent(blob));
	git_blob_free(blob);

	cl_git_pass(git_blob_lookup(&blob, g_repo,
		& git_index_get_bypath(index, "more2.identcrlf", 0)->id));
	cl_assert_equal_s(
		"\n$Id$\n" MORE_CRLF_TEXT_AS_LF, git_blob_rawcontent(blob));
	git_blob_free(blob);

	/* check that filesystem is initially untouched - matching core Git */

	cl_assert_equal_file(
		ALL_LF_TEXT_RAW "\n$Id: initial content$\n", 0, "crlf/lf.ident");

	/* check that forced checkout rewrites correctly */

	p_unlink("crlf/lf.ident");
	p_unlink("crlf/crlf.ident");
	p_unlink("crlf/more1.identlf");
	p_unlink("crlf/more2.identcrlf");

	git_checkout_head(g_repo, &opts);

	if (GIT_EOL_NATIVE == GIT_EOL_LF) {
		cl_assert_equal_file(
			ALL_LF_TEXT_RAW
			"\n$Id: fcf6d4d9c212dc66563b1171b1cd99953c756467 $\n",
			0, "crlf/lf.ident");
		cl_assert_equal_file(
			ALL_CRLF_TEXT_AS_LF
			"\n$Id: f2c66ad9b2b5a734d9bf00d5000cc10a62b8a857 $\n\n",
			0, "crlf/crlf.ident");
	} else {
		cl_assert_equal_file(
			ALL_LF_TEXT_AS_CRLF
			"\r\n$Id: fcf6d4d9c212dc66563b1171b1cd99953c756467 $\r\n",
			0, "crlf/lf.ident");
		cl_assert_equal_file(
			ALL_CRLF_TEXT_RAW
			"\r\n$Id: f2c66ad9b2b5a734d9bf00d5000cc10a62b8a857 $\r\n\r\n",
			0, "crlf/crlf.ident");
	}

	cl_assert_equal_file(
		"$Id: f7830382dac1f1583422be5530fdfbd26289431b $\n"
		MORE_LF_TEXT_AS_LF, 0, "crlf/more1.identlf");

	cl_assert_equal_file(
		"\r\n$Id: 74677a68413012ce8d7e7cfc3f12603df3a3eac4 $\r\n"
		MORE_CRLF_TEXT_AS_CRLF, 0, "crlf/more2.identcrlf");

	git_index_free(index);
}