Beispiel #1
0
PyObject *
Diff_find_similar(Diff *self, PyObject *args)
{
    int err;
    git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;

    if (!PyArg_ParseTuple(args, "|i", &opts.flags))
        return NULL;

    err = git_diff_find_similar(self->list, &opts);
    if (err < 0)
        return Error_set(err);

    Py_RETURN_NONE;
}
Beispiel #2
0
static void diff_stats_from_commit_oid(
	git_diff_stats **stats, const char *oidstr, bool rename)
{
	git_oid oid;
	git_commit *commit;
	git_diff *diff;

	git_oid_fromstr(&oid, oidstr);
	cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
	cl_git_pass(git_diff__commit(&diff, _repo, commit, NULL));
	if (rename)
		cl_git_pass(git_diff_find_similar(diff, NULL));
	cl_git_pass(git_diff_get_stats(stats, diff));

	git_diff_free(diff);
	git_commit_free(commit);
}
Beispiel #3
0
PyObject *
Diff_find_similar(Diff *self, PyObject *args, PyObject *kwds)
{
    int err;
    git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;

    char *keywords[] = {"flags", "rename_threshold", "copy_threshold", "rename_from_rewrite_threshold", "break_rewrite_threshold", "rename_limit", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iHHHHI", keywords,
                &opts.flags, &opts.rename_threshold, &opts.copy_threshold, &opts.rename_from_rewrite_threshold, &opts.break_rewrite_threshold, &opts.rename_limit))
        return NULL;

    err = git_diff_find_similar(self->diff, &opts);
    if (err < 0)
        return Error_set(err);

    Py_RETURN_NONE;
}
Beispiel #4
0
static void test_tree_to_tree_computed_to_parsed(
	const char *sandbox, const char *a_id, const char *b_id,
	uint32_t diff_flags, uint32_t find_flags)
{
	git_repository *repo;
	git_diff *computed, *parsed;
	git_tree *a, *b;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
	git_buf computed_buf = GIT_BUF_INIT;

	repo = cl_git_sandbox_init(sandbox);

	opts.id_abbrev = GIT_OID_HEXSZ;
	opts.flags = GIT_DIFF_SHOW_BINARY | diff_flags;
	findopts.flags = find_flags;

	cl_assert((a = resolve_commit_oid_to_tree(repo, a_id)) != NULL);
	cl_assert((b = resolve_commit_oid_to_tree(repo, b_id)) != NULL);

	cl_git_pass(git_diff_tree_to_tree(&computed, repo, a, b, &opts));

	if (find_flags)
		cl_git_pass(git_diff_find_similar(computed, &findopts));

	cl_git_pass(git_diff_to_buf(&computed_buf,
		computed, GIT_DIFF_FORMAT_PATCH));

	cl_git_pass(git_diff_from_buffer(&parsed,
		computed_buf.ptr, computed_buf.size));

	diff_assert_equal(computed, parsed);

	git_tree_free(a);
	git_tree_free(b);

	git_diff_free(computed);
	git_diff_free(parsed);

	git_buf_free(&computed_buf);

	cl_git_sandbox_cleanup();
}
Beispiel #5
0
Datei: diff.c Projekt: jwes/luagi
int luagi_diff_find_similar( lua_State *L )
{
   git_diff **diff = checkdiff_at( L, 1 );

   luaL_checktype( L, 2, LUA_TTABLE );
   git_diff_find_options options;
   if( luagi_diff_find_init_options( L, 2, &options ) ) 
   {
      const git_error *err = giterr_last();
      luaL_error( L, err->message );
   }

   if( git_diff_find_similar( *diff, &options ) )
   {
      const git_error *err = giterr_last();
      luaL_error( L, err->message );
   }
   return 0;
}
Beispiel #6
0
int lg2_diff(git_repository *repo, int argc, char *argv[])
{
	git_tree *t1 = NULL, *t2 = NULL;
	git_diff *diff;
	struct opts o = {
		GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
		-1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
	};

	parse_opts(&o, argc, argv);

	/**
	 * Possible argument patterns:
	 *
	 *  * &lt;sha1&gt; &lt;sha2&gt;
	 *  * &lt;sha1&gt; --cached
	 *  * &lt;sha1&gt;
	 *  * --cached
	 *  * --nocache (don't use index data in diff at all)
	 *  * nothing
	 *
	 * Currently ranged arguments like &lt;sha1&gt;..&lt;sha2&gt; and &lt;sha1&gt;...&lt;sha2&gt;
	 * are not supported in this example
	 */

	if (o.treeish1)
		treeish_to_tree(&t1, repo, o.treeish1);
	if (o.treeish2)
		treeish_to_tree(&t2, repo, o.treeish2);

	if (t1 && t2)
		check_lg2(
			git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts),
			"diff trees", NULL);
	else if (o.cache != CACHE_NORMAL) {
		if (!t1)
			treeish_to_tree(&t1, repo, "HEAD");

		if (o.cache == CACHE_NONE)
			check_lg2(
				git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts),
				"diff tree to working directory", NULL);
		else
			check_lg2(
				git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts),
				"diff tree to index", NULL);
	}
	else if (t1)
		check_lg2(
			git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts),
			"diff tree to working directory", NULL);
	else
		check_lg2(
			git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts),
			"diff index to working directory", NULL);

	/** Apply rename and copy detection if requested. */

	if ((o.findopts.flags & GIT_DIFF_FIND_ALL) != 0)
		check_lg2(
			git_diff_find_similar(diff, &o.findopts),
			"finding renames and copies", NULL);

	/** Generate simple output using libgit2 display helper. */

	if (!o.output)
		o.output = OUTPUT_DIFF;

	if (o.output != OUTPUT_DIFF)
		diff_print_stats(diff, &o);

	if ((o.output & OUTPUT_DIFF) != 0) {
		if (o.color >= 0)
			fputs(colors[0], stdout);

		check_lg2(
			git_diff_print(diff, o.format, color_printer, &o.color),
			"displaying diff", NULL);

		if (o.color >= 0)
			fputs(colors[0], stdout);
	}

	/** Cleanup before exiting. */
	git_diff_free(diff);
	git_tree_free(t1);
	git_tree_free(t2);

	return 0;
}
Beispiel #7
0
static git_blame__origin* find_origin(
		git_blame *blame,
		git_commit *parent,
		git_blame__origin *origin)
{
	git_blame__origin *porigin = NULL;
	git_diff *difflist = NULL;
	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
	git_tree *otree=NULL, *ptree=NULL;

	/* Get the trees from this commit and its parent */
	if (0 != git_commit_tree(&otree, origin->commit) ||
	    0 != git_commit_tree(&ptree, parent))
		goto cleanup;

	/* Configure the diff */
	diffopts.context_lines = 0;
	diffopts.flags = GIT_DIFF_SKIP_BINARY_CHECK;

	/* Check to see if files we're interested have changed */
	diffopts.pathspec.count = blame->paths.length;
	diffopts.pathspec.strings = (char**)blame->paths.contents;
	if (0 != git_diff_tree_to_tree(&difflist, blame->repository, ptree, otree, &diffopts))
			goto cleanup;

	if (!git_diff_num_deltas(difflist)) {
		/* No changes; copy data */
		git_blame__get_origin(&porigin, blame, parent, origin->path);
	} else {
		git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
		int i;

		/* Generate a full diff between the two trees */
		git_diff_free(difflist);
		diffopts.pathspec.count = 0;
		if (0 != git_diff_tree_to_tree(&difflist, blame->repository, ptree, otree, &diffopts))
			goto cleanup;

		/* Let diff find renames */
		findopts.flags = GIT_DIFF_FIND_RENAMES;
		if (0 != git_diff_find_similar(difflist, &findopts))
			goto cleanup;

		/* Find one that matches */
		for (i=0; i<(int)git_diff_num_deltas(difflist); i++) {
			const git_diff_delta *delta = git_diff_get_delta(difflist, i);

			if (!git_vector_bsearch(NULL, &blame->paths, delta->new_file.path))
			{
				git_vector_insert_sorted(&blame->paths, (void*)git__strdup(delta->old_file.path),
						paths_on_dup);
				make_origin(&porigin, parent, delta->old_file.path);
			}
		}
	}

cleanup:
	git_diff_free(difflist);
	git_tree_free(otree);
	git_tree_free(ptree);
	return porigin;
}
Beispiel #8
0
static void test_with_many(int expected_new)
{
	git_index *index;
	git_tree *tree, *new_tree;
	git_diff *diff = NULL;
	diff_expects exp;
	git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(
		git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));

	cl_git_pass(p_rename("renames/ikeepsix.txt", "renames/ikeepsix2.txt"));
	cl_git_pass(git_index_remove_bypath(index, "ikeepsix.txt"));
	cl_git_pass(git_index_add_bypath(index, "ikeepsix2.txt"));
	cl_git_pass(git_index_write(index));

	cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, diff_file_cb, NULL, NULL, NULL, &exp));
	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
	cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(expected_new + 2, exp.files);

	opts.flags = GIT_DIFF_FIND_ALL;
	cl_git_pass(git_diff_find_similar(diff, &opts));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, diff_file_cb, NULL, NULL, NULL, &exp));
	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
	cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(expected_new + 1, exp.files);

	git_diff_free(diff);

	cl_repo_commit_from_index(NULL, g_repo, NULL, 1372350000, "yoyoyo");
	cl_git_pass(git_revparse_single(
		(git_object **)&new_tree, g_repo, "HEAD^{tree}"));

	cl_git_pass(git_diff_tree_to_tree(
		&diff, g_repo, tree, new_tree, &diffopts));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, diff_file_cb, NULL, NULL, NULL, &exp));
	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
	cl_assert_equal_i(expected_new + 1, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(expected_new + 2, exp.files);

	opts.flags = GIT_DIFF_FIND_ALL;
	cl_git_pass(git_diff_find_similar(diff, &opts));

	memset(&exp, 0, sizeof(exp));
	cl_git_pass(git_diff_foreach(
		diff, diff_file_cb, NULL, NULL, NULL, &exp));
	cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
	cl_assert_equal_i(expected_new, exp.file_status[GIT_DELTA_ADDED]);
	cl_assert_equal_i(expected_new + 1, exp.files);

	git_diff_free(diff);

	git_tree_free(new_tree);
	git_tree_free(tree);
	git_index_free(index);
}