void test_core_merge__basic_iterator_all(void) { AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_ALL_ENTRIES); cl_assert(it!=NULL); AGBMergeEntry * mergeEntry = agb_merge_entry_from_iterator(it); // Since everything should be sorted alphabetically our first entry in the iterator should be // created_in_a.txt, which should only occur in the head side. // char hexid[GIT_OID_HEXSZ+1] = {0}; char hexid2[GIT_OID_HEXSZ+1] = {0}; cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(head_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_LOCAL))); cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(branch_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_REMOTE))); cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(base_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_BASE))); cl_assert_equal_s("README.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_s("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL))); cl_assert_equal_s("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE))); cl_assert_equal_s("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE))); cl_assert_equal_i(0, agb_merge_iterator_next(it) ); mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s("created_in_a.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_s("6a8f9dc8fbbc0a9c632ff7f58b419ab09f7d49d9", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL))); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE)); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE)); cl_assert_equal_i(0, agb_merge_iterator_next(it) ); mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s("created_in_b.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL)); cl_assert_equal_s("21a97ca7942380e581d314d80aed559be2150219", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE))); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE)); cl_assert_equal_i(0, agb_merge_iterator_next(it) ); mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s("created_in_root.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL))); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE))); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE))); cl_assert_equal_i(0, agb_merge_iterator_next(it) ); mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s("created_in_root_2.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL))); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE))); cl_assert_equal_s("0867712ecec02144b5bf4ee2a59deb0f42b49a53", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE))); cl_assert_equal_i(1, agb_merge_iterator_next(it) ); agb_merge_iterator_free(it); }
int git_commit_create_buffer(git_buf *out, git_repository *repo, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, size_t parent_count, const git_commit *parents[]) { int error; commit_parent_data data = { parent_count, parents, repo }; git_array_oid_t parents_arr = GIT_ARRAY_INIT; const git_oid *tree_id; assert(tree && git_tree_owner(tree) == repo); tree_id = git_tree_id(tree); if ((error = validate_tree_and_parents(&parents_arr, repo, tree_id, commit_parent_from_array, &data, NULL, true)) < 0) return error; error = git_commit__create_buffer_internal( out, author, committer, message_encoding, message, tree_id, &parents_arr); git_array_clear(parents_arr); return error; }
int git_commit_create_v( git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, size_t parent_count, ...) { int error = 0; commit_parent_varargs data; assert(tree && git_tree_owner(tree) == repo); data.total = parent_count; va_start(data.args, parent_count); error = git_commit__create_internal( id, repo, update_ref, author, committer, message_encoding, message, git_tree_id(tree), commit_parent_from_varargs, &data, false); va_end(data.args); return error; }
int git_commit__writeback(git_commit *commit, git_odb_source *src) { unsigned int i; if (commit->tree == NULL) return GIT_EMISSINGOBJDATA; git__write_oid(src, "tree", git_tree_id(commit->tree)); for (i = 0; i < commit->parents.length; ++i) { git_commit *parent; parent = git_vector_get(&commit->parents, i); git__write_oid(src, "parent", git_commit_id(parent)); } if (commit->author == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "author", commit->author); if (commit->committer == NULL) return GIT_EMISSINGOBJDATA; git_signature__write(src, "committer", commit->committer); if (commit->message != NULL) git__source_printf(src, "\n%s", commit->message); /* Mark the commit as having all attributes */ commit->full_parse = 1; return GIT_SUCCESS; }
static void check_tree_entry( git_iterator *i, const char *oid, const char *oid_p, const char *oid_pp, const char *oid_ppp) { const git_index_entry *ie; const git_tree_entry *te; const git_tree *tree; git_buf path = GIT_BUF_INIT; cl_git_pass(git_iterator_current_tree_entry(&te, i)); cl_assert(te); cl_assert(git_oid_streq(te->oid, oid) == 0); cl_git_pass(git_iterator_current(&ie, i)); cl_git_pass(git_buf_sets(&path, ie->path)); if (oid_p) { git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr)); cl_assert(tree); cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0); } if (oid_pp) { git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr)); cl_assert(tree); cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0); } if (oid_ppp) { git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr)); cl_assert(tree); cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0); } git_buf_free(&path); }
static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_pool *pool) { git_repository *repo; size_t i, j, nentries, ntrees; int error; repo = git_tree_owner(tree); git_oid_cpy(&cache->oid, git_tree_id(tree)); nentries = git_tree_entrycount(tree); /* * We make sure we know how many trees we need to allocate for * so we don't have to realloc and change the pointers for the * parents. */ ntrees = 0; for (i = 0; i < nentries; i++) { const git_tree_entry *entry; entry = git_tree_entry_byindex(tree, i); if (git_tree_entry_filemode(entry) == GIT_FILEMODE_TREE) ntrees++; } cache->children_count = ntrees; cache->children = git_pool_mallocz(pool, ntrees * sizeof(git_tree_cache *)); GITERR_CHECK_ALLOC(cache->children); j = 0; for (i = 0; i < nentries; i++) { const git_tree_entry *entry; git_tree *subtree; entry = git_tree_entry_byindex(tree, i); if (git_tree_entry_filemode(entry) != GIT_FILEMODE_TREE) continue; if ((error = git_tree_cache_new(&cache->children[j], git_tree_entry_name(entry), pool)) < 0) return error; if ((error = git_tree_lookup(&subtree, repo, git_tree_entry_id(entry))) < 0) return error; error = read_tree_recursive(cache->children[j], subtree, pool); git_tree_free(subtree); j++; if (error < 0) return error; } return 0; }
void test_core_merge__basic_iterator(void) { AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_NONE); cl_assert(it!=NULL); // Since everything should be sorted alphabetically our first entry in the iterator should be // created_in_a.txt, which should only occur in the head side. // char hexid[GIT_OID_HEXSZ+1] = {0}; char hexid2[GIT_OID_HEXSZ+1] = {0}; AGBMergeEntry * mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(head_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_LOCAL))); cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(branch_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_REMOTE))); cl_assert_equal_s(git_oid_tostr(hexid2, GIT_OID_HEXSZ+1, git_tree_id(base_tree)), git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_iterator_tree_id(it,AGB_MERGE_BASE))); //TODO: How do we handle the case with zero entries. //We probably need a agb_merge_iterator_is_valid(it) //We can then use it like: // // cl_assert_equal_s("created_in_a.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_s("6a8f9dc8fbbc0a9c632ff7f58b419ab09f7d49d9", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL))); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE)); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE)); cl_assert_equal_i(0, agb_merge_iterator_next(it) ); mergeEntry = agb_merge_entry_from_iterator(it); cl_assert_equal_s("created_in_b.txt", agb_merge_entry_name(mergeEntry)); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_LOCAL)); cl_assert_equal_s("21a97ca7942380e581d314d80aed559be2150219", git_oid_tostr(hexid,GIT_OID_HEXSZ+1,agb_merge_entry_id(mergeEntry,AGB_MERGE_REMOTE))); cl_assert_equal_p(NULL, agb_merge_entry_id(mergeEntry,AGB_MERGE_BASE)); cl_assert_equal_i(1, agb_merge_iterator_next(it) ); agb_merge_iterator_free(it); }
/** * ggit_tree_get_id: * @tree: a #GgitTree. * * Get the #GgitOId of the tree. * * Returns: (transfer full): a #GgitOId. * **/ GgitOId * ggit_tree_get_id (GgitTree *tree) { git_tree *t; const git_oid *oid; g_return_val_if_fail (GGIT_IS_TREE (tree), NULL); t = _ggit_native_get (tree); oid = git_tree_id (t); return _ggit_oid_wrap (oid); }
static int prepare_index(git_index *index, char* msg){ git_oid index_tree; git_tree *head_obj; git_reference *head; char tree_str[GIT_OID_HEXSZ+1], parent_str[GIT_OID_HEXSZ+1]; // Get the head OID git_repository_head(&head, repo); git_reference_peel((git_object**)&head_obj, head, GIT_OBJ_COMMIT); git_oid_tostr(parent_str, GIT_OID_HEXSZ+1, git_tree_id(head_obj)); git_reference_free(head); git_object_free((git_object*)head_obj); // Write the coin // TODO: Use C for this? system("perl -i -pe 's/(null:)(\\d+)/$1 . ($2+1)/e' LEDGER.txt"); system("grep -q \"null\" LEDGER.txt || echo \"null:1\" >> LEDGER.txt"); // Update the index check_lg2(git_index_read(index, 0), "Could not re-read index from disk", NULL); check_lg2(git_index_add_bypath(index, "LEDGER.txt"), "Could not add to index", "LEDGER.txt"); // Write the index and get the tree OID git_index_write_tree(&index_tree, index); git_oid_tostr(tree_str, GIT_OID_HEXSZ+1, &index_tree); snprintf(msg, BUFFER_LENGTH, "commit %d%c" "tree %s\n" "parent %s\n" "author null <*****@*****.**> %d +0000\n" "committer null <*****@*****.**> %d +0000\n" "\n" "coins now" "\x01\x01\x01\x01" "\x01\x01\x01\x01" "\x01\x01\x01", // Align 32 bit words on GPU MSG_LENGTH, 0, tree_str, parent_str, (int)time(NULL), (int)time(NULL)); pad_message(msg, COMMIT_LENGTH, BUFFER_LENGTH); return 0; }
int git_commit_create( git_oid *id, git_repository *repo, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree, size_t parent_count, const git_commit *parents[]) { commit_parent_data data = { parent_count, parents, repo }; assert(tree && git_tree_owner(tree) == repo); return git_commit__create_internal( id, repo, update_ref, author, committer, message_encoding, message, git_tree_id(tree), commit_parent_from_array, &data, false); }
static int find_subtree_r(git_tree **out, git_tree *root, git_repository *repo, const char *target, int *fanout) { int error; git_tree *subtree = NULL; *out = NULL; error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout); if (error == GIT_EEXISTS) return git_tree_lookup(out, repo, git_tree_id(root)); if (error < 0) return error; *fanout += 2; error = find_subtree_r(out, subtree, repo, target, fanout); git_tree_free(subtree); return error; }
int CRepositoryBrowser::ReadTree(CShadowFilesTree * treeroot) { CStringA gitdir = CUnicodeUtils::GetMulti(g_Git.m_CurrentDir, CP_UTF8); git_repository *repository = NULL; git_commit *commit = NULL; git_tree * tree = NULL; int ret = 0; do { ret = git_repository_open(&repository, gitdir.GetBuffer()); if (ret) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not open repository.")), _T("TortoiseGit"), MB_ICONERROR); break; } if (m_sRevision == _T("HEAD")) { ret = git_repository_head_unborn(repository); if (ret == 1) // is orphan break; else if (ret != 0) { MessageBox(g_Git.GetLibGit2LastErr(_T("Could not check HEAD.")), _T("TortoiseGit"), MB_ICONERROR); break; } } CGitHash hash; if (g_Git.GetHash(hash, m_sRevision)) { MessageBox(g_Git.GetGitLastErr(_T("Could not get hash of ") + m_sRevision + _T(".")), _T("TortoiseGit"), MB_ICONERROR); break; } ret = git_commit_lookup(&commit, repository, (git_oid *) hash.m_hash); if (ret) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not lookup commit.")), _T("TortoiseGit"), MB_ICONERROR); break; } ret = git_commit_tree(&tree, commit); if (ret) { MessageBox(CGit::GetLibGit2LastErr(_T("Could not get tree of commit.")), _T("TortoiseGit"), MB_ICONERROR); break; } 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 (g_Git.GetMapHashToFriendName(map)) MessageBox(g_Git.GetGitLastErr(_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); } while(0); if (tree) git_tree_free(tree); if (commit) git_commit_free(commit); if (repository) git_repository_free(repository); return ret; }
int git_commit_amend( git_oid *id, const git_commit *commit_to_amend, const char *update_ref, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message, const git_tree *tree) { git_repository *repo; git_oid tree_id; git_reference *ref; int error; assert(id && commit_to_amend); repo = git_commit_owner(commit_to_amend); if (!author) author = git_commit_author(commit_to_amend); if (!committer) committer = git_commit_committer(commit_to_amend); if (!message_encoding) message_encoding = git_commit_message_encoding(commit_to_amend); if (!message) message = git_commit_message(commit_to_amend); if (!tree) { git_tree *old_tree; GITERR_CHECK_ERROR( git_commit_tree(&old_tree, commit_to_amend) ); git_oid_cpy(&tree_id, git_tree_id(old_tree)); git_tree_free(old_tree); } else { assert(git_tree_owner(tree) == repo); git_oid_cpy(&tree_id, git_tree_id(tree)); } if (update_ref) { if ((error = git_reference_lookup_resolved(&ref, repo, update_ref, 5)) < 0) return error; if (git_oid_cmp(git_commit_id(commit_to_amend), git_reference_target(ref))) { git_reference_free(ref); giterr_set(GITERR_REFERENCE, "commit to amend is not the tip of the given branch"); return -1; } } error = git_commit__create_internal( id, repo, NULL, author, committer, message_encoding, message, &tree_id, commit_parent_for_amend, (void *)commit_to_amend, false); if (!error && update_ref) { error = git_reference__update_for_commit( repo, ref, NULL, id, "commit"); git_reference_free(ref); } return error; }
static int rebase_commit__create( git_commit **out, git_rebase *rebase, git_index *index, git_commit *parent_commit, const git_signature *author, const git_signature *committer, const char *message_encoding, const char *message) { git_rebase_operation *operation; git_commit *current_commit = NULL, *commit = NULL; git_tree *parent_tree = NULL, *tree = NULL; git_oid tree_id, commit_id; int error; operation = git_array_get(rebase->operations, rebase->current); if (git_index_has_conflicts(index)) { giterr_set(GITERR_REBASE, "conflicts have not been resolved"); error = GIT_EUNMERGED; goto done; } if ((error = git_commit_lookup(¤t_commit, rebase->repo, &operation->id)) < 0 || (error = git_commit_tree(&parent_tree, parent_commit)) < 0 || (error = git_index_write_tree_to(&tree_id, index, rebase->repo)) < 0 || (error = git_tree_lookup(&tree, rebase->repo, &tree_id)) < 0) goto done; if (git_oid_equal(&tree_id, git_tree_id(parent_tree))) { giterr_set(GITERR_REBASE, "this patch has already been applied"); error = GIT_EAPPLIED; goto done; } if (!author) author = git_commit_author(current_commit); if (!message) { message_encoding = git_commit_message_encoding(current_commit); message = git_commit_message(current_commit); } if ((error = git_commit_create(&commit_id, rebase->repo, NULL, author, committer, message_encoding, message, tree, 1, (const git_commit **)&parent_commit)) < 0 || (error = git_commit_lookup(&commit, rebase->repo, &commit_id)) < 0) goto done; *out = commit; done: if (error < 0) git_commit_free(commit); git_commit_free(current_commit); git_tree_free(parent_tree); git_tree_free(tree); return error; }
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; }
QGitOId QGitTree::oid() { return QGitOId(git_tree_id(data())); }