int CRepositoryBrowser::ReadTreeRecursive(git_repository &repo, git_tree * tree, CShadowFilesTree * treeroot) { size_t count = git_tree_entrycount(tree); for (size_t i = 0; i < count; ++i) { const git_tree_entry *entry = git_tree_entry_byindex(tree, i); if (entry == NULL) continue; const int mode = git_tree_entry_filemode(entry); CString base = CUnicodeUtils::GetUnicode(git_tree_entry_name(entry), CP_UTF8); const git_oid *oid = git_tree_entry_id(entry); CShadowFilesTree * pNextTree = &treeroot->m_ShadowTree[base]; pNextTree->m_sName = base; pNextTree->m_pParent = treeroot; pNextTree->m_hash = CGitHash((char *)oid->id); if (mode == GIT_FILEMODE_COMMIT) pNextTree->m_bSubmodule = true; else if (mode & S_IFDIR) { pNextTree->m_bFolder = true; TVINSERTSTRUCT tvinsert = {0}; tvinsert.hParent = treeroot->m_hTree; tvinsert.hInsertAfter = TVI_SORT; tvinsert.itemex.mask = TVIF_DI_SETITEM | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE; tvinsert.itemex.pszText = base.GetBuffer(base.GetLength()); tvinsert.itemex.lParam = (LPARAM)pNextTree; tvinsert.itemex.iImage = m_nIconFolder; tvinsert.itemex.iSelectedImage = m_nOpenIconFolder; pNextTree->m_hTree = m_RepoTree.InsertItem(&tvinsert); base.ReleaseBuffer(); git_object *object = nullptr; git_tree_entry_to_object(&object, &repo, entry); if (object == nullptr) continue; ReadTreeRecursive(repo, (git_tree*)object, pNextTree); git_object_free(object); } else { git_blob * blob = nullptr; git_blob_lookup(&blob, &repo, oid); if (blob == NULL) continue; pNextTree->m_iSize = git_blob_rawsize(blob); git_blob_free(blob); } } return 0; }
void CGitPropertyPage::DisplayCommit(const git_commit* commit, UINT hashLabel, UINT subjectLabel, UINT authorLabel, UINT dateLabel) { if (commit == NULL) { SetDlgItemText(m_hwnd, hashLabel, _T("")); SetDlgItemText(m_hwnd, subjectLabel, _T("")); SetDlgItemText(m_hwnd, authorLabel, _T("")); SetDlgItemText(m_hwnd, dateLabel, _T("")); return; } int encode = CP_UTF8; const char * encodingString = git_commit_message_encoding(commit); if (encodingString != NULL) encode = CUnicodeUtils::GetCPCode(CUnicodeUtils::GetUnicode(encodingString)); const git_signature * author = git_commit_author(commit); CString authorName = CUnicodeUtils::GetUnicode(author->name, encode); CString message = CUnicodeUtils::GetUnicode(git_commit_message(commit), encode); int start = 0; message = message.Tokenize(L"\n", start); SetDlgItemText(m_hwnd, hashLabel, CGitHash((char*)(git_commit_id(commit)->id)).ToString()); SetDlgItemText(m_hwnd, subjectLabel, message); SetDlgItemText(m_hwnd, authorLabel, authorName); CString authorDate; Time64ToTimeString(author->when.time, authorDate.GetBufferSetLength(200), 200); SetDlgItemText(m_hwnd, dateLabel, authorDate); }
int GitRev::ParserParentFromCommit(const git_commit* commit) { m_ParentHash.clear(); unsigned int parentCount = git_commit_parentcount(commit); for (unsigned int i = 0; i < parentCount; ++i) m_ParentHash.push_back(CGitHash((char*)git_commit_parent_id(commit, i)->id)); return 0; }
int GitRev::ParserParentFromCommit(GIT_COMMIT *commit) { this->m_ParentHash.clear(); GIT_COMMIT_LIST list; GIT_HASH parent; git_get_commit_first_parent(commit,&list); while(git_get_commit_next_parent(&list,parent)==0) { m_ParentHash.push_back(CGitHash((char *)parent)); } return 0; }
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 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; }
int CRepositoryBrowser::ReadTreeRecursive(git_repository &repo, const git_tree * tree, CShadowFilesTree * treeroot) { size_t count = git_tree_entrycount(tree); bool hasSubfolders = false; for (size_t i = 0; i < count; ++i) { const git_tree_entry *entry = git_tree_entry_byindex(tree, i); if (entry == NULL) continue; const int mode = git_tree_entry_filemode(entry); CString base = CUnicodeUtils::GetUnicode(git_tree_entry_name(entry), CP_UTF8); const git_oid *oid = git_tree_entry_id(entry); CShadowFilesTree * pNextTree = &treeroot->m_ShadowTree[base]; pNextTree->m_sName = base; pNextTree->m_pParent = treeroot; pNextTree->m_hash = CGitHash((char *)oid->id); if (mode == GIT_FILEMODE_COMMIT) pNextTree->m_bSubmodule = true; else if (mode & S_IFDIR) { hasSubfolders = true; pNextTree->m_bFolder = true; pNextTree->m_bLoaded = false; TVINSERTSTRUCT tvinsert = {0}; tvinsert.hParent = treeroot->m_hTree; tvinsert.hInsertAfter = TVI_SORT; tvinsert.itemex.mask = TVIF_DI_SETITEM | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_CHILDREN; tvinsert.itemex.pszText = base.GetBuffer(base.GetLength()); tvinsert.itemex.cChildren = 1; tvinsert.itemex.lParam = (LPARAM)pNextTree; tvinsert.itemex.iImage = m_nIconFolder; tvinsert.itemex.iSelectedImage = m_nOpenIconFolder; pNextTree->m_hTree = m_RepoTree.InsertItem(&tvinsert); base.ReleaseBuffer(); } else { if (mode == GIT_FILEMODE_BLOB_EXECUTABLE) pNextTree->m_bExecutable = true; if (mode == GIT_FILEMODE_LINK) pNextTree->m_bSymlink = true; CAutoBlob blob; git_blob_lookup(blob.GetPointer(), &repo, oid); if (!blob) continue; pNextTree->m_iSize = git_blob_rawsize(blob); } } if (!hasSubfolders) { TVITEM tvitem = { 0 }; tvitem.hItem = treeroot->m_hTree; tvitem.mask = TVIF_CHILDREN; tvitem.cChildren = 0; m_RepoTree.SetItem(&tvitem); } return 0; }