Пример #1
0
Файл: diff.c Проект: jwes/luagi
// diff functions
int luagi_diff_merge( lua_State *L )
{
   git_diff **diff = checkdiff_at( L, 1 );
   git_diff **from = checkdiff_at( L, 2 );
   if( git_diff_merge( *diff, *from ) )
   {
      const git_error *err = giterr_last();
      luaL_error(L, err->message );
   }
   return 0; 
}
Пример #2
0
void test_diff_tree__merge(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "605812a";
	const char *b_commit = "370fe9ec22";
	const char *c_commit = "f5b0af1fb4f5c";
	git_tree *a, *b, *c;
	git_diff_list *diff1 = NULL, *diff2 = NULL;
	diff_expects exp;

	g_repo = cl_git_sandbox_init("attr");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);

	cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, a, b, &diff1));

	cl_git_pass(git_diff_tree_to_tree(g_repo, NULL, c, b, &diff2));

	git_tree_free(a);
	git_tree_free(b);
	git_tree_free(c);

	cl_git_pass(git_diff_merge(diff1, diff2));

	git_diff_list_free(diff2);

	memset(&exp, 0, sizeof(exp));

	cl_git_pass(git_diff_foreach(
		diff1, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert_equal_i(6, exp.files);
	cl_assert_equal_i(2, exp.file_adds);
	cl_assert_equal_i(1, exp.file_dels);
	cl_assert_equal_i(3, exp.file_mods);

	cl_assert_equal_i(6, exp.hunks);

	cl_assert_equal_i(59, exp.lines);
	cl_assert_equal_i(1, exp.line_ctxt);
	cl_assert_equal_i(36, exp.line_adds);
	cl_assert_equal_i(22, exp.line_dels);

	git_diff_list_free(diff1);
}
Пример #3
0
static int build_workdir_tree(
	git_tree **tree_out,
	git_index *index,
	git_commit *b_commit)
{
	git_repository *repo = git_index_owner(index);
	git_tree *b_tree = NULL;
	git_diff_list *diff = NULL, *diff2 = NULL;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	struct cb_data data = {0};
	int error;

	if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
		goto cleanup;

	if ((error = git_diff_tree_to_index(&diff, repo, b_tree, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_index_to_workdir(&diff2, repo, NULL, &opts)) < 0)
		goto cleanup;

	if ((error = git_diff_merge(diff, diff2)) < 0)
		goto cleanup;

	data.index = index;
	data.include_changed = true;

	if ((error = git_diff_foreach(
			diff, update_index_cb, NULL, NULL, &data)) < 0)
	{
		if (error == GIT_EUSER)
			error = data.error;
		goto cleanup;
	}


	if ((error = build_tree_from_index(tree_out, index)) < 0)
		goto cleanup;

cleanup:
	git_diff_list_free(diff);
	git_diff_list_free(diff2);
	git_tree_free(b_tree);

	return error;
}
Пример #4
0
PyObject *
Diff_merge(Diff *self, PyObject *args)
{
    Diff *py_diff;
    int err;

    if (!PyArg_ParseTuple(args, "O!", &DiffType, &py_diff))
        return NULL;

    if (py_diff->repo->repo != self->repo->repo)
        return Error_set(GIT_ERROR);

    err = git_diff_merge(self->list, py_diff->list);
    if (err < 0)
        return Error_set(err);

    Py_RETURN_NONE;
}
Пример #5
0
void test_diff_tree__merge(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "605812a";
	const char *b_commit = "370fe9ec22";
	const char *c_commit = "f5b0af1fb4f5c";
	git_tree *c;
	git_diff *diff1 = NULL, *diff2 = NULL;

	g_repo = cl_git_sandbox_init("attr");

	cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
	cl_assert((c = resolve_commit_oid_to_tree(g_repo, c_commit)) != NULL);

	cl_git_pass(git_diff_tree_to_tree(&diff1, g_repo, a, b, NULL));

	cl_git_pass(git_diff_tree_to_tree(&diff2, g_repo, c, b, NULL));

	git_tree_free(c);

	cl_git_pass(git_diff_merge(diff1, diff2));

	git_diff_free(diff2);

	cl_git_pass(git_diff_foreach(
		diff1, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expect));

	cl_assert_equal_i(6, expect.files);
	cl_assert_equal_i(2, expect.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(1, expect.file_status[GIT_DELTA_DELETED]);
	cl_assert_equal_i(3, expect.file_status[GIT_DELTA_MODIFIED]);

	cl_assert_equal_i(6, expect.hunks);

	cl_assert_equal_i(59, expect.lines);
	cl_assert_equal_i(1, expect.line_ctxt);
	cl_assert_equal_i(36, expect.line_adds);
	cl_assert_equal_i(22, expect.line_dels);

	git_diff_free(diff1);
}
Пример #6
0
 Diff& Diff::merge(Diff const & other)
 {
     git_diff_merge(diff_, other.diff_);
     return *this;
 }
Пример #7
0
void test_diff_workdir__to_tree(void)
{
	/* grabbed a couple of commit oids from the history of the attr repo */
	const char *a_commit = "26a125ee1bf"; /* the current HEAD */
	const char *b_commit = "0017bd4ab1ec3"; /* the start */
	git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
	git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
	git_diff_options opts = {0};
	git_diff_list *diff = NULL;
	git_diff_list *diff2 = NULL;
	diff_expects exp;

	opts.context_lines = 3;
	opts.interhunk_lines = 1;
	opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;

	memset(&exp, 0, sizeof(exp));

	/* You can't really generate the equivalent of git_diff_workdir_to_tree()
	 * using C git.  It really wants to interpose the index into the diff.
	 *
	 * To validate the following results with command line git, I ran the
	 * following:
	 * - git ls-tree 26a125
	 * - find . ! -path ./.git/\* -a -type f | git hash-object --stdin-paths
	 * The results are documented at the bottom of this file in the
	 * long comment entitled "PREPARATION OF TEST DATA".
	 */
	cl_git_pass(git_diff_workdir_to_tree(g_repo, &opts, a, &diff));

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 13);
	cl_assert(exp.file_adds == 0);
	cl_assert(exp.file_dels == 4);
	cl_assert(exp.file_mods == 4);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 4);

	/* Since there is no git diff equivalent, let's just assume that the
	 * text diffs produced by git_diff_foreach are accurate here.  We will
	 * do more apples-to-apples test comparison below.
	 */

	git_diff_list_free(diff);
	diff = NULL;
	memset(&exp, 0, sizeof(exp));

	/* This is a compatible emulation of "git diff <sha>" which looks like
	 * a workdir to tree diff (even though it is not really).  This is what
	 * you would get from "git diff --name-status 26a125ee1bf"
	 */
	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, a, &diff));
	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2));
	cl_git_pass(git_diff_merge(diff, diff2));
	git_diff_list_free(diff2);

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 14);
	cl_assert(exp.file_adds == 2);
	cl_assert(exp.file_dels == 5);
	cl_assert(exp.file_mods == 4);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 2);

	cl_assert(exp.hunks == 11);

	cl_assert(exp.lines == 17);
	cl_assert(exp.line_ctxt == 4);
	cl_assert(exp.line_adds == 8);
	cl_assert(exp.line_dels == 5);

	git_diff_list_free(diff);
	diff = NULL;
	memset(&exp, 0, sizeof(exp));

	/* Again, emulating "git diff <sha>" for testing purposes using
	 * "git diff --name-status 0017bd4ab1ec3" instead.
	 */
	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, b, &diff));
	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff2));
	cl_git_pass(git_diff_merge(diff, diff2));
	git_diff_list_free(diff2);

	cl_git_pass(git_diff_foreach(
		diff, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

	cl_assert(exp.files == 15);
	cl_assert(exp.file_adds == 5);
	cl_assert(exp.file_dels == 4);
	cl_assert(exp.file_mods == 3);
	cl_assert(exp.file_ignored == 1);
	cl_assert(exp.file_untracked == 2);

	cl_assert(exp.hunks == 12);

	cl_assert(exp.lines == 19);
	cl_assert(exp.line_ctxt == 3);
	cl_assert(exp.line_adds == 12);
	cl_assert(exp.line_dels == 4);

	git_diff_list_free(diff);

	git_tree_free(a);
	git_tree_free(b);
}
Пример #8
0
void test_diff_workdir__head_index_and_workdir_all_differ(void)
{
	git_diff_options opts = {0};
	git_diff_list *diff_i2t = NULL, *diff_w2i = NULL;
	diff_expects exp;
	char *pathspec = "staged_changes_modified_file";
	git_tree *tree;
	int use_iterator;

	/* For this file,
	 * - head->index diff has 1 line of context, 1 line of diff
	 * - index->workdir diff has 2 lines of context, 1 line of diff
	 * but
	 * - head->workdir diff has 1 line of context, 2 lines of diff
	 * Let's make sure the right one is returned from each fn.
	 */

	g_repo = cl_git_sandbox_init("status");

	tree = resolve_commit_oid_to_tree(g_repo, "26a125ee1bfc5df1e1b2e9441bbe63c8a7ae989f");

	opts.pathspec.strings = &pathspec;
	opts.pathspec.count   = 1;

	cl_git_pass(git_diff_index_to_tree(g_repo, &opts, tree, &diff_i2t));
	cl_git_pass(git_diff_workdir_to_index(g_repo, &opts, &diff_w2i));

	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
		memset(&exp, 0, sizeof(exp));

		if (use_iterator)
			cl_git_pass(diff_foreach_via_iterator(
				diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
		else
			cl_git_pass(git_diff_foreach(
				diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

		cl_assert_equal_i(1, exp.files);
		cl_assert_equal_i(0, exp.file_adds);
		cl_assert_equal_i(0, exp.file_dels);
		cl_assert_equal_i(1, exp.file_mods);
		cl_assert_equal_i(1, exp.hunks);
		cl_assert_equal_i(2, exp.lines);
		cl_assert_equal_i(1, exp.line_ctxt);
		cl_assert_equal_i(1, exp.line_adds);
		cl_assert_equal_i(0, exp.line_dels);
	}

	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
		memset(&exp, 0, sizeof(exp));

		if (use_iterator)
			cl_git_pass(diff_foreach_via_iterator(
				diff_w2i, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
		else
			cl_git_pass(git_diff_foreach(
				diff_w2i, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

		cl_assert_equal_i(1, exp.files);
		cl_assert_equal_i(0, exp.file_adds);
		cl_assert_equal_i(0, exp.file_dels);
		cl_assert_equal_i(1, exp.file_mods);
		cl_assert_equal_i(1, exp.hunks);
		cl_assert_equal_i(3, exp.lines);
		cl_assert_equal_i(2, exp.line_ctxt);
		cl_assert_equal_i(1, exp.line_adds);
		cl_assert_equal_i(0, exp.line_dels);
	}

	cl_git_pass(git_diff_merge(diff_i2t, diff_w2i));

	for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
		memset(&exp, 0, sizeof(exp));

		if (use_iterator)
			cl_git_pass(diff_foreach_via_iterator(
				diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));
		else
			cl_git_pass(git_diff_foreach(
				diff_i2t, &exp, diff_file_fn, diff_hunk_fn, diff_line_fn));

		cl_assert_equal_i(1, exp.files);
		cl_assert_equal_i(0, exp.file_adds);
		cl_assert_equal_i(0, exp.file_dels);
		cl_assert_equal_i(1, exp.file_mods);
		cl_assert_equal_i(1, exp.hunks);
		cl_assert_equal_i(3, exp.lines);
		cl_assert_equal_i(1, exp.line_ctxt);
		cl_assert_equal_i(2, exp.line_adds);
		cl_assert_equal_i(0, exp.line_dels);
	}

	git_diff_list_free(diff_i2t);
	git_diff_list_free(diff_w2i);

	git_tree_free(tree);
}