+ POSITION pos = GetFirstSelectedItemPosition();\r
+ int indexNext = GetNextSelectedItem(pos);\r
+ if (indexNext < 0)\r
+ return;\r
+\r
+ CString procCmd;\r
+\r
+ GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));\r
+\r
+ bool bOpenWith = false;\r
+\r
+ procCmd+=_T("/path:\"");\r
+ procCmd+=((CMainFrame*)::AfxGetApp()->GetMainWnd())->GetActiveView()->GetDocument()->GetPathName();\r
+ procCmd+=_T("\" ");\r
+ procCmd+=_T(" /rev:")+this->m_logEntries[indexNext].m_CommitHash;\r
+\r
+ procCmd+=_T(" /command:");\r
+\r
+ switch (cmd)\r
+ {\r
+ case ID_GNUDIFF1:\r
+ procCmd+=_T("diff /udiff");\r
+ break;\r
+\r
+#if 0\r
+ case ID_GNUDIFF2:\r
+ {\r
+ CString tempfile=GetTempFile();\r
+ CString cmd;\r
+ GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
+ GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
+ cmd.Format(_T("git.exe diff-tree -r -p --stat %s %s"),r1->m_CommitHash,r2->m_CommitHash);\r
+ g_Git.RunLogFile(cmd,tempfile);\r
+ CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.Left(6)+_T(":")+r2->m_CommitHash.Left(6));\r
+\r
+ }\r
+ break;\r
+#endif\r
+#if 0\r
+ case ID_COMPARETWO:\r
+ {\r
+ GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));\r
+ GitRev * r2 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(LastSelect));\r
+ CFileDiffDlg dlg;\r
+ dlg.SetDiff(NULL,*r1,*r2);\r
+ dlg.DoModal();\r
+ \r
+ }\r
+ break;\r
+#endif \r
+#if 0\r
+ case ID_COMPARE:\r
+ {\r
+ GitRev * r1 = &m_wcRev;\r
+ GitRev * r2 = pSelLogEntry;\r
+ CFileDiffDlg dlg;\r
+ dlg.SetDiff(NULL,*r1,*r2);\r
+ dlg.DoModal();\r
+\r
+ //user clicked on the menu item "compare with working copy"\r
+ //if (PromptShown())\r
+ //{\r
+ // GitDiff diff(this, m_hWnd, true);\r
+ // diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ // diff.SetHEADPeg(m_LogRevision);\r
+ // diff.ShowCompare(m_path, GitRev::REV_WC, m_path, revSelected);\r
+ //}\r
+ //else\r
+ // CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_WC, m_path, revSelected, GitRev(), m_LogRevision, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+ }\r
+ break;\r
+#endif\r
+ case ID_COMPARE:\r
+ procCmd+=CString(_T("diff \rev1:"))+CString(GIT_REV_ZERO)+CString(_T(" \rev2:"))+this->m_logEntries[indexNext].m_CommitHash;\r
+ break;\r
+ case ID_COMPAREWITHPREVIOUS:\r
+ procCmd+=_T("prevdiff");\r
+ break;\r
+ case ID_COPYCLIPBOARD:\r
+ {\r
+ CopySelectionToClipBoard();\r
+ }\r
+ return;\r
+ case ID_COPYHASH:\r
+ {\r
+ CopySelectionToClipBoard(TRUE);\r
+ }\r
+ return;\r
+ case ID_EXPORT:\r
+ procCmd+=_T("export");\r
+ break;\r
+ case ID_CREATE_BRANCH:\r
+ procCmd+=_T("branch");\r
+ break;\r
+ case ID_CREATE_TAG:\r
+ procCmd+=_T("tag");\r
+ break;\r
+ case ID_SWITCHTOREV:\r
+ procCmd+=_T("switch");\r
+ break;\r
+\r
+ default:\r
+ //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);\r
+ return;\r
+\r
+#if 0\r
+ \r
+ case ID_REVERTREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+ CString msg;\r
+ msg.Format(IDS_LOG_REVERT_CONFIRM, m_path.GetWinPath());\r
+ if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(m_path));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ revisionRanges.AdjustForMerge(true);\r
+ dlg.SetRevisionRanges(revisionRanges);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ case ID_MERGEREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+\r
+ CString path = m_path.GetWinPathString();\r
+ bool bGotSavePath = false;\r
+ if ((GetSelectedCount() == 1)&&(!m_path.IsDirectory()))\r
+ {\r
+ bGotSavePath = CAppUtils::FileOpenSave(path, NULL, IDS_LOG_MERGETO, IDS_COMMONFILEFILTER, true, GetSafeHwnd());\r
+ }\r
+ else\r
+ {\r
+ CBrowseFolder folderBrowser;\r
+ folderBrowser.SetInfo(CString(MAKEINTRESOURCE(IDS_LOG_MERGETO)));\r
+ bGotSavePath = (folderBrowser.Show(GetSafeHwnd(), path, path) == CBrowseFolder::OK);\r
+ }\r
+ if (bGotSavePath)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(CTGitPath(path)));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ revisionRanges.AdjustForMerge(false);\r
+ dlg.SetRevisionRanges(revisionRanges);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ case ID_REVERTTOREV:\r
+ {\r
+ // we need an URL to complete this command, so error out if we can't get an URL\r
+ if (pathURL.IsEmpty())\r
+ {\r
+ CString strMessage;\r
+ strMessage.Format(IDS_ERR_NOURLOFFILE, (LPCTSTR)(m_path.GetUIPathString()));\r
+ CMessageBox::Show(this->m_hWnd, strMessage, _T("TortoiseGit"), MB_ICONERROR);\r
+ TRACE(_T("could not retrieve the URL of the folder!\n"));\r
+ break; //exit\r
+ }\r
+\r
+ CString msg;\r
+ msg.Format(IDS_LOG_REVERTTOREV_CONFIRM, m_path.GetWinPath());\r
+ if (CMessageBox::Show(this->m_hWnd, msg, _T("TortoiseGit"), MB_YESNO | MB_ICONQUESTION) == IDYES)\r
+ {\r
+ CGitProgressDlg dlg;\r
+ dlg.SetCommand(CGitProgressDlg::GitProgress_Merge);\r
+ dlg.SetPathList(CTGitPathList(m_path));\r
+ dlg.SetUrl(pathURL);\r
+ dlg.SetSecondUrl(pathURL);\r
+ GitRevRangeArray revarray;\r
+ revarray.AddRevRange(GitRev::REV_HEAD, revSelected);\r
+ dlg.SetRevisionRanges(revarray);\r
+ dlg.SetPegRevision(m_LogRevision);\r
+ dlg.DoModal();\r
+ }\r
+ }\r
+ break;\r
+ \r
+\r
+ \r
+ case ID_BLAMECOMPARE:\r
+ {\r
+ //user clicked on the menu item "compare with working copy"\r
+ //now first get the revision which is selected\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, m_path, GitRev::REV_BASE, m_path, revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ case ID_BLAMETWO:\r
+ {\r
+ //user clicked on the menu item "compare and blame revisions"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revSelected2, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ case ID_BLAMEWITHPREVIOUS:\r
+ {\r
+ //user clicked on the menu item "Compare and Blame with previous revision"\r
+ if (PromptShown())\r
+ {\r
+ GitDiff diff(this, this->m_hWnd, true);\r
+ diff.SetHEADPeg(m_LogRevision);\r
+ diff.ShowCompare(CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), false, true);\r
+ }\r
+ else\r
+ CAppUtils::StartShowCompare(m_hWnd, CTGitPath(pathURL), revPrevious, CTGitPath(pathURL), revSelected, GitRev(), m_LogRevision, false, false, true);\r
+ }\r
+ break;\r
+ \r
+ case ID_OPENWITH:\r
+ bOpenWith = true;\r
+ case ID_OPEN:\r
+ {\r
+ CProgressDlg progDlg;\r
+ progDlg.SetTitle(IDS_APPNAME);\r
+ progDlg.SetAnimation(IDR_DOWNLOAD);\r
+ CString sInfoLine;\r
+ sInfoLine.Format(IDS_PROGRESSGETFILEREVISION, m_path.GetWinPath(), (LPCTSTR)revSelected.ToString());\r
+ progDlg.SetLine(1, sInfoLine, true);\r
+ SetAndClearProgressInfo(&progDlg);\r
+ progDlg.ShowModeless(m_hWnd);\r
+ CTGitPath tempfile = CTempFiles::Instance().GetTempFilePath(false, m_path, revSelected);\r
+ bool bSuccess = true;\r
+ if (!Cat(m_path, GitRev(GitRev::REV_HEAD), revSelected, tempfile))\r
+ {\r
+ bSuccess = false;\r
+ // try again, but with the selected revision as the peg revision\r
+ if (!Cat(m_path, revSelected, revSelected, tempfile))\r
+ {\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ CMessageBox::Show(this->m_hWnd, GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ EnableOKButton();\r
+ break;\r
+ }\r
+ bSuccess = true;\r
+ }\r
+ if (bSuccess)\r
+ {\r
+ progDlg.Stop();\r
+ SetAndClearProgressInfo((HWND)NULL);\r
+ SetFileAttributes(tempfile.GetWinPath(), FILE_ATTRIBUTE_READONLY);\r
+ int ret = 0;\r
+ if (!bOpenWith)\r
+ ret = (int)ShellExecute(this->m_hWnd, NULL, tempfile.GetWinPath(), NULL, NULL, SW_SHOWNORMAL);\r
+ if ((ret <= HINSTANCE_ERROR)||bOpenWith)\r
+ {\r
+ CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
+ cmd += tempfile.GetWinPathString() + _T(" ");\r
+ CAppUtils::LaunchApplication(cmd, NULL, false);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case ID_BLAME:\r
+ {\r
+ CBlameDlg dlg;\r
+ dlg.EndRev = revSelected;\r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ CBlame blame;\r
+ CString tempfile;\r
+ CString logfile;\r
+ tempfile = blame.BlameToTempFile(m_path, dlg.StartRev, dlg.EndRev, dlg.EndRev, logfile, _T(""), dlg.m_bIncludeMerge, TRUE, TRUE);\r
+ if (!tempfile.IsEmpty())\r
+ {\r
+ if (dlg.m_bTextView)\r
+ {\r
+ //open the default text editor for the result file\r
+ CAppUtils::StartTextViewer(tempfile);\r
+ }\r
+ else\r
+ {\r
+ CString sParams = _T("/path:\"") + m_path.GetGitPathString() + _T("\" ");\r
+ if(!CAppUtils::LaunchTortoiseBlame(tempfile, logfile, CPathUtils::GetFileNameFromPath(m_path.GetFileOrDirectoryName()),sParams))\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ CMessageBox::Show(this->m_hWnd, blame.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ case ID_UPDATE:\r
+ {\r
+ CString sCmd;\r
+ CString url = _T("tgit:")+pathURL;\r
+ sCmd.Format(_T("%s /command:update /path:\"%s\" /rev:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)m_path.GetWinPath(), (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_FINDENTRY:\r
+ {\r
+ m_nSearchIndex = GetSelectionMark();\r
+ if (m_nSearchIndex < 0)\r
+ m_nSearchIndex = 0;\r
+ if (m_pFindDialog)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ m_pFindDialog = new CFindReplaceDialog();\r
+ m_pFindDialog->Create(TRUE, NULL, NULL, FR_HIDEUPDOWN | FR_HIDEWHOLEWORD, this); \r
+ }\r
+ }\r
+ break;\r
+ case ID_REPOBROWSE:\r
+ {\r
+ CString sCmd;\r
+ sCmd.Format(_T("%s /command:repobrowser /path:\"%s\" /rev:%s"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)pathURL, (LPCTSTR)revSelected.ToString());\r
+\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_EDITLOG:\r
+ {\r
+ EditLogMessage(selIndex);\r
+ }\r
+ break;\r
+ case ID_EDITAUTHOR:\r
+ {\r
+ EditAuthor(selEntries);\r
+ }\r
+ break;\r
+ case ID_REVPROPS:\r
+ {\r
+ CEditPropertiesDlg dlg;\r
+ dlg.SetProjectProperties(&m_ProjectProperties);\r
+ CTGitPathList escapedlist;\r
+ dlg.SetPathList(CTGitPathList(CTGitPath(pathURL)));\r
+ dlg.SetRevision(revSelected);\r
+ dlg.RevProps(true);\r
+ dlg.DoModal();\r
+ }\r
+ break;\r
+ \r
+ case ID_EXPORT:\r
+ {\r
+ CString sCmd;\r
+ sCmd.Format(_T("%s /command:export /path:\"%s\" /revision:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)pathURL, (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_CHECKOUT:\r
+ {\r
+ CString sCmd;\r
+ CString url = _T("tgit:")+pathURL;\r
+ sCmd.Format(_T("%s /command:checkout /url:\"%s\" /revision:%ld"),\r
+ (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")),\r
+ (LPCTSTR)url, (LONG)revSelected);\r
+ CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+ }\r
+ break;\r
+ case ID_VIEWREV:\r
+ {\r
+ CString url = m_ProjectProperties.sWebViewerRev;\r
+ url = GetAbsoluteUrlFromRelativeUrl(url);\r
+ url.Replace(_T("%REVISION%"), revSelected.ToString());\r
+ if (!url.IsEmpty())\r
+ ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT); \r
+ }\r
+ break;\r
+ case ID_VIEWPATHREV:\r
+ {\r
+ CString relurl = pathURL;\r
+ CString sRoot = GetRepositoryRoot(CTGitPath(relurl));\r
+ relurl = relurl.Mid(sRoot.GetLength());\r
+ CString url = m_ProjectProperties.sWebViewerPathRev;\r
+ url = GetAbsoluteUrlFromRelativeUrl(url);\r
+ url.Replace(_T("%REVISION%"), revSelected.ToString());\r
+ url.Replace(_T("%PATH%"), relurl);\r
+ if (!url.IsEmpty())\r
+ ShellExecute(this->m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT); \r
+ }\r
+ break;\r
+#endif\r
+\r
+ } // switch (cmd)\r
+\r
+\r
+ STARTUPINFO startup;\r
+ PROCESS_INFORMATION process;\r
+ memset(&startup, 0, sizeof(startup));\r
+ startup.cb = sizeof(startup);\r
+ memset(&process, 0, sizeof(process));\r
+ CString tortoiseProcPath = CPathUtils::GetAppDirectory() + _T("TortoiseProc.exe");\r
+ \r
+ if (CreateProcess(tortoiseProcPath, procCmd.GetBuffer(), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))\r
+ {\r
+ CloseHandle(process.hThread);\r
+ CloseHandle(process.hProcess);\r
+ }\r