// 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; }
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); }
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; }
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; }
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); }
Diff& Diff::merge(Diff const & other) { git_diff_merge(diff_, other.diff_); return *this; }
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); }
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); }