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; }
bool ResetProgressCommand::Run(CGitProgressList* list, CString& sWindowTitle, int& /*m_itemCountTotal*/, int& /*m_itemCount*/) { if (!g_Git.UsingLibGit2(CGit::GIT_CMD_RESET)) { // should never run to here ASSERT(0); return false; } list->SetWindowTitle(IDS_PROGRS_TITLE_RESET, g_Git.m_CurrentDir, sWindowTitle); list->SetBackgroundImage(IDI_UPDATE_BKG); int resetTypesResource[] = { IDS_RESET_SOFT, IDS_RESET_MIXED, IDS_RESET_HARD }; list->ReportCmd(CString(MAKEINTRESOURCE(IDS_PROGRS_TITLE_RESET)) + L' ' + CString(MAKEINTRESOURCE(resetTypesResource[m_resetType])) + L' ' + m_revision); list->ShowProgressBar(); CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { list->ReportGitError(); return false; } CGitProgressList::Payload cbpayload = { list, repo }; git_checkout_options checkout_options = GIT_CHECKOUT_OPTIONS_INIT; CBlockCacheForPath block(g_Git.m_CurrentDir); CAutoObject target; if (git_revparse_single(target.GetPointer(), repo, CUnicodeUtils::GetUTF8(m_revision))) goto error; checkout_options.progress_payload = &cbpayload; checkout_options.progress_cb = [](const char*, size_t completed_steps, size_t total_steps, void* payload) { CGitProgressList::Payload* cbpayload = (CGitProgressList::Payload*)payload; cbpayload->list->m_itemCountTotal = (int)total_steps; cbpayload->list->m_itemCount = (int)completed_steps; }; checkout_options.notify_cb = [](git_checkout_notify_t, const char* pPath, const git_diff_file*, const git_diff_file*, const git_diff_file*, void* payload) -> int { CGitProgressList* list = (CGitProgressList*)payload; CString path(CUnicodeUtils::GetUnicode(pPath)); if (DWORD(CRegDWORD(L"Software\\TortoiseGit\\RevertWithRecycleBin", TRUE))) { if (!CTGitPath(g_Git.CombinePath(path)).Delete(true, true)) { list->ReportError(L"Could move \"" + path + L"\" to recycle bin"); return GIT_EUSER; } } list->AddNotify(new CGitProgressList::WC_File_NotificationData(path, CGitProgressList::WC_File_NotificationData::git_wc_notify_checkout)); return 0; }; checkout_options.notify_flags = GIT_CHECKOUT_NOTIFY_UPDATED; checkout_options.notify_payload = list; if (git_reset(repo, target, (git_reset_t)(m_resetType + 1), &checkout_options)) goto error; // Not setting m_PostCmdCallback here, as clone is only called from AppUtils.cpp return true; error: list->ReportGitError(); return false; }
bool CatCommand::Execute() { if (!GitAdminDir::IsWorkingTreeOrBareRepo(g_Git.m_CurrentDir)) { CMessageBox::Show(GetExplorerHWND(), IDS_NOGITREPO, IDS_APPNAME, MB_ICONERROR); return false; } CString savepath = CPathUtils::GetLongPathname(parser.GetVal(L"savepath")); CString revision = parser.GetVal(L"revision"); if (g_Git.UsingLibGit2(CGit::GIT_CMD_GETONEFILE)) { CAutoRepository repo(g_Git.GetGitRepository()); if (!repo) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not open repository."), L"TortoiseGit", MB_ICONERROR); return false; } CAutoObject obj; if (git_revparse_single(obj.GetPointer(), repo, CUnicodeUtils::GetUTF8(revision))) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not parse revision."), L"TortoiseGit", MB_ICONERROR); return false; } if (git_object_type(obj) == GIT_OBJECT_BLOB) { CAutoFILE file = _wfsopen(savepath, L"wb", SH_DENYRW); if (file == nullptr) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), L"Could not open file for writing.", L"TortoiseGit", MB_ICONERROR); return false; } CAutoBuf buf; if (git_blob_filtered_content(buf, reinterpret_cast<git_blob*>(static_cast<git_object*>(obj)), CUnicodeUtils::GetUTF8(cmdLinePath.GetGitPathString()), 0)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), g_Git.GetLibGit2LastErr(L"Could not get filtered content."), L"TortoiseGit", MB_ICONERROR); return false; } if (fwrite(buf->ptr, sizeof(char), buf->size, file) != buf->size) { ::DeleteFile(savepath); CString err = CFormatMessageWrapper(); CMessageBox::Show(GetExplorerHWND(), L"Could not write to file: " + err, L"TortoiseGit", MB_ICONERROR); return false; } return true; } if (g_Git.GetOneFile(revision, cmdLinePath, savepath)) { MessageBox(GetExplorerHWND(), g_Git.GetGitLastErr(L"Could get file.", CGit::GIT_CMD_GETONEFILE), L"TortoiseGit", MB_ICONERROR); return false; } return true; } CString cmd, output, err; cmd.Format(L"git.exe cat-file -t %s", static_cast<LPCTSTR>(revision)); if (g_Git.Run(cmd, &output, &err, CP_UTF8)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), output + L'\n' + err, L"TortoiseGit", MB_ICONERROR); return false; } if (CStringUtils::StartsWith(output, L"blob")) cmd.Format(L"git.exe cat-file -p %s", static_cast<LPCTSTR>(revision)); else cmd.Format(L"git.exe show %s -- \"%s\"", static_cast<LPCTSTR>(revision), static_cast<LPCTSTR>(this->cmdLinePath.GetWinPathString())); if (g_Git.RunLogFile(cmd, savepath, &err)) { ::DeleteFile(savepath); MessageBox(GetExplorerHWND(), L"Cat file failed:\n" + err, L"TortoiseGit", MB_ICONERROR); return false; } return true; }