std::vector<std::string> Commit::getAffectedFiles() const { git_tree* tree = nullptr; git_tree* tree2 = nullptr; int error = git_commit_tree(&tree, get()); throw_on_error(error); try { error = git_commit_tree(&tree2, parent(0).get()); } catch (GitException e) { tree2 = nullptr; // probably initial commit } git_diff* diff = nullptr; git_diff_tree_to_tree(&diff, getRepo(), tree2, tree, 0); std::vector<std::string> ret; git_diff_foreach(diff, [](const git_diff_delta* entry, float progress, void* payload) { std::string str = entry->old_file.path; ((std::vector<std::string>*)payload)->push_back(str); return 0; }, nullptr, nullptr, &ret); git_tree_free(tree); git_tree_free(tree2); git_diff_free(diff); return ret; }
static int rebase_next_inmemory( git_rebase_operation **out, git_rebase *rebase) { git_commit *current_commit = NULL, *parent_commit = NULL; git_tree *current_tree = NULL, *head_tree = NULL, *parent_tree = NULL; git_rebase_operation *operation; git_index *index = NULL; unsigned int parent_count; int error; *out = NULL; operation = git_array_get(rebase->operations, rebase->current); if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 || (error = git_commit_tree(¤t_tree, current_commit)) < 0) goto done; if ((parent_count = git_commit_parentcount(current_commit)) > 1) { giterr_set(GITERR_REBASE, "Cannot rebase a merge commit"); error = -1; goto done; } else if (parent_count) { if ((error = git_commit_parent(&parent_commit, current_commit, 0)) < 0 || (error = git_commit_tree(&parent_tree, parent_commit)) < 0) goto done; } if ((error = git_commit_tree(&head_tree, rebase->last_commit)) < 0 || (error = git_merge_trees(&index, rebase->repo, parent_tree, head_tree, current_tree, &rebase->options.merge_options)) < 0) goto done; if (!rebase->index) { rebase->index = index; index = NULL; } else { if ((error = git_index_read_index(rebase->index, index)) < 0) goto done; } *out = operation; done: git_commit_free(current_commit); git_commit_free(parent_commit); git_tree_free(current_tree); git_tree_free(head_tree); git_tree_free(parent_tree); git_index_free(index); return error; }
void test_core_merge__initialize(void) { //TODO: Change this path and IDs - can use the code in // utils/src/get_commit_info to get the tree ids. git_repository_open(&repo, REPODIR); head_commit = commit_from_ref("branch_a"); branch_commit = commit_from_ref("branch_b"); base_commit = commit_from_ref("a_b_merge_base"); git_commit_tree((git_tree**)&head_tree, head_commit); git_commit_tree((git_tree**)&branch_tree, branch_commit); git_commit_tree((git_tree**)&base_tree, base_commit); }
void test_patch( const char *one, const char *two, const git_diff_options *opts, const char *expected) { git_oid id_one, id_two; git_index *index = NULL; git_commit *commit_one, *commit_two = NULL; git_tree *tree_one, *tree_two; git_diff *diff; git_patch *patch; git_buf actual = GIT_BUF_INIT; cl_git_pass(git_oid_fromstr(&id_one, one)); cl_git_pass(git_commit_lookup(&commit_one, repo, &id_one)); cl_git_pass(git_commit_tree(&tree_one, commit_one)); if (two) { cl_git_pass(git_oid_fromstr(&id_two, two)); cl_git_pass(git_commit_lookup(&commit_two, repo, &id_two)); cl_git_pass(git_commit_tree(&tree_two, commit_two)); } else { cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_write_tree(&id_two, index)); cl_git_pass(git_tree_lookup(&tree_two, repo, &id_two)); } cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree_one, tree_two, opts)); cl_git_pass(git_patch_from_diff(&patch, diff, 0)); cl_git_pass(git_patch_to_buf(&actual, patch)); cl_assert_equal_s(expected, actual.ptr); git_buf_clear(&actual); cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual)); cl_assert_equal_s(expected, actual.ptr); git_buf_dispose(&actual); git_patch_free(patch); git_diff_free(diff); git_tree_free(tree_one); git_tree_free(tree_two); git_commit_free(commit_one); git_commit_free(commit_two); git_index_free(index); }
void Commit::buildTree() { git_tree *gitTree; gitTest(git_commit_tree (&gitTree, commit)); commitTree = new Tree (repo, gitTree); }
// ReadTree is/must only be executed on an empty list int CGitHeadFileList::ReadTree() { CAutoWriteLock lock(m_SharedMutex); ATLASSERT(empty()); CAutoRepository repository(m_Gitdir); CAutoCommit commit; CAutoTree tree; bool ret = repository; ret = ret && !git_commit_lookup(commit.GetPointer(), repository, (const git_oid*)m_Head.m_hash); ret = ret && !git_commit_tree(tree.GetPointer(), commit); try { ret = ret && !ReadTreeRecursive(*repository, tree, "", CGitHeadFileList::CallBack, this); } catch (const std::bad_alloc& ex) { CTraceToOutputDebugString::Instance()(__FUNCTION__ ": Catched exception inside ReadTreeRecursive: %s\n", ex.what()); return -1; } if (!ret) { clear(); m_LastModifyTimeHead = 0; return -1; } std::sort(this->begin(), this->end(), SortTree); m_TreeHash = git_commit_id(commit)->id; return 0; }
PyObject * Commit_tree__get__(Commit *commit) { git_tree *tree; Tree *py_tree; int err; err = git_commit_tree(&tree, commit->commit); if (err == GIT_ENOTFOUND) { char tree_id[GIT_OID_HEXSZ + 1] = { 0 }; git_oid_fmt(tree_id, git_commit_tree_id(commit->commit)); return PyErr_Format(GitError, "Unable to read tree %s", tree_id); } if (err < 0) return Error_set(err); py_tree = PyObject_New(Tree, &TreeType); if (py_tree) { Py_INCREF(commit->repo); py_tree->repo = commit->repo; py_tree->tree = (git_tree*)tree; } return (PyObject*)py_tree; }
static void execute_test(void) { git_oid oid, check; git_commit *commit; git_tree *tree; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/branch1")); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); cl_git_pass(git_commit_tree(&tree, commit)); opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_checkout_tree(g_repo, (git_object *)tree, &opts)); git_tree_free(tree); git_commit_free(commit); /* Verify that the lenna.jpg file was checked out correctly */ cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1")); cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJ_BLOB)); cl_assert(git_oid_equal(&oid, &check)); /* Verify that the text file was checked out correctly */ cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a")); cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJ_BLOB)); cl_assert(git_oid_equal(&oid, &check)); }
static int mne_git_get_tag_tree(git_tree **tag_tree, git_reference **tag_ref, const char *ref_name) { int err = git_reference_lookup(tag_ref, repo, ref_name); mne_check_error("git_reference_lookup()", err, __FILE__, __LINE__); const git_oid *tag_oid = git_reference_oid(*tag_ref); assert(tag_oid != NULL); git_tag *tag; err = git_tag_lookup(&tag, repo, tag_oid); const git_oid *tag_commit_oid; if (err == GIT_ENOTFOUND) { /* Not a tag, must be a commit. */ tag_commit_oid = tag_oid; } else { err = mne_git_get_tag_commit_oid(&tag_commit_oid, tag); git_tag_free(tag); if (err != GIT_OK) return err; } git_commit *tag_commit; err = git_commit_lookup(&tag_commit, repo, tag_commit_oid); mne_check_error("git_commit_lookup()", err, __FILE__, __LINE__); err = git_commit_tree(tag_tree, tag_commit); mne_check_error("git_commit_tree()", err, __FILE__, __LINE__); git_commit_free(tag_commit); return MNE_GIT_OK; }
void test_diff_binary__empty_for_no_diff(void) { git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_oid id; git_commit *commit; git_tree *tree; git_diff *diff; git_buf actual = GIT_BUF_INIT; opts.flags = GIT_DIFF_SHOW_BINARY | GIT_DIFF_FORCE_BINARY; opts.id_abbrev = GIT_OID_HEXSZ; repo = cl_git_sandbox_init("renames"); cl_git_pass(git_oid_fromstr(&id, "19dd32dfb1520a64e5bbaae8dce6ef423dfa2f13")); cl_git_pass(git_commit_lookup(&commit, repo, &id)); cl_git_pass(git_commit_tree(&tree, commit)); cl_git_pass(git_diff_tree_to_tree(&diff, repo, tree, tree, &opts)); cl_git_pass(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, git_diff_print_callback__to_buf, &actual)); cl_assert_equal_s("", actual.ptr); git_buf_dispose(&actual); git_diff_free(diff); git_commit_free(commit); git_tree_free(tree); }
int git_cherry_pick_commit( git_index **out, git_repository *repo, git_commit *cherry_pick_commit, git_commit *our_commit, unsigned int mainline, const git_merge_options *merge_opts) { git_commit *parent_commit = NULL; git_tree *parent_tree = NULL, *our_tree = NULL, *cherry_pick_tree = NULL; int parent = 0, error = 0; assert(out && repo && cherry_pick_commit && our_commit); if (git_commit_parentcount(cherry_pick_commit) > 1) { if (!mainline) return cherry_pick_seterr(cherry_pick_commit, "Mainline branch is not specified but %s is a merge commit"); parent = mainline; } else { if (mainline) return cherry_pick_seterr(cherry_pick_commit, "Mainline branch specified but %s is not a merge commit"); parent = git_commit_parentcount(cherry_pick_commit); } if (parent && ((error = git_commit_parent(&parent_commit, cherry_pick_commit, (parent - 1))) < 0 || (error = git_commit_tree(&parent_tree, parent_commit)) < 0)) goto done; if ((error = git_commit_tree(&cherry_pick_tree, cherry_pick_commit)) < 0 || (error = git_commit_tree(&our_tree, our_commit)) < 0) goto done; error = git_merge_trees(out, repo, parent_tree, our_tree, cherry_pick_tree, merge_opts); done: git_tree_free(parent_tree); git_tree_free(our_tree); git_tree_free(cherry_pick_tree); git_commit_free(parent_commit); return error; }
Diff::Diff(const Commit& comm, const Commit& comm2) { git_tree *commit_tree = nullptr, *parent_tree = nullptr; int error = 0; error = git_commit_tree(&commit_tree, comm.get()); throw_on_error(error); error = git_commit_tree(&parent_tree, comm2.get()); throw_on_error(error); git_diff *d = nullptr; error = git_diff_tree_to_tree( &d, comm.getRepo(), commit_tree, parent_tree, nullptr); throw_on_error(error); // TODO: Make this exception safe git_tree_free(commit_tree); git_tree_free(parent_tree); diff = std::shared_ptr<git_diff>(d, git_diff_free); }
static int read_file_git(const char *repo_path, const char *name, void **out, size_t *outlen) { int ret, retcode = -1; git_repository *repo; ret = git_repository_open_bare(&repo, repo_path); if(check_lg2(ret, "opening repo")) goto out; git_object *master; ret = git_revparse_single(&master, repo, "master"); if(check_lg2(ret, "getting master branch")) goto out_repo; if(git_object_type(master) != GIT_OBJ_COMMIT) { debug("master is not a commit"); goto out_master; } git_tree *tree; ret = git_commit_tree(&tree, (git_commit*)master); if(check_lg2(ret, "getting tree from commit")) goto out_master; const git_tree_entry *entry = git_tree_entry_byname(tree, name); if(!entry) { debug("entry %s not found", name); goto out_tree; } if(git_tree_entry_type(entry) != GIT_OBJ_BLOB) { debug("entry is not a blob"); goto out_tree; } git_object *file; ret = git_tree_entry_to_object(&file, repo, entry); if(check_lg2(ret, "getting file from tree entry")) goto out_tree; const void *data = git_blob_rawcontent((git_blob*)file); *outlen = git_blob_rawsize((git_blob*)file); *out = malloc(*outlen); memcpy(*out, data, *outlen); retcode = 0; git_object_free(file); out_tree: git_tree_free(tree); out_master: git_object_free(master); out_repo: git_repository_free(repo); out: return retcode; }
static VALUE rb_git_commit_tree_GET(VALUE self) { git_commit *commit; const git_tree *tree; Data_Get_Struct(self, git_commit, commit); tree = git_commit_tree(commit); return tree ? rugged_object_c2rb((git_object *)tree) : Qnil; }
int merge_trees_from_branches( git_index **index, git_repository *repo, const char *ours_name, const char *theirs_name, git_merge_tree_opts *opts) { git_commit *our_commit, *their_commit, *ancestor_commit = NULL; git_tree *our_tree, *their_tree, *ancestor_tree = NULL; git_oid our_oid, their_oid, ancestor_oid; git_buf branch_buf = GIT_BUF_INIT; int error; git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name); cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); git_buf_clear(&branch_buf); git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr)); cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid)); error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)); if (error != GIT_ENOTFOUND) { cl_git_pass(error); cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)); cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit)); } cl_git_pass(git_commit_tree(&our_tree, our_commit)); cl_git_pass(git_commit_tree(&their_tree, their_commit)); cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts)); git_buf_free(&branch_buf); git_tree_free(our_tree); git_tree_free(their_tree); git_tree_free(ancestor_tree); git_commit_free(our_commit); git_commit_free(their_commit); git_commit_free(ancestor_commit); return 0; }
static VALUE rb_git_commit_tree_GET(VALUE self) { git_commit *commit; const git_tree *tree; VALUE owner; RUGGED_OBJ_UNWRAP(self, git_commit, commit); RUGGED_OBJ_OWNER(self, owner); tree = git_commit_tree(commit); return tree ? rugged_object_new(owner, (git_object *)tree) : Qnil; }
void test_apply_both__generated_diff(void) { git_oid a_oid, b_oid; git_commit *a_commit, *b_commit; git_tree *a_tree, *b_tree; git_diff *diff; git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; struct merge_index_entry both_expected[] = { { 0100644, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", 0, "asparagus.txt" }, { 0100644, "68f6182f4c85d39e1309d97c7e456156dc9c0096", 0, "beef.txt" }, { 0100644, "4b7c5650008b2e747fe1809eeb5a1dde0e80850a", 0, "bouilli.txt" }, { 0100644, "c4e6cca3ec6ae0148ed231f97257df8c311e015f", 0, "gravy.txt" }, { 0100644, "68af1fc7407fd9addf1701a87eb1c95c7494c598", 0, "oyster.txt" }, { 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" }, }; size_t both_expected_cnt = sizeof(both_expected) / sizeof(struct merge_index_entry); git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"); git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid)); cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid)); cl_git_pass(git_commit_tree(&a_tree, a_commit)); cl_git_pass(git_commit_tree(&b_tree, b_commit)); cl_git_pass(git_diff_tree_to_tree(&diff, repo, a_tree, b_tree, &diff_opts)); cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL)); validate_apply_index(repo, both_expected, both_expected_cnt); validate_apply_workdir(repo, both_expected, both_expected_cnt); git_diff_free(diff); git_tree_free(a_tree); git_tree_free(b_tree); git_commit_free(a_commit); git_commit_free(b_commit); }
static int build_untracked_tree( git_tree **tree_out, git_index *index, git_commit *i_commit, uint32_t flags) { git_tree *i_tree = NULL; git_diff_list *diff = NULL; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; struct cb_data data = {0}; int error; git_index_clear(index); data.index = index; if (flags & GIT_STASH_INCLUDE_UNTRACKED) { opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_RECURSE_UNTRACKED_DIRS; data.include_untracked = true; } if (flags & GIT_STASH_INCLUDE_IGNORED) { opts.flags |= GIT_DIFF_INCLUDE_IGNORED; data.include_ignored = true; } if ((error = git_commit_tree(&i_tree, i_commit)) < 0) goto cleanup; if ((error = git_diff_tree_to_workdir( &diff, git_index_owner(index), i_tree, &opts)) < 0) goto cleanup; if ((error = git_diff_foreach( diff, update_index_cb, NULL, NULL, &data)) < 0) { if (error == GIT_EUSER) error = data.error; goto cleanup; } error = build_tree_from_index(tree_out, index); cleanup: git_diff_list_free(diff); git_tree_free(i_tree); return error; }
// ReadTree is/must only be executed on an empty list int CGitHeadFileList::ReadTree() { CAutoWriteLock lock(&m_SharedMutex); CStringA gitdir = CUnicodeUtils::GetMulti(m_Gitdir, CP_UTF8); git_repository *repository = NULL; git_commit *commit = NULL; git_tree * tree = NULL; int ret = 0; ATLASSERT(this->empty()); do { ret = git_repository_open(&repository, gitdir); if(ret) break; ret = git_commit_lookup(&commit, repository, (const git_oid*)m_Head.m_hash); if(ret) break; ret = git_commit_tree(&tree, commit); if(ret) break; ret = ReadTreeRecursive(*repository, tree,"", CGitHeadFileList::CallBack,this); if(ret) break; std::sort(this->begin(), this->end(), SortTree); this->m_TreeHash = (char*)(git_commit_id(commit)->id); } while(0); if (tree) git_tree_free(tree); if (commit) git_commit_free(commit); if (repository) git_repository_free(repository); if (ret) { clear(); m_LastModifyTimeHead = 0; } return ret; }
/* * call-seq: * commit.tree -> tree * * Return the tree pointed at by this +commit+. The tree is * returned as a +Rugged::Tree+ object. * * commit.tree #=> #<Rugged::Tree:0x10882c680> */ static VALUE rb_git_commit_tree_GET(VALUE self) { git_commit *commit; git_tree *tree; VALUE owner; int error; Data_Get_Struct(self, git_commit, commit); owner = rugged_owner(self); error = git_commit_tree(&tree, commit); rugged_exception_check(error); return rugged_object_new(owner, (git_object *)tree); }
/* Helper to find how many files in a commit changed from its nth parent. */ static int match_with_parent(git_commit *commit, int i, git_diff_options *opts) { git_commit *parent; git_tree *a, *b; git_diff *diff; int ndeltas; check_lg2( git_commit_parent(&parent, commit, (size_t)i), "Get parent", NULL); check_lg2(git_commit_tree(&a, parent), "Tree for parent", NULL); check_lg2(git_commit_tree(&b, commit), "Tree for commit", NULL); check_lg2( git_diff_tree_to_tree(&diff, git_commit_owner(commit), a, b, opts), "Checking diff between parent and commit", NULL); ndeltas = (int)git_diff_num_deltas(diff); git_diff_free(diff); git_tree_free(a); git_tree_free(b); git_commit_free(parent); return ndeltas > 0; }
int luagi_commit_tree( lua_State *L ) { git_commit** commit = checkcommit( L ); git_tree** tree = (git_tree**) lua_newuserdata( L, sizeof( git_tree* ) ); int ret = git_commit_tree( tree, *commit); if( ret != 0 ) { lua_pushnil( L ); lua_pushfstring( L, "can't find tree %d", ret ); return 2; } ltk_setmetatable( L, LUAGI_TREE_FUNCS ); return 1; }
/* Helper to get the latest commit of the specified file */ int git_show_last_commit(char *filename) { git_oid oid; git_commit *commit = NULL; /* Set up pathspec. */ git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT; diffopts.pathspec.strings = &filename; diffopts.pathspec.count = 1; /* Use the revwalker to traverse the history. */ check_lg2(git_revwalk_push_ref(s.walker, s.ref), "Could not find repository reference", NULL); for (; !git_revwalk_next(&oid, s.walker); git_commit_free(commit)) { check_lg2(git_commit_lookup(&commit, s.repo, &oid), "Failed to look up commit", NULL); int parents = (int)git_commit_parentcount(commit); int unmatched = parents; if (parents == 0) { git_tree *tree; git_pathspec *ps; check_lg2(git_commit_tree(&tree, commit), "Get tree", NULL); check_lg2(git_pathspec_new(&ps, &diffopts.pathspec), "Building pathspec", NULL); if (git_pathspec_match_tree( NULL, tree, GIT_PATHSPEC_NO_MATCH_ERROR, ps) != 0) unmatched = 1; git_pathspec_free(ps); git_tree_free(tree); } else { int i; for (i = 0; i < parents; ++i) { if (match_with_parent(commit, i, &diffopts)) unmatched--; } } if (unmatched > 0) continue; print_commit(commit); git_commit_free(commit); break; } git_revwalk_reset(s.walker); return 0; }
static void fill_index_wth_head_entries(git_repository *repo, git_index *index) { git_oid oid; git_commit *commit; git_tree *tree; cl_git_pass(git_reference_name_to_oid(&oid, repo, "HEAD")); cl_git_pass(git_commit_lookup(&commit, repo, &oid)); cl_git_pass(git_commit_tree(&tree, commit)); cl_git_pass(git_index_read_tree(index, tree)); cl_git_pass(git_index_write(index)); git_tree_free(tree); git_commit_free(commit); }
/** * Get the tree pointed to by a commit * * @param commit S4 class git_commit or git_stash * @return S4 class git_tree */ SEXP git2r_commit_tree(SEXP commit) { int err; SEXP result = R_NilValue; SEXP repo; git_commit *commit_obj = NULL; git_repository *repository = NULL; git_tree *tree = NULL; if (git2r_arg_check_commit(commit)) git2r_error(git2r_err_commit_arg, __func__, "commit"); repo = GET_SLOT(commit, Rf_install("repo")); repository = git2r_repository_open(repo); if (!repository) git2r_error(git2r_err_invalid_repository, __func__, NULL); err = git2r_commit_lookup(&commit_obj, repository, commit); if (GIT_OK != err) goto cleanup; err = git_commit_tree(&tree, commit_obj); if (GIT_OK != err) goto cleanup; PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree"))); git2r_tree_init((git_tree*)tree, repo, result); cleanup: if (commit_obj) git_commit_free(commit_obj); if (tree) git_tree_free(tree); if (repository) git_repository_free(repository); if (R_NilValue != result) UNPROTECT(1); if (GIT_OK != err) git2r_error(git2r_err_from_libgit2, __func__, giterr_last()->message); return result; }
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; }
/* * call-seq: * index.diff([options]) -> diff * index.diff(diffable[, options]) -> diff * * The first form returns a diff between the index and the current working * directory. * * The second form returns a diff between the index and the given diffable object. * +diffable+ can either be a +Rugged::Commit+ or a +Rugged::Tree+. * * The index will be used as the "old file" side of the diff, while the working * directory or the +diffable+ will be used for the "new file" side. * * The following options can be passed in the +options+ Hash: * * :paths :: * An array of paths / fnmatch patterns to constrain the diff to a specific * set of files. Also see +:disable_pathspec_match+. * * :max_size :: * An integer specifying the maximum byte size of a file before a it will * be treated as binary. The default value is 512MB. * * :context_lines :: * The number of unchanged lines that define the boundary of a hunk (and * to display before and after the actual changes). The default is 3. * * :interhunk_lines :: * The maximum number of unchanged lines between hunk boundaries before the hunks * will be merged into a one. The default is 0. * * :reverse :: * If true, the sides of the diff will be reversed. * * :force_text :: * If true, all files will be treated as text, disabling binary attributes & detection. * * :ignore_whitespace :: * If true, all whitespace will be ignored. * * :ignore_whitespace_change :: * If true, changes in amount of whitespace will be ignored. * * :ignore_whitespace_eol :: * If true, whitespace at end of line will be ignored. * * :ignore_submodules :: * if true, submodules will be excluded from the diff completely. * * :patience :: * If true, the "patience diff" algorithm will be used (currenlty unimplemented). * * :include_ignored :: * If true, ignored files will be included in the diff. * * :include_untracked :: * If true, untracked files will be included in the diff. * * :include_unmodified :: * If true, unmodified files will be included in the diff. * * :recurse_untracked_dirs :: * Even if +:include_untracked+ is true, untracked directories will only be * marked with a single entry in the diff. If this flag is set to true, * all files under ignored directories will be included in the diff, too. * * :disable_pathspec_match :: * If true, the given +:paths+ will be applied as exact matches, instead of * as fnmatch patterns. * * :deltas_are_icase :: * If true, filename comparisons will be made with case-insensitivity. * * :include_untracked_content :: * if true, untracked content will be contained in the the diff patch text. * * :skip_binary_check :: * If true, diff deltas will be generated without spending time on binary * detection. This is useful to improve performance in cases where the actual * file content difference is not needed. * * :include_typechange :: * If true, type changes for files will not be interpreted as deletion of * the "old file" and addition of the "new file", but will generate * typechange records. * * :include_typechange_trees :: * Even if +:include_typechange+ is true, blob -> tree changes will still * usually be handled as a deletion of the blob. If this flag is set to true, * blob -> tree changes will be marked as typechanges. * * :ignore_filemode :: * If true, file mode changes will be ignored. * * :recurse_ignored_dirs :: * Even if +:include_ignored+ is true, ignored directories will only be * marked with a single entry in the diff. If this flag is set to true, * all files under ignored directories will be included in the diff, too. */ static VALUE rb_git_index_diff(int argc, VALUE *argv, VALUE self) { git_index *index; git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_repository *repo; git_diff *diff = NULL; VALUE owner, rb_other, rb_options; int error; rb_scan_args(argc, argv, "01:", &rb_other, &rb_options); rugged_parse_diff_options(&opts, rb_options); Data_Get_Struct(self, git_index, index); owner = rugged_owner(self); Data_Get_Struct(owner, git_repository, repo); if (NIL_P(rb_other)) { error = git_diff_index_to_workdir(&diff, repo, index, &opts); } else { // Need to flip the reverse option, so that the index is by default // the "old file" side of the diff. opts.flags ^= GIT_DIFF_REVERSE; if (rb_obj_is_kind_of(rb_other, rb_cRuggedCommit)) { git_tree *other_tree; git_commit *commit; Data_Get_Struct(rb_other, git_commit, commit); error = git_commit_tree(&other_tree, commit); if (!error) error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts); } else if (rb_obj_is_kind_of(rb_other, rb_cRuggedTree)) { git_tree *other_tree; Data_Get_Struct(rb_other, git_tree, other_tree); error = git_diff_tree_to_index(&diff, repo, other_tree, index, &opts); } else { xfree(opts.pathspec.strings); rb_raise(rb_eTypeError, "A Rugged::Commit or Rugged::Tree instance is required"); } } xfree(opts.pathspec.strings); rugged_exception_check(error); return rugged_diff_new(rb_cRuggedDiff, owner, diff); }
void test_object_tree_read__largefile(void) { git_reference *ref; git_commit *commit; git_tree *tree; git_oid oid; const git_tree_entry *entry; git_object *object; git_buf file = GIT_BUF_INIT; int fd; git_index *idx; if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE")) cl_skip(); cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/heads/master")); cl_git_pass(git_repository_index(&idx, g_repo)); cl_git_pass(git_buf_puts(&file, git_repository_workdir(g_repo))); cl_git_pass(git_buf_joinpath(&file, file.ptr, BIGFILE)); fd = p_open(git_buf_cstr(&file), O_CREAT|O_RDWR, 0644); cl_assert_(fd >= 0, "invalid file descriptor"); cl_must_pass(p_fallocate(fd, 0, BIGFILE_SIZE)); cl_must_pass(p_close(fd)); cl_git_pass(git_index_add_bypath(idx, BIGFILE)); cl_repo_commit_from_index(&oid, g_repo, NULL, 0, "bigfile"); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); cl_git_pass(git_commit_tree(&tree, commit)); entry = git_tree_entry_byname(tree, BIGFILE); cl_assert_(entry, "entry was NULL"); cl_git_pass(git_tree_entry_to_object(&object, g_repo, entry)); git_buf_dispose(&file); git_object_free(object); git_tree_free(tree); git_index_free(idx); git_commit_free(commit); git_reference_free(ref); }
static int do_git_load(git_repository *repo, const char *branch) { int ret; git_object *object; git_commit *commit; git_tree *tree; ret = find_commit(repo, branch, &commit); if (ret) return ret; if (git_commit_tree(&tree, commit)) return report_error("Could not look up tree of commit in branch '%s'", branch); ret = load_dives_from_tree(repo, tree); if (!ret) set_git_id(git_commit_id(commit)); git_object_free((git_object *)tree); return ret; }
int CGitHeadFileList::ReadTree() { CStringA gitdir = CUnicodeUtils::GetMulti(m_Gitdir,CP_ACP) ; gitdir += "\\.git"; git_repository *repository = NULL; git_commit *commit = NULL; git_tree * tree = NULL; int ret = 0; this->clear(); // hack to avoid duplicates in the head list, which are introduced in GitStatus::GetFileStatus when this method is called do { ret = git_repository_open(&repository, gitdir.GetBuffer()); if(ret) break; ret = git_commit_lookup(&commit, repository, (const git_oid*)m_Head.m_hash); if(ret) break; ret = git_commit_tree(&tree, commit); if(ret) break; ret = ReadTreeRecursive(*repository, tree,"", CGitHeadFileList::CallBack,this); if(ret) break; std::sort(this->begin(), this->end(), SortTree); this->m_TreeHash = (char*)(git_commit_id(commit)->id); } while(0); if (tree) git_tree_free(tree); if (commit) git_commit_free(commit); if (repository) git_repository_free(repository); return ret; }