int git_object_lookup_bypath( git_object **out, const git_object *treeish, const char *path, git_otype type) { int error = -1; git_tree *tree = NULL; git_tree_entry *entry = NULL; assert(out && treeish && path); if ((error = git_object_peel((git_object**)&tree, treeish, GIT_OBJ_TREE)) < 0 || (error = git_tree_entry_bypath(&entry, tree, path)) < 0) { goto cleanup; } if (type != GIT_OBJ_ANY && git_tree_entry_type(entry) != type) { giterr_set(GITERR_OBJECT, "object at path '%s' is not of the asked-for type %d", path, type); error = GIT_EINVALIDSPEC; goto cleanup; } error = git_tree_entry_to_object(out, git_object_owner(treeish), entry); cleanup: git_tree_entry_free(entry); git_tree_free(tree); return error; }
static VALUE rb_git_treeentry_fromC(const git_tree_entry *entry) { VALUE rb_entry; VALUE type; if (!entry) return Qnil; rb_entry = rb_hash_new(); rb_hash_aset(rb_entry, CSTR2SYM("name"), rugged_str_new2(git_tree_entry_name(entry), NULL)); rb_hash_aset(rb_entry, CSTR2SYM("oid"), rugged_create_oid(git_tree_entry_id(entry))); rb_hash_aset(rb_entry, CSTR2SYM("filemode"), INT2FIX(git_tree_entry_filemode(entry))); switch(git_tree_entry_type(entry)) { case GIT_OBJ_TREE: type = CSTR2SYM("tree"); break; case GIT_OBJ_BLOB: type = CSTR2SYM("blob"); break; default: type = Qnil; break; } rb_hash_aset(rb_entry, CSTR2SYM("type"), type); return rb_entry; }
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 void assert_workdir_matches_tree( git_repository *repo, const git_oid *id, const char *root, bool recurse) { git_object *obj; git_tree *tree; size_t i, max_i; git_buf path = GIT_BUF_INIT; if (!root) root = git_repository_workdir(repo); cl_assert(root); cl_git_pass(git_object_lookup(&obj, repo, id, GIT_OBJ_ANY)); cl_git_pass(git_object_peel((git_object **)&tree, obj, GIT_OBJ_TREE)); git_object_free(obj); max_i = git_tree_entrycount(tree); for (i = 0; i < max_i; ++i) { const git_tree_entry *te = git_tree_entry_byindex(tree, i); cl_assert(te); cl_git_pass(git_buf_joinpath(&path, root, git_tree_entry_name(te))); switch (git_tree_entry_type(te)) { case GIT_OBJ_COMMIT: assert_dir_exists(path.ptr); break; case GIT_OBJ_TREE: assert_dir_exists(path.ptr); if (recurse) assert_workdir_matches_tree( repo, git_tree_entry_id(te), path.ptr, true); break; case GIT_OBJ_BLOB: switch (git_tree_entry_filemode(te)) { case GIT_FILEMODE_BLOB: case GIT_FILEMODE_BLOB_EXECUTABLE: assert_file_exists(path.ptr); /* because of cross-platform, don't confirm exec bit yet */ break; case GIT_FILEMODE_LINK: cl_assert_(git_path_exists(path.ptr), path.ptr); /* because of cross-platform, don't confirm link yet */ break; default: cl_assert(false); /* really?! */ } break; default: cl_assert(false); /* really?!! */ } } git_tree_free(tree); git_buf_free(&path); }
PyObject * TreeEntry_repr(TreeEntry *self) { char str[GIT_OID_HEXSZ + 1] = { 0 }; const char *typename; typename = git_object_type2string(git_tree_entry_type(self->entry)); git_oid_fmt(str, git_tree_entry_id(self->entry)); return PyString_FromFormat("pygit2.TreeEntry('%s', %s, %s)", git_tree_entry_name(self->entry), typename, str); }
static int rugged__treecount_cb(const char *root, const git_tree_entry *entry, void *data) { struct rugged_treecount_cb_payload *payload = data; if (payload->limit >= 0 && payload->count >= payload->limit) { return -1; } else if(git_tree_entry_type(entry) == GIT_OBJ_TREE) { return 0; } else { ++(payload->count); return 1; } }
/** Show each entry with its type, id and attributes */ static void show_tree(const git_tree *tree) { size_t i, max_i = (int)git_tree_entrycount(tree); char oidstr[GIT_OID_HEXSZ + 1]; const git_tree_entry *te; for (i = 0; i < max_i; ++i) { te = git_tree_entry_byindex(tree, i); git_oid_tostr(oidstr, sizeof(oidstr), git_tree_entry_id(te)); printf("%06o %s %s\t%s\n", git_tree_entry_filemode(te), git_object_type2string(git_tree_entry_type(te)), oidstr, git_tree_entry_name(te)); } }
static int checksum_tree_callback (const char *root, const git_tree_entry *entry, void *data) { int iter_r = 1; int tmp_r; struct TreeWalkData *twdata = data; git_otype otype = git_tree_entry_type (entry); switch (otype) { case GIT_OBJ_TREE: case GIT_OBJ_BLOB: if (!checksum_object_id (twdata, git_tree_entry_id (entry), twdata->error)) { twdata->caught_error = TRUE; return -1; } break; case GIT_OBJ_COMMIT: { git_submodule *submod = NULL; tmp_r = git_submodule_lookup (&submod, twdata->repo, git_tree_entry_name (entry)); if (!handle_libgit_ret (tmp_r, twdata->error)) goto out; tmp_r = checksum_submodule (twdata, submod); if (tmp_r != 0) goto out; git_submodule_free (submod); } break; default: g_assert_not_reached (); } iter_r = 0; out: if (iter_r > 0) twdata->caught_error = TRUE; return iter_r; }
int read_repo(const char *repo_name) { int i; int r; int n; git_repository *repo; git_reference *head; git_oid oid; git_commit *commit; git_tree *tree; git_tree_entry *tree_entry; char out[41]; out[40] = '\0'; // opening the repository r = git_repository_open(&repo, repo_name); if (r) printf("error in opening the repository\n"); printf("Opened the repository successfully.\n"); // obtaining the head r = git_repository_head(&head, repo); if (r) printf("error in obtaining the head\n"); r = git_reference_name_to_oid(&oid, repo, git_reference_name(head)); if (r) printf("error in obtaining the ref id of head\n"); printf("Obtained the head id %s\n", git_oid_tostr(out, 41, &oid)); // obtaining the commit from commit id r = git_commit_lookup(&commit, repo, &oid); if (r) printf("error in obtaining the commit from oid\n"); printf("Obtained the commit.\n"); // obtaining the tree id from the commit oid = *git_commit_tree_oid(commit); // get the tree r = git_tree_lookup(&tree, repo, &oid); if (r) printf("error in looking up the tree for oid\n"); printf("Lookup for tree of oid successful.\n"); n = git_tree_entrycount(tree); for (i=0; i<n; i++) { tree_entry = git_tree_entry_byindex(tree, i); printf("entry >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %s %s\n", git_tree_entry_name(tree_entry), git_object_type2string(git_tree_entry_type(tree_entry))); } git_repository_free(repo); return 0; }
int CRepositoryBrowser::ReadTree(CShadowFilesTree * treeroot, const CString& root) { CWaitCursor wait; CAutoRepository repository(g_Git.GetGitRepository()); if (!repository) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } if (m_sRevision == _T("HEAD")) { int ret = git_repository_head_unborn(repository); if (ret == 1) // is orphan return ret; else if (ret != 0) { MessageBox(g_Git.GetLibGit2LastErr(_T("Could not check HEAD.")), _T("TortoiseGit"), MB_ICONERROR); return ret; } } CGitHash hash; if (CGit::GetHash(repository, hash, m_sRevision)) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not get hash of ") + m_sRevision + _T(".")), _T("TortoiseGit"), MB_ICONERROR); return -1; } CAutoCommit commit; if (git_commit_lookup(commit.GetPointer(), repository, (git_oid *)hash.m_hash)) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup commit.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } CAutoTree tree; if (git_commit_tree(tree.GetPointer(), commit)) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not get tree of commit.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } if (!root.IsEmpty()) { CAutoTreeEntry treeEntry; if (git_tree_entry_bypath(treeEntry.GetPointer(), tree, CUnicodeUtils::GetUTF8(root))) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } if (git_tree_entry_type(treeEntry) != GIT_OBJ_TREE) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } CAutoObject object; if (git_tree_entry_to_object(object.GetPointer(), repository, treeEntry)) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup path.")), _T("TortoiseGit"), MB_ICONERROR); return -1; } tree = (git_tree*)object.Detach(); } treeroot->m_hash = CGitHash((char *)git_tree_id(tree)->id); ReadTreeRecursive(*repository, tree, treeroot); // try to resolve hash to a branch name if (m_sRevision == hash.ToString()) { MAP_HASH_NAME map; if (CGit::GetMapHashToFriendName(repository, map)) MessageBox(g_Git.GetLibGit2LastErr(_T("Could not get all refs.")), _T("TortoiseGit"), MB_ICONERROR); if (!map[hash].empty()) m_sRevision = map[hash].at(0); } this->GetDlgItem(IDC_BUTTON_REVISION)->SetWindowText(m_sRevision); return 0; }
PyObject * TreeEntry_type__get__(TreeEntry *self) { return to_path(git_object_type2string(git_tree_entry_type(self->entry))); }
/** * Merges two tree objects, producing a third tree. * The base tree allows the algorithm to distinguish between adds and deletes. * The algorithm always prefers the item from tree 1 when there is a conflict. */ static int sync_merge_trees(git_oid *out, git_repository *repo, const git_oid *base_id, const git_oid *id1, const git_oid *id2) { int e = 0; git_tree *base_tree = NULL; git_tree *tree1 = NULL; git_tree *tree2 = NULL; git_treebuilder *tb = NULL; size_t size1, size2; size_t i1 = 0; size_t i2 = 0; const git_tree_entry *e1 = NULL; const git_tree_entry *e2 = NULL; enum { ONLY1 = 1, ONLY2 = 2, BOTH = 3 } state = BOTH; git_check(git_tree_lookup(&base_tree, repo, base_id)); git_check(git_tree_lookup(&tree1, repo, id1)); git_check(git_tree_lookup(&tree2, repo, id2)); git_check(git_treebuilder_new(&tb, repo, NULL)); size1 = git_tree_entrycount(tree1); size2 = git_tree_entrycount(tree2); while (1) { // Advance to next file: if (state == ONLY1 || state == BOTH) { e1 = i1 < size1 ? git_tree_entry_byindex(tree1, i1++) : NULL; } if (state == ONLY2 || state == BOTH) { e2 = i2 < size2 ? git_tree_entry_byindex(tree2, i2++) : NULL; } // Determine state: if (e1 && e2) { int s = strcmp(git_tree_entry_name(e1), git_tree_entry_name(e2)); state = s < 0 ? ONLY1 : s > 0 ? ONLY2 : BOTH; } else if (e1 && !e2) { state = ONLY1; } else if (!e1 && e2) { state = ONLY2; } else { break; } // Grab the entry in question: const git_tree_entry *entry = (state == ONLY1 || state == BOTH) ? e1 : e2; const git_tree_entry *base_entry = git_tree_entry_byname(base_tree, git_tree_entry_name(entry)); // Decide what to do with the entry: if (state == BOTH && base_entry && GIT_OBJ_TREE == git_tree_entry_type(e1) && GIT_OBJ_TREE == git_tree_entry_type(e2) && GIT_OBJ_TREE == git_tree_entry_type(base_entry)) { // Merge sub-trees: git_oid new_tree; git_check(sync_merge_trees(&new_tree, repo, git_tree_entry_id(base_entry), git_tree_entry_id(e1), git_tree_entry_id(e2))); git_check(git_treebuilder_insert(NULL, tb, git_tree_entry_name(e1), &new_tree, git_tree_entry_filemode(e1))); } else if (state == BOTH && base_entry) { if (git_oid_cmp(git_tree_entry_id(base_entry), git_tree_entry_id(e1))) { // Entry `e1` has changes, so use that: git_check(git_treebuilder_insert(NULL, tb, git_tree_entry_name(e1), git_tree_entry_id(e1), git_tree_entry_filemode(e1))); } else { // Entry `e1` has no changes, so use `e2`: git_check(git_treebuilder_insert(NULL, tb, git_tree_entry_name(e2), git_tree_entry_id(e2), git_tree_entry_filemode(e2))); } } else if (state == BOTH || !base_entry) { // Entry was added, or already present: git_check(git_treebuilder_insert(NULL, tb, git_tree_entry_name(entry), git_tree_entry_id(entry), git_tree_entry_filemode(entry))); } // Otherwise, the entry was deleted. } // Write tree: git_check(git_treebuilder_write(out, tb)); exit: if (base_tree) git_tree_free(base_tree); if (tree1) git_tree_free(tree1); if (tree2) git_tree_free(tree2); if (tb) git_treebuilder_free(tb); return e; }
static int mne_git_tree_entry_cb(const char *root, git_tree_entry *entry, void *arg) { mne_git_walk_ctx *ctx = (mne_git_walk_ctx*)arg; git_otype type = git_tree_entry_type(entry); if (likely(type == GIT_OBJ_BLOB)) { const git_oid *blob_oid = git_tree_entry_id(entry); char *sha1 = malloc(sizeof(char) * GIT_OID_HEXSZ + 1); assert(sha1 != NULL); git_oid_tostr(sha1, GIT_OID_HEXSZ + 1, blob_oid); git_odb_object *blob_odb_object; git_odb_read(&blob_odb_object, odb, blob_oid); gpointer blob = g_hash_table_lookup(blobs, (gpointer)sha1); char **sha1_refs; if (blob == NULL) { ctx->distinct_blobs++; char *tmp_data = (char*)git_odb_object_data(blob_odb_object); int data_len = strlen(tmp_data); char *data = malloc(sizeof(char) * (data_len + 1)); memcpy(data, tmp_data, data_len); data[data_len] = 0; assert((strlen(root) + strlen(git_tree_entry_name(entry))) < MNE_MAX_PATH_LENGTH); char *path = malloc(sizeof(char) * MNE_MAX_PATH_LENGTH); assert(path != NULL); strcpy(path, root); strcat(path, git_tree_entry_name(entry)); /* TOOD: Check that the blob <-> path mapping is 1-1. */ g_hash_table_insert(paths, (gpointer)sha1, (gpointer)path); g_hash_table_insert(blobs, (gpointer)sha1, (gpointer)data); ctx->bytes += (unsigned long)(sizeof(char) * strlen(data)); sha1_refs = malloc(sizeof(char*) * total_refs); assert(sha1_refs != NULL); int i; for (i = 0; i < total_refs; i++) sha1_refs[i] = NULL; g_hash_table_insert(refs, (gpointer)sha1, (gpointer)sha1_refs); } else { sha1_refs = g_hash_table_lookup(refs, (gpointer)sha1); free(sha1); } git_odb_object_free(blob_odb_object); int i; for (i = 0; i < total_refs; i++) { if (sha1_refs[i] != NULL) continue; sha1_refs[i] = ctx->ref_name; break; } } return GIT_OK; }