//#include "RepositoryBrowser.h"\r
//#include "BrowseFolder.h"\r
#include "UnicodeUtils.h"\r
+#include "ExportDlg.h"\r
+#include "ProgressDlg.h"\r
+#include "GitAdminDir.h"\r
+#include "ProgressDlg.h"\r
+#include "BrowseFolder.h"\r
+#include "DirFileEnum.h"\r
+#include "MessageBox.h"\r
+#include "GitStatus.h"\r
+#include "CreateBranchTagDlg.h"\r
+#include "GitSwitchDlg.h"\r
+#include "ResetDlg.h"\r
+#include "DeleteConflictDlg.h"\r
+#include "ChangedDlg.h"\r
+#include "SendMailDlg.h"\r
+#include "SVNProgressDlg.h"\r
+#include "PushDlg.h"\r
\r
CAppUtils::CAppUtils(void)\r
{\r
{\r
}\r
\r
+int CAppUtils::StashApply(CString ref)\r
+{\r
+ CString cmd,out;\r
+ cmd=_T("git.exe stash apply ");\r
+ cmd+=ref;\r
+ \r
+ if(g_Git.Run(cmd,&out,CP_ACP))\r
+ {\r
+ CMessageBox::Show(NULL,CString(_T("<ct=0x0000FF>Stash Apply Fail!!!</ct>\n"))+out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+\r
+ }else\r
+ {\r
+ if(CMessageBox::Show(NULL,CString(_T("<ct=0xff0000>Stash Apply Success</ct>\nDo you want to show change?"))\r
+ ,_T("TortoiseGit"),MB_YESNO|MB_ICONINFORMATION) == IDYES)\r
+ {\r
+ CChangedDlg dlg;\r
+ dlg.m_pathList.AddPath(CTGitPath());\r
+ dlg.DoModal(); \r
+ }\r
+ return 0;\r
+ }\r
+ return -1;\r
+}\r
bool CAppUtils::GetMimeType(const CTGitPath& file, CString& mimetype)\r
{\r
#if 0\r
CloseHandle(process.hProcess);\r
return true;\r
}\r
+bool CAppUtils::LaunchPAgent(CString *keyfile,CString * pRemote)\r
+{\r
+ CString key,remote;\r
+ CString cmd,out;\r
+ if( pRemote == NULL)\r
+ {\r
+ remote=_T("origin");\r
+ }else\r
+ {\r
+ remote=*pRemote;\r
+ }\r
+ if(keyfile == NULL)\r
+ {\r
+ cmd.Format(_T("git.exe config remote.%s.puttykeyfile"),remote);\r
+ g_Git.Run(cmd,&key,CP_ACP);\r
+ int start=0;\r
+ key = key.Tokenize(_T("\n"),start);\r
+ }\r
+ else\r
+ key=*keyfile;\r
+\r
+ if(key.IsEmpty())\r
+ return false;\r
+\r
+ CString proc=CPathUtils::GetAppDirectory();\r
+ proc += _T("pageant.exe \"");\r
+ proc += key;\r
+ proc += _T("\"");\r
\r
+ return LaunchApplication(proc, IDS_ERR_PAGEANT, false);\r
+}\r
+bool CAppUtils::LaunchRemoteSetting()\r
+{\r
+ CString proc=CPathUtils::GetAppDirectory();\r
+ proc += _T("TortoiseProc.exe /command:settings");\r
+ proc += _T(" /path:\"");\r
+ proc += g_Git.m_CurrentDir;\r
+ proc += _T("\" /page:remote");\r
+ return LaunchApplication(proc, IDS_ERR_EXTDIFFSTART, false);\r
+}\r
/**\r
* Launch the external blame viewer\r
*/\r
-bool CAppUtils::LaunchTortoiseBlame(const CString& sBlameFile, const CString& sLogFile, const CString& sOriginalFile, const CString& sParams)\r
+bool CAppUtils::LaunchTortoiseBlame(const CString& sBlameFile,CString Rev,const CString& sParams)\r
{\r
CString viewer = CPathUtils::GetAppDirectory();\r
- viewer += _T("TortoiseBlame.exe");\r
+ viewer += _T("TortoiseGitBlame.exe");\r
viewer += _T(" \"") + sBlameFile + _T("\"");\r
- viewer += _T(" \"") + sLogFile + _T("\"");\r
- viewer += _T(" \"") + sOriginalFile + _T("\"");\r
+ //viewer += _T(" \"") + sLogFile + _T("\"");\r
+ //viewer += _T(" \"") + sOriginalFile + _T("\"");\r
+ if(!Rev.IsEmpty())\r
+ viewer += CString(_T(" /rev:"))+Rev;\r
viewer += _T(" ")+sParams;\r
\r
return LaunchApplication(viewer, IDS_ERR_EXTDIFFSTART, false);\r
}\r
\r
-void CAppUtils::ResizeAllListCtrlCols(CListCtrl * pListCtrl)\r
-{\r
- int maxcol = ((CHeaderCtrl*)(pListCtrl->GetDlgItem(0)))->GetItemCount()-1;\r
- int nItemCount = pListCtrl->GetItemCount();\r
- TCHAR textbuf[MAX_PATH];\r
- CHeaderCtrl * pHdrCtrl = (CHeaderCtrl*)(pListCtrl->GetDlgItem(0));\r
- if (pHdrCtrl)\r
- {\r
- for (int col = 0; col <= maxcol; col++)\r
- {\r
- HDITEM hdi = {0};\r
- hdi.mask = HDI_TEXT;\r
- hdi.pszText = textbuf;\r
- hdi.cchTextMax = sizeof(textbuf);\r
- pHdrCtrl->GetItem(col, &hdi);\r
- int cx = pListCtrl->GetStringWidth(hdi.pszText)+20; // 20 pixels for col separator and margin\r
- for (int index = 0; index<nItemCount; ++index)\r
- {\r
- // get the width of the string and add 14 pixels for the column separator and margins\r
- int linewidth = pListCtrl->GetStringWidth(pListCtrl->GetItemText(index, col)) + 14;\r
- if (index == 0)\r
- {\r
- // add the image size\r
- CImageList * pImgList = pListCtrl->GetImageList(LVSIL_SMALL);\r
- if ((pImgList)&&(pImgList->GetImageCount()))\r
- {\r
- IMAGEINFO imginfo;\r
- pImgList->GetImageInfo(0, &imginfo);\r
- linewidth += (imginfo.rcImage.right - imginfo.rcImage.left);\r
- linewidth += 3; // 3 pixels between icon and text\r
- }\r
- }\r
- if (cx < linewidth)\r
- cx = linewidth;\r
- }\r
- pListCtrl->SetColumnWidth(col, cx);\r
-\r
- }\r
- }\r
-}\r
-\r
bool CAppUtils::FormatTextInRichEditControl(CWnd * pWnd)\r
{\r
CString sText;\r
CString cmd;\r
if(rev1 == GitRev::GetWorkingCopy())\r
{\r
- cmd.Format(_T("git.cmd diff --stat -p %s"),rev2);\r
+ cmd.Format(_T("git.exe diff --stat -p %s "),rev2);\r
}else\r
{ \r
- cmd.Format(_T("git.cmd diff-tree -r -p --stat %s %s"),rev1,rev2);\r
+ cmd.Format(_T("git.exe diff-tree -r -p --stat %s %s"),rev1,rev2);\r
+ }\r
+\r
+ if( !url1.IsEmpty() )\r
+ {\r
+ cmd+=_T(" \"");\r
+ cmd+=url1.GetGitPathString();\r
+ cmd+=_T("\" ");\r
}\r
g_Git.RunLogFile(cmd,tempfile);\r
CAppUtils::StartUnifiedDiffViewer(tempfile,rev1.Left(6)+_T(":")+rev2.Left(6));\r
return CAppUtils::LaunchApplication(sCmd, NULL, false);\r
#endif\r
return true;\r
-}
\ No newline at end of file
+}\r
+\r
+bool CAppUtils::Export(CString *BashHash)\r
+{\r
+ bool bRet = false;\r
+\r
+ // ask from where the export has to be done\r
+ CExportDlg dlg;\r
+ if(BashHash)\r
+ dlg.m_Revision=*BashHash;\r
+\r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ CString cmd;\r
+ cmd.Format(_T("git.exe archive --format=zip --verbose %s"),\r
+ dlg.m_VersionName);\r
+\r
+ //g_Git.RunLogFile(cmd,dlg.m_strExportDirectory);\r
+ CProgressDlg pro;\r
+ pro.m_GitCmd=cmd;\r
+ pro.m_LogFile=dlg.m_strExportDirectory;\r
+ pro.DoModal();\r
+ return TRUE;\r
+ }\r
+ return bRet;\r
+}\r
+\r
+bool CAppUtils::CreateBranchTag(bool IsTag,CString *CommitHash)\r
+{\r
+ CCreateBranchTagDlg dlg;\r
+ dlg.m_bIsTag=IsTag;\r
+ if(CommitHash)\r
+ dlg.m_Base = *CommitHash;\r
+\r
+ if(dlg.DoModal()==IDOK)\r
+ {\r
+ CString cmd;\r
+ CString force;\r
+ CString track;\r
+ if(dlg.m_bTrack)\r
+ track=_T(" --track ");\r
+\r
+ if(dlg.m_bForce)\r
+ force=_T(" -f ");\r
+\r
+ if(IsTag)\r
+ {\r
+ cmd.Format(_T("git.exe tag %s %s %s %s"),\r
+ track,\r
+ force,\r
+ dlg.m_BranchTagName,\r
+ dlg.m_VersionName\r
+ );\r
+\r
+ \r
+ }else\r
+ {\r
+ cmd.Format(_T("git.exe branch %s %s %s %s"),\r
+ track,\r
+ force,\r
+ dlg.m_BranchTagName,\r
+ dlg.m_VersionName\r
+ );\r
+ }\r
+ CString out;\r
+ if(g_Git.Run(cmd,&out,CP_UTF8))\r
+ {\r
+ CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+ }\r
+ if( !IsTag && dlg.m_bSwitch )\r
+ {\r
+ // it is a new branch and the user has requested to switch to it\r
+ cmd.Format(_T("git.exe checkout %s"), dlg.m_BranchTagName);\r
+ g_Git.Run(cmd,&out,CP_UTF8);\r
+ CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+ }\r
+ \r
+ return TRUE;\r
+ \r
+ }\r
+ return FALSE;\r
+}\r
+\r
+bool CAppUtils::Switch(CString *CommitHash)\r
+{\r
+ CGitSwitchDlg dlg;\r
+ if(CommitHash)\r
+ dlg.m_Base=*CommitHash;\r
+ \r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ CString cmd;\r
+ CString track;\r
+ CString base;\r
+ CString force;\r
+ CString branch;\r
+\r
+ if(dlg.m_bBranch)\r
+ branch.Format(_T("-b %s"),dlg.m_NewBranch);\r
+ if(dlg.m_bForce)\r
+ force=_T("-f");\r
+ if(dlg.m_bTrack)\r
+ track=_T("--track");\r
+\r
+ cmd.Format(_T("git.exe checkout %s %s %s %s"),\r
+ force,\r
+ track,\r
+ branch,\r
+ dlg.m_VersionName);\r
+\r
+ CProgressDlg progress;\r
+ progress.m_GitCmd=cmd;\r
+ if(progress.DoModal()==IDOK)\r
+ return TRUE;\r
+\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+bool CAppUtils::IgnoreFile(CTGitPathList &path,bool IsMask)\r
+{\r
+ CString ignorefile;\r
+ ignorefile=g_Git.m_CurrentDir+_T("\\");\r
+\r
+ if(IsMask)\r
+ {\r
+ ignorefile+=path.GetCommonRoot().GetDirectory().GetWinPathString()+_T("\\.gitignore");\r
+\r
+ }else\r
+ {\r
+ ignorefile+=_T("\\.gitignore");\r
+ }\r
+\r
+ CStdioFile file;\r
+ if(!file.Open(ignorefile,CFile::modeCreate|CFile::modeReadWrite|CFile::modeNoTruncate))\r
+ {\r
+ CMessageBox::Show(NULL,ignorefile+_T(" Open Failure"),_T("TortoiseGit"),MB_OK);\r
+ return FALSE;\r
+ }\r
+\r
+ CString ignorelist;\r
+ CString mask;\r
+ try\r
+ {\r
+ //file.ReadString(ignorelist);\r
+ file.SeekToEnd();\r
+ for(int i=0;i<path.GetCount();i++)\r
+ {\r
+ if(IsMask)\r
+ {\r
+ mask=_T("*")+path[i].GetFileExtension();\r
+ if(ignorelist.Find(mask)<0)\r
+ ignorelist+=_T("\n")+mask;\r
+ \r
+ }else\r
+ {\r
+ ignorelist+=_T("\n/")+path[i].GetGitPathString();\r
+ }\r
+ }\r
+ file.WriteString(ignorelist);\r
+\r
+ file.Close();\r
+\r
+ }catch(...)\r
+ {\r
+ file.Close();\r
+ return FALSE;\r
+ }\r
+ \r
+ return TRUE;\r
+}\r
+\r
+\r
+bool CAppUtils::GitReset(CString *CommitHash,int type)\r
+{\r
+ CResetDlg dlg;\r
+ dlg.m_ResetType=type;\r
+ if (dlg.DoModal() == IDOK)\r
+ {\r
+ CString cmd;\r
+ CString type;\r
+ switch(dlg.m_ResetType)\r
+ {\r
+ case 0:\r
+ type=_T("--soft");\r
+ break;\r
+ case 1:\r
+ type=_T("--mixed");\r
+ break;\r
+ case 2:\r
+ type=_T("--hard");\r
+ break;\r
+ default:\r
+ type=_T("--mixed");\r
+ break;\r
+ }\r
+ cmd.Format(_T("git.exe reset %s %s"),type, *CommitHash);\r
+\r
+ CProgressDlg progress;\r
+ progress.m_GitCmd=cmd;\r
+ if(progress.DoModal()==IDOK)\r
+ return TRUE;\r
+\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+void CAppUtils::DescribeFile(bool mode, bool base,CString &descript)\r
+{\r
+ if(mode == FALSE)\r
+ {\r
+ descript=_T("Deleted");\r
+ return;\r
+ }\r
+ if(base)\r
+ {\r
+ descript=_T("Modified");\r
+ return;\r
+ }\r
+ descript=_T("Created");\r
+ return;\r
+}\r
+\r
+CString CAppUtils::GetMergeTempFile(CString type,CTGitPath &merge)\r
+{\r
+ CString file;\r
+ file=g_Git.m_CurrentDir+_T("\\")+merge.GetDirectory().GetWinPathString()+_T("\\")+merge.GetFilename()+_T(".")+type+merge.GetFileExtension();\r
+\r
+ return file;\r
+}\r
+\r
+bool CAppUtils::ConflictEdit(CTGitPath &path,bool bAlternativeTool)\r
+{\r
+ bool bRet = false;\r
+\r
+ CTGitPath merge=path;\r
+ CTGitPath directory = merge.GetDirectory();\r
+ \r
+ \r
+\r
+ // we have the conflicted file (%merged)\r
+ // now look for the other required files\r
+ //GitStatus stat;\r
+ //stat.GetStatus(merge);\r
+ //if (stat.status == NULL)\r
+ // return false;\r
+\r
+ BYTE_VECTOR vector;\r
+\r
+ CString cmd;\r
+ cmd.Format(_T("git.exe ls-files -u -t -z -- \"%s\""),merge.GetGitPathString());\r
+\r
+ if(g_Git.Run(cmd,&vector))\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ CTGitPathList list;\r
+ list.ParserFromLsFile(vector);\r
+\r
+ if(list.GetCount() == 0)\r
+ return FALSE;\r
+\r
+ TCHAR szTempName[512]; \r
+ GetTempFileName(_T(""),_T(""),0,szTempName);\r
+ CString temp(szTempName);\r
+ temp=temp.Mid(1,temp.GetLength()-5);\r
+\r
+ CTGitPath theirs;\r
+ CTGitPath mine;\r
+ CTGitPath base;\r
+\r
+ \r
+ mine.SetFromGit(GetMergeTempFile(_T("LOCAL"),merge));\r
+ theirs.SetFromGit(GetMergeTempFile(_T("REMOTE"),merge));\r
+ base.SetFromGit(GetMergeTempFile(_T("BASE"),merge));\r
+\r
+ CString format;\r
+\r
+ format=_T("git.exe cat-file blob \":%d:%s\"");\r
+ CFile tempfile;\r
+ //create a empty file, incase stage is not three\r
+ tempfile.Open(mine.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+ tempfile.Close();\r
+ tempfile.Open(theirs.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+ tempfile.Close();\r
+ tempfile.Open(base.GetWinPathString(),CFile::modeCreate|CFile::modeReadWrite);\r
+ tempfile.Close();\r
+\r
+ bool b_base=false, b_local=false, b_remote=false;\r
+\r
+ for(int i=0;i<list.GetCount();i++)\r
+ {\r
+ CString cmd;\r
+ CString outfile;\r
+ cmd.Format(format,list[i].m_Stage,list[i].GetGitPathString());\r
+ \r
+ if( list[i].m_Stage == 1)\r
+ {\r
+ b_base = true;\r
+ outfile=base.GetWinPathString();\r
+ }\r
+ if( list[i].m_Stage == 2 )\r
+ {\r
+ b_local = true;\r
+ outfile=mine.GetWinPathString();\r
+ }\r
+ if( list[i].m_Stage == 3 )\r
+ {\r
+ b_remote = true;\r
+ outfile=theirs.GetWinPathString();\r
+ } \r
+ g_Git.RunLogFile(cmd,outfile);\r
+ }\r
+\r
+ if(b_local && b_remote )\r
+ {\r
+ merge.SetFromWin(g_Git.m_CurrentDir+_T("\\")+merge.GetWinPathString());\r
+ bRet = !!CAppUtils::StartExtMerge(base, theirs, mine, merge,_T("BASE"),_T("REMOTE"),_T("LOCAL"));\r
+ \r
+ }else\r
+ {\r
+ CFile::Remove(mine.GetWinPathString());\r
+ CFile::Remove(theirs.GetWinPathString());\r
+ CFile::Remove(base.GetWinPathString());\r
+\r
+ CDeleteConflictDlg dlg;\r
+ DescribeFile(b_local, b_base,dlg.m_LocalStatus);\r
+ DescribeFile(b_remote,b_base,dlg.m_RemoteStatus);\r
+ dlg.m_bShowModifiedButton=b_base;\r
+ dlg.m_File=merge.GetGitPathString();\r
+ if(dlg.DoModal() == IDOK)\r
+ {\r
+ CString cmd,out;\r
+ if(dlg.m_bIsDelete)\r
+ {\r
+ cmd.Format(_T("git.exe rm \"%s\""),merge.GetGitPathString());\r
+ }else\r
+ cmd.Format(_T("git.exe add \"%s\""),merge.GetGitPathString());\r
+\r
+ if(g_Git.Run(cmd,&out,CP_ACP))\r
+ {\r
+ CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+ }\r
+ else \r
+ return FALSE;\r
+\r
+ \r
+\r
+ }\r
+\r
+#if 0\r
+\r
+ CAppUtils::StartExtMerge(CAppUtils::MergeFlags().AlternativeTool(bAlternativeTool), \r
+ base, theirs, mine, merge);\r
+#endif\r
+#if 0\r
+ if (stat.status->text_status == svn_wc_status_conflicted)\r
+ {\r
+ // we have a text conflict, use our merge tool to resolve the conflict\r
+\r
+ CTSVNPath theirs(directory);\r
+ CTSVNPath mine(directory);\r
+ CTSVNPath base(directory);\r
+ bool bConflictData = false;\r
+\r
+ if ((stat.status->entry)&&(stat.status->entry->conflict_new))\r
+ {\r
+ theirs.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_new));\r
+ bConflictData = true;\r
+ }\r
+ if ((stat.status->entry)&&(stat.status->entry->conflict_old))\r
+ {\r
+ base.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_old));\r
+ bConflictData = true;\r
+ }\r
+ if ((stat.status->entry)&&(stat.status->entry->conflict_wrk))\r
+ {\r
+ mine.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->conflict_wrk));\r
+ bConflictData = true;\r
+ }\r
+ else\r
+ {\r
+ mine = merge;\r
+ }\r
+ if (bConflictData)\r
+ bRet = !!CAppUtils::StartExtMerge(CAppUtils::MergeFlags().AlternativeTool(bAlternativeTool), \r
+ base, theirs, mine, merge);\r
+ }\r
+\r
+ if (stat.status->prop_status == svn_wc_status_conflicted)\r
+ {\r
+ // we have a property conflict\r
+ CTSVNPath prej(directory);\r
+ if ((stat.status->entry)&&(stat.status->entry->prejfile))\r
+ {\r
+ prej.AppendPathString(CUnicodeUtils::GetUnicode(stat.status->entry->prejfile));\r
+ // there's a problem: the prej file contains a _description_ of the conflict, and\r
+ // that description string might be translated. That means we have no way of parsing\r
+ // the file to find out the conflicting values.\r
+ // The only thing we can do: show a dialog with the conflict description, then\r
+ // let the user either accept the existing property or open the property edit dialog\r
+ // to manually change the properties and values. And a button to mark the conflict as\r
+ // resolved.\r
+ CEditPropConflictDlg dlg;\r
+ dlg.SetPrejFile(prej);\r
+ dlg.SetConflictedItem(merge);\r
+ bRet = (dlg.DoModal() != IDCANCEL);\r
+ }\r
+ }\r
+\r
+ if (stat.status->tree_conflict)\r
+ {\r
+ // we have a tree conflict\r
+ SVNInfo info;\r
+ const SVNInfoData * pInfoData = info.GetFirstFileInfo(merge, SVNRev(), SVNRev());\r
+ if (pInfoData)\r
+ {\r
+ if (pInfoData->treeconflict_kind == svn_wc_conflict_kind_text)\r
+ {\r
+ CTSVNPath theirs(directory);\r
+ CTSVNPath mine(directory);\r
+ CTSVNPath base(directory);\r
+ bool bConflictData = false;\r
+\r
+ if (pInfoData->treeconflict_theirfile)\r
+ {\r
+ theirs.AppendPathString(pInfoData->treeconflict_theirfile);\r
+ bConflictData = true;\r
+ }\r
+ if (pInfoData->treeconflict_basefile)\r
+ {\r
+ base.AppendPathString(pInfoData->treeconflict_basefile);\r
+ bConflictData = true;\r
+ }\r
+ if (pInfoData->treeconflict_myfile)\r
+ {\r
+ mine.AppendPathString(pInfoData->treeconflict_myfile);\r
+ bConflictData = true;\r
+ }\r
+ else\r
+ {\r
+ mine = merge;\r
+ }\r
+ if (bConflictData)\r
+ bRet = !!CAppUtils::StartExtMerge(CAppUtils::MergeFlags().AlternativeTool(bAlternativeTool),\r
+ base, theirs, mine, merge);\r
+ }\r
+ else if (pInfoData->treeconflict_kind == svn_wc_conflict_kind_tree)\r
+ {\r
+ CString sConflictAction;\r
+ CString sConflictReason;\r
+ CString sResolveTheirs;\r
+ CString sResolveMine;\r
+ CTSVNPath treeConflictPath = CTSVNPath(pInfoData->treeconflict_path);\r
+ CString sItemName = treeConflictPath.GetUIFileOrDirectoryName();\r
+ \r
+ if (pInfoData->treeconflict_nodekind == svn_node_file)\r
+ {\r
+ switch (pInfoData->treeconflict_operation)\r
+ {\r
+ case svn_wc_operation_update:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILEUPDATEDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);\r
+ break;\r
+ }\r
+ break;\r
+ case svn_wc_operation_switch:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILESWITCHDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);\r
+ break;\r
+ }\r
+ break;\r
+ case svn_wc_operation_merge:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILEMERGEEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sResolveTheirs.Format(IDS_TREECONFLICT_FILEMERGEADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYFILE);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_FILEMERGEDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEFILE);\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ else if (pInfoData->treeconflict_nodekind == svn_node_dir)\r
+ {\r
+ switch (pInfoData->treeconflict_operation)\r
+ {\r
+ case svn_wc_operation_update:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRUPDATEDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);\r
+ break;\r
+ }\r
+ break;\r
+ case svn_wc_operation_switch:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRSWITCHDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);\r
+ break;\r
+ }\r
+ break;\r
+ case svn_wc_operation_merge:\r
+ switch (pInfoData->treeconflict_action)\r
+ {\r
+ case svn_wc_conflict_action_edit:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEEDIT, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_add:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEADD, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_KEEPREPOSITORYDIR);\r
+ break;\r
+ case svn_wc_conflict_action_delete:\r
+ sConflictAction.Format(IDS_TREECONFLICT_DIRMERGEDELETE, (LPCTSTR)sItemName);\r
+ sResolveTheirs.LoadString(IDS_TREECONFLICT_RESOLVE_REMOVEDIR);\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ UINT uReasonID = 0;\r
+ switch (pInfoData->treeconflict_reason)\r
+ { \r
+ case svn_wc_conflict_reason_edited:\r
+ uReasonID = IDS_TREECONFLICT_REASON_EDITED;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);\r
+ break;\r
+ case svn_wc_conflict_reason_obstructed:\r
+ uReasonID = IDS_TREECONFLICT_REASON_OBSTRUCTED;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);\r
+ break;\r
+ case svn_wc_conflict_reason_deleted:\r
+ uReasonID = IDS_TREECONFLICT_REASON_DELETED;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_REMOVEDIR : IDS_TREECONFLICT_RESOLVE_REMOVEFILE);\r
+ break;\r
+ case svn_wc_conflict_reason_added:\r
+ uReasonID = IDS_TREECONFLICT_REASON_ADDED;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);\r
+ break;\r
+ case svn_wc_conflict_reason_missing:\r
+ uReasonID = IDS_TREECONFLICT_REASON_MISSING;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_REMOVEDIR : IDS_TREECONFLICT_RESOLVE_REMOVEFILE);\r
+ break;\r
+ case svn_wc_conflict_reason_unversioned:\r
+ uReasonID = IDS_TREECONFLICT_REASON_UNVERSIONED;\r
+ sResolveMine.LoadString(pInfoData->treeconflict_nodekind == svn_node_dir ? IDS_TREECONFLICT_RESOLVE_KEEPLOCALDIR : IDS_TREECONFLICT_RESOLVE_KEEPLOCALFILE);\r
+ break;\r
+ }\r
+ sConflictReason.Format(uReasonID, (LPCTSTR)sConflictAction);\r
+\r
+ CTreeConflictEditorDlg dlg;\r
+ dlg.SetConflictInfoText(sConflictReason);\r
+ dlg.SetResolveTexts(sResolveTheirs, sResolveMine);\r
+ dlg.SetPath(treeConflictPath);\r
+ INT_PTR dlgRet = dlg.DoModal();\r
+ bRet = (dlgRet != IDCANCEL);\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ return bRet;\r
+}\r
+\r
+/**\r
+ * FUNCTION : FormatDateAndTime\r
+ * DESCRIPTION : Generates a displayable string from a CTime object in\r
+ * system short or long format or as a relative value\r
+ * cTime - the time\r
+ * option - DATE_SHORTDATE or DATE_LONGDATE\r
+ * bIncluedeTime - whether to show time as well as date\r
+ * bRelative - if true then relative time is shown if reasonable \r
+ * If HKCU\Software\TortoiseGit\UseSystemLocaleForDates is 0 then use fixed format\r
+ * rather than locale\r
+ * RETURN : CString containing date/time\r
+ */\r
+CString CAppUtils::FormatDateAndTime( const CTime& cTime, DWORD option, bool bIncludeTime /*=true*/,\r
+ bool bRelative /*=false*/)\r
+{\r
+ CString datetime;\r
+ if ( bRelative )\r
+ {\r
+ datetime = ToRelativeTimeString( cTime );\r
+ }\r
+ else\r
+ {\r
+ // should we use the locale settings for formatting the date/time?\r
+ if (CRegDWORD(_T("Software\\TortoiseGit\\UseSystemLocaleForDates"), TRUE))\r
+ {\r
+ // yes\r
+ SYSTEMTIME sysTime;\r
+ cTime.GetAsSystemTime( sysTime );\r
+ \r
+ TCHAR buf[100];\r
+ \r
+ GetDateFormat(LOCALE_USER_DEFAULT, option, &sysTime, NULL, buf, \r
+ sizeof(buf)/sizeof(TCHAR)-1);\r
+ datetime = buf;\r
+ if ( bIncludeTime )\r
+ {\r
+ datetime += _T(" ");\r
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, buf, sizeof(buf)/sizeof(TCHAR)-1);\r
+ datetime += buf;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // no, so fixed format\r
+ if ( bIncludeTime )\r
+ {\r
+ datetime = cTime.Format(_T("%Y-%m-%d %H:%M:%S"));\r
+ }\r
+ else\r
+ {\r
+ datetime = cTime.Format(_T("%Y-%m-%d"));\r
+ }\r
+ }\r
+ }\r
+ return datetime;\r
+}\r
+\r
+/**\r
+ * Converts a given time to a relative display string (relative to current time)\r
+ * Given time must be in local timezone\r
+ */\r
+CString CAppUtils::ToRelativeTimeString(CTime time)\r
+{\r
+ CString answer;\r
+ // convert to COleDateTime\r
+ SYSTEMTIME sysTime;\r
+ time.GetAsSystemTime( sysTime );\r
+ COleDateTime oleTime( sysTime );\r
+ answer = ToRelativeTimeString(oleTime, COleDateTime::GetCurrentTime());\r
+ return answer;\r
+}\r
+\r
+/**\r
+ * Generates a display string showing the relative time between the two given times as COleDateTimes\r
+ */\r
+CString CAppUtils::ToRelativeTimeString(COleDateTime time,COleDateTime RelativeTo)\r
+{\r
+ CString answer;\r
+ COleDateTimeSpan ts = RelativeTo - time;\r
+ //years\r
+ if(fabs(ts.GetTotalDays()) >= 3*365)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalDays()/365, IDS_YEAR_AGO, IDS_YEARS_AGO );\r
+ }\r
+ //Months\r
+ if(fabs(ts.GetTotalDays()) >= 60)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalDays()/30, IDS_MONTH_AGO, IDS_MONTHS_AGO );\r
+ return answer;\r
+ }\r
+ //Weeks\r
+ if(fabs(ts.GetTotalDays()) >= 14)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalDays()/7, IDS_WEEK_AGO, IDS_WEEKS_AGO );\r
+ return answer;\r
+ }\r
+ //Days\r
+ if(fabs(ts.GetTotalDays()) >= 2)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalDays(), IDS_DAY_AGO, IDS_DAYS_AGO );\r
+ return answer;\r
+ }\r
+ //hours\r
+ if(fabs(ts.GetTotalHours()) >= 2)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalHours(), IDS_HOUR_AGO, IDS_HOURS_AGO );\r
+ return answer;\r
+ }\r
+ //minutes\r
+ if(fabs(ts.GetTotalMinutes()) >= 2)\r
+ {\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalMinutes(), IDS_MINUTE_AGO, IDS_MINUTES_AGO );\r
+ return answer;\r
+ }\r
+ //seconds\r
+ answer = ExpandRelativeTime( (int)ts.GetTotalSeconds(), IDS_SECOND_AGO, IDS_SECONDS_AGO );\r
+ return answer;\r
+}\r
+\r
+/** \r
+ * Passed a value and two resource string ids\r
+ * if count is 1 then FormatString is called with format_1 and the value\r
+ * otherwise format_2 is used\r
+ * the formatted string is returned\r
+*/\r
+CString CAppUtils::ExpandRelativeTime( int count, UINT format_1, UINT format_n )\r
+{\r
+ CString answer;\r
+ if ( count == 1 )\r
+ {\r
+ answer.FormatMessage( format_1, count );\r
+ }\r
+ else\r
+ {\r
+ answer.FormatMessage( format_n, count );\r
+ }\r
+ return answer;\r
+}\r
+\r
+bool CAppUtils::IsSSHPutty()\r
+{\r
+ CString sshclient=CRegString(_T("Software\\TortoiseGit\\SSH"));\r
+ sshclient=sshclient.MakeLower();\r
+ if(sshclient.Find(_T("plink.exe"),0)>=0)\r
+ {\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+CString CAppUtils::GetClipboardLink()\r
+{\r
+ if (!OpenClipboard(NULL))\r
+ return CString();\r
+\r
+ CString sClipboardText;\r
+ HGLOBAL hglb = GetClipboardData(CF_TEXT);\r
+ if (hglb)\r
+ {\r
+ LPCSTR lpstr = (LPCSTR)GlobalLock(hglb);\r
+ sClipboardText = CString(lpstr);\r
+ GlobalUnlock(hglb); \r
+ }\r
+ hglb = GetClipboardData(CF_UNICODETEXT);\r
+ if (hglb)\r
+ {\r
+ LPCTSTR lpstr = (LPCTSTR)GlobalLock(hglb);\r
+ sClipboardText = lpstr;\r
+ GlobalUnlock(hglb); \r
+ }\r
+ CloseClipboard();\r
+\r
+ if(!sClipboardText.IsEmpty())\r
+ {\r
+ if(sClipboardText[0] == _T('\"') && sClipboardText[sClipboardText.GetLength()-1] == _T('\"'))\r
+ sClipboardText=sClipboardText.Mid(1,sClipboardText.GetLength()-2);\r
+\r
+ if(sClipboardText.Find( _T("http://")) == 0)\r
+ return sClipboardText;\r
+ \r
+ if(sClipboardText.Find( _T("https://")) == 0)\r
+ return sClipboardText;\r
+\r
+ if(sClipboardText.Find( _T("git://")) == 0)\r
+ return sClipboardText;\r
+\r
+ if(sClipboardText.Find( _T("ssh://")) == 0)\r
+ return sClipboardText;\r
+\r
+ if(sClipboardText.GetLength()>=2)\r
+ if( sClipboardText[1] == _T(':') )\r
+ if( (sClipboardText[0] >= 'A' && sClipboardText[0] <= 'Z') \r
+ || (sClipboardText[0] >= 'a' && sClipboardText[0] <= 'z') )\r
+ return sClipboardText;\r
+ }\r
+\r
+ return CString(_T(""));\r
+}\r
+\r
+CString CAppUtils::ChooseRepository(CString *path)\r
+{\r
+ CBrowseFolder browseFolder;\r
+ browseFolder.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;\r
+ CString strCloneDirectory;\r
+ if(path)\r
+ strCloneDirectory=*path;\r
+\r
+ CString title;\r
+ title.LoadString(IDS_CHOOSE_REPOSITORY);\r
+\r
+ browseFolder.SetInfo(title);\r
+\r
+ if (browseFolder.Show(NULL, strCloneDirectory) == CBrowseFolder::OK) \r
+ {\r
+ return strCloneDirectory;\r
+ \r
+ }else\r
+ {\r
+ return CString();\r
+ }\r
+ \r
+}\r
+\r
+bool CAppUtils::SendPatchMail(CTGitPathList &list,bool autoclose)\r
+{\r
+ CSendMailDlg dlg;\r
+\r
+ dlg.m_PathList = list;\r
+ \r
+ if(dlg.DoModal()==IDOK)\r
+ {\r
+ if(dlg.m_PathList.GetCount() == 0)\r
+ return FALSE;\r
+ \r
+ CGitProgressDlg progDlg;\r
+ \r
+ theApp.m_pMainWnd = &progDlg;\r
+ progDlg.SetCommand(CGitProgressDlg::GitProgress_SendMail);\r
+ \r
+ progDlg.SetAutoClose(autoclose);\r
+\r
+ progDlg.SetPathList(dlg.m_PathList);\r
+ //ProjectProperties props;\r
+ //props.ReadPropsPathList(dlg.m_pathList);\r
+ //progDlg.SetProjectProperties(props);\r
+ progDlg.SetItemCount(dlg.m_PathList.GetCount());\r
+\r
+ DWORD flags =0;\r
+ if(dlg.m_bAttachment)\r
+ flags |= SENDMAIL_ATTACHMENT;\r
+ if(dlg.m_bCombine)\r
+ flags |= SENDMAIL_COMBINED;\r
+\r
+ progDlg.SetSendMailOption(dlg.m_To,dlg.m_CC,dlg.m_Subject,flags);\r
+ \r
+ progDlg.DoModal(); \r
+\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+int CAppUtils::GetLogOutputEncode()\r
+{\r
+ CString cmd,output;\r
+ int start=0;\r
+ cmd=_T("git.exe config i18n.logOutputEncoding");\r
+ if(g_Git.Run(cmd,&output,CP_ACP))\r
+ {\r
+ cmd=_T("git.exe config i18n.commitencoding");\r
+ if(g_Git.Run(cmd,&output,CP_ACP))\r
+ return CP_UTF8;\r
+ \r
+ int start=0;\r
+ output=output.Tokenize(_T("\n"),start);\r
+ return CUnicodeUtils::GetCPCode(output); \r
+\r
+ }else\r
+ {\r
+ output=output.Tokenize(_T("\n"),start);\r
+ return CUnicodeUtils::GetCPCode(output);\r
+ }\r
+}\r
+int CAppUtils::SaveCommitUnicodeFile(CString &filename, CString &message)\r
+{\r
+ CFile file(filename,CFile::modeReadWrite|CFile::modeCreate );\r
+ CString cmd,output;\r
+ int cp=CP_UTF8;\r
+\r
+ cmd=_T("git.exe config i18n.commitencoding");\r
+ if(g_Git.Run(cmd,&output,CP_ACP))\r
+ cp=CP_UTF8;\r
+ \r
+ int start=0;\r
+ output=output.Tokenize(_T("\n"),start);\r
+ cp=CUnicodeUtils::GetCPCode(output); \r
+\r
+ int len=message.GetLength();\r
+\r
+ char * buf;\r
+ buf = new char[len*4 + 4];\r
+ SecureZeroMemory(buf, (len*4 + 4));\r
+\r
+ int lengthIncTerminator = WideCharToMultiByte(cp, 0, message, -1, buf, len*4, NULL, NULL);\r
+\r
+ file.Write(buf,lengthIncTerminator-1);\r
+ file.Close();\r
+ delete buf;\r
+ return 0;\r
+}\r
+\r
+bool CAppUtils::Push()\r
+{\r
+ CPushDlg dlg;\r
+// dlg.m_Directory=this->orgCmdLinePath.GetWinPathString();\r
+ if(dlg.DoModal()==IDOK)\r
+ {\r
+// CString dir=dlg.m_Directory;\r
+// CString url=dlg.m_URL;\r
+ CString cmd;\r
+ CString force;\r
+ CString tags;\r
+ CString thin;\r
+\r
+ if(dlg.m_bAutoLoad)\r
+ {\r
+ CAppUtils::LaunchPAgent(NULL,&dlg.m_URL);\r
+ }\r
+\r
+ if(dlg.m_bPack)\r
+ thin=_T("--thin");\r
+ if(dlg.m_bTags)\r
+ tags=_T("--tags");\r
+ if(dlg.m_bForce)\r
+ force=_T("--force");\r
+ \r
+ cmd.Format(_T("git.exe push %s %s %s \"%s\" %s"),\r
+ thin,tags,force,\r
+ dlg.m_URL,\r
+ dlg.m_BranchSourceName);\r
+ if (!dlg.m_BranchRemoteName.IsEmpty())\r
+ {\r
+ cmd += _T(":") + dlg.m_BranchRemoteName;\r
+ }\r
+\r
+ CProgressDlg progress;\r
+ progress.m_GitCmd=cmd;\r
+ if(progress.DoModal()==IDOK)\r
+ return TRUE;\r
+ \r
+ }\r
+ return FALSE;\r
+}\r
+\r
+bool CAppUtils::CreateMultipleDirectory(CString& szPath)\r
+{\r
+ CString strDir(szPath);\r
+ if (strDir.GetAt(strDir.GetLength()-1)!=_T('\\'))\r
+ {\r
+ strDir.AppendChar(_T('\\'));\r
+ }\r
+ std::vector<CString> vPath;\r
+ CString strTemp;\r
+ bool bSuccess = false;\r
+ \r
+ for (int i=0;i<strDir.GetLength();++i)\r
+ {\r
+ if (strDir.GetAt(i) != _T('\\')) \r
+ {\r
+ strTemp.AppendChar(strDir.GetAt(i));\r
+ }\r
+ else \r
+ {\r
+ vPath.push_back(strTemp);\r
+ strTemp.AppendChar(_T('\\'));\r
+ }\r
+ }\r
+\r
+ std::vector<CString>::const_iterator vIter;\r
+ for (vIter = vPath.begin(); vIter != vPath.end(); vIter++) \r
+ {\r
+ bSuccess = CreateDirectory(*vIter, NULL) ? true : false; \r
+ }\r
+\r
+ return bSuccess;\r
+}\r