Beispiel #1
0
void CSyncDlg::RunPostAction()
{
	if (m_bWantToExit)
		return;

	FillNewRefMap();

	if (this->m_CurrentCmd == GIT_COMMAND_PUSH)
	{
		if (!m_GitCmdStatus)
		{
			CTGitPathList list;
			list.AddPath(CTGitPath(g_Git.m_CurrentDir));
			DWORD exitcode;
			CString error;
			if (CHooks::Instance().PostPush(list,exitcode, error))
			{
				if (exitcode)
				{
					CString temp;
					temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
					//ReportError(temp);
					CMessageBox::Show(NULL,temp,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
					return;
				}
			}

		}
		EnableControlButton(true);
		SwitchToInput();
		this->FetchOutList(true);
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_PULL)
	{
		PullComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_FETCH || this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)
	{
		FetchComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_SUBMODULE)
	{
		//this->m_ctrlCmdOut.SetSel(-1,-1);
		//this->m_ctrlCmdOut.ReplaceSel(_T("Done\r\n"));
		//this->m_ctrlCmdOut.SetSel(-1,-1);
		EnableControlButton(true);
		SwitchToInput();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_STASH)
	{
		StashComplete();
	}
	else if (this->m_CurrentCmd == GIT_COMMAND_REMOTE)
	{
		this->FetchOutList(true);
		EnableControlButton(true);
		SwitchToInput();
		ShowTab(IDC_REFLIST);
	}
}
Beispiel #2
0
void CRebaseDlg::ListConflictFile()
{
	this->m_FileListCtrl.Clear();
	CTGitPathList list;
	CTGitPath path;
	list.AddPath(path);

	m_FileListCtrl.m_bIsRevertTheirMy = !m_IsCherryPick;

	this->m_FileListCtrl.GetStatus(&list,true);
	this->m_FileListCtrl.Show(CTGitPath::LOGACTIONS_UNMERGED|CTGitPath::LOGACTIONS_MODIFIED|CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_DELETED,
							   CTGitPath::LOGACTIONS_UNMERGED);
}
Beispiel #3
0
static bool GetFilesToCleanUp(CTGitPathList& delList, const CString& baseCmd, CGit *pGit, const CString& path, const boolean quotepath, CSysProgressDlg& sysProgressDlg)
{
    CString cmd(baseCmd);
    if (!path.IsEmpty())
        cmd += _T(" -- \"") + path + _T("\"");

    CString cmdout, cmdouterr;
    if (pGit->Run(cmd, &cmdout, &cmdouterr, CP_UTF8))
    {
        MessageBox(nullptr, cmdouterr, _T("TortoiseGit"), MB_ICONERROR);
        return false;
    }

    if (sysProgressDlg.HasUserCancelled())
    {
        CMessageBox::Show(nullptr, IDS_USERCANCELLED, IDS_APPNAME, MB_OK);
        return false;
    }

    int pos = 0;
    CString token = cmdout.Tokenize(_T("\n"), pos);
    while (!token.IsEmpty())
    {
        if (token.Mid(0, 13) == _T("Would remove "))
        {
            CString tempPath = token.Mid(13).TrimRight();
            if (quotepath)
                tempPath = UnescapeQuotePath(tempPath.Trim(_T('"')));
            delList.AddPath(pGit->CombinePath(tempPath));
        }

        token = cmdout.Tokenize(_T("\n"), pos);
    }

    if (sysProgressDlg.HasUserCancelled())
    {
        CMessageBox::Show(nullptr, IDS_USERCANCELLED, IDS_APPNAME, MB_OK);
        return false;
    }

    return true;
}
Beispiel #4
0
void CSyncDlg::StashComplete()
{
	EnableControlButton(true);
	INT_PTR entry = m_ctrlStash.GetCurrentEntry();
	if (entry != 1 && entry != 2)
		return;

	SwitchToInput();
	if (m_GitCmdStatus)
	{
		CTGitPathList list;
		if (g_Git.ListConflictFile(list))
		{
			m_ctrlCmdOut.SetSel(-1, -1);
			m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));

			ShowTab(IDC_CMD_LOG);
			return;
		}

		if (!list.IsEmpty())
		{
			m_ConflictFileList.Clear();
			CTGitPathList list;
			CTGitPath path;
			list.AddPath(path);

			m_ConflictFileList.GetStatus(&list,true);
			m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED, CTGitPath::LOGACTIONS_UNMERGED);

			ShowTab(IDC_IN_CONFLICT);
		}
		else
			ShowTab(IDC_CMD_LOG);
	}
}
Beispiel #5
0
void CSyncDlg::PullComplete()
{
	EnableControlButton(true);
	SwitchToInput();
	this->FetchOutList(true);

	CGitHash newhash;
	if (g_Git.GetHash(newhash, _T("HEAD")))
		MessageBox(g_Git.GetGitLastErr(_T("Could not get HEAD hash after pulling.")), _T("TortoiseGit"), MB_ICONERROR);

	if( this ->m_GitCmdStatus )
	{
		CTGitPathList list;
		if(g_Git.ListConflictFile(list))
		{
			this->m_ctrlCmdOut.SetSel(-1,-1);
			this->m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));

			this->ShowTab(IDC_CMD_LOG);
			return;
		}

		if (!list.IsEmpty())
		{
			this->m_ConflictFileList.Clear();
			CTGitPathList list;
			CTGitPath path;
			list.AddPath(path);

			this->m_ConflictFileList.GetStatus(&list,true);
			this->m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED,
											CTGitPath::LOGACTIONS_UNMERGED);

			this->ShowTab(IDC_IN_CONFLICT);
		}
		else
			this->ShowTab(IDC_CMD_LOG);

	}
	else
	{
		if(newhash == this->m_oldHash)
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);
			this->m_InLogList.ShowText(CString(MAKEINTRESOURCE(IDS_UPTODATE)));
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);
			this->ShowTab(IDC_REFLIST);
		}
		else
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,true);
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);

			this->AddDiffFileList(&m_InChangeFileList, &m_arInChangeList, newhash.ToString(), m_oldHash.ToString());

			CString range;
			range.Format(_T("%s..%s"), m_oldHash.ToString(), newhash.ToString());
			m_InLogList.FillGitLog(nullptr, &range, CGit::LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE);
			this->ShowTab(IDC_IN_LOGLIST);
		}
	}
}
Beispiel #6
0
void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMenu *popmenu)
{
	POSITION pos = GetFirstSelectedItemPosition();
	int indexNext = GetNextSelectedItem(pos);
	if (indexNext < 0)
		return;

	GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));

	theApp.DoWaitCursor(1);
	switch (cmd&0xFFFF)
		{
			case ID_COMMIT:
			{
				CTGitPathList pathlist;
				CTGitPathList selectedlist;
				pathlist.AddPath(this->m_Path);
				bool bSelectFilesForCommit = !!DWORD(CRegStdDWORD(_T("Software\\TortoiseGit\\SelectFilesForCommit"), TRUE));
				CString str;
				CAppUtils::Commit(CString(),false,str,
								  pathlist,selectedlist,bSelectFilesForCommit);
				//this->Refresh();
				this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH,0);
			}
			break;
			case ID_GNUDIFF1:
			{
				CString tempfile=GetTempFile();
				CString command;
				GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
				if(!r1->m_CommitHash.IsEmpty())
				{
					CString merge;
					CString hash2;
					cmd >>= 16;
					if( (cmd&0xFFFF) == 0xFFFF)
					{
						merge=_T("-m");
					}
					else if((cmd&0xFFFF) == 0xFFFE)
					{
						merge=_T("-c");
					}
					else
					{
						if(cmd > r1->m_ParentHash.size())
						{
							CString str;
							str.Format(_T("Parent %d does not exist"), cmd);
							CMessageBox::Show(NULL,str,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
							return;
						}
						else
						{
							if(cmd>0)
								hash2 = r1->m_ParentHash[cmd-1].ToString();
						}
					}
					command.Format(_T("git.exe diff-tree %s -r -p --stat %s %s"), merge, hash2, r1->m_CommitHash.ToString());
				}
				else
					command.Format(_T("git.exe diff -r -p --stat"));

				g_Git.RunLogFile(command,tempfile);
				CAppUtils::StartUnifiedDiffViewer(tempfile,r1->m_CommitHash.ToString().Left(6)+_T(":")+r1->GetSubject());
			}
bool DropCopyAddCommand::Execute()
{
	bool bRet = false;

	CString droppath = parser.GetVal(_T("droptarget"));
	if (CTGitPath(droppath).IsAdminDir())
		return FALSE;

	if(!CTGitPath(droppath).HasAdminDir(&g_Git.m_CurrentDir))
		return FALSE;

	orgPathList.RemoveAdminPaths();
	CTGitPathList copiedFiles;
	for(int nPath = 0; nPath < orgPathList.GetCount(); nPath++)
	{
		if (!orgPathList[nPath].IsEquivalentTo(CTGitPath(droppath)))
		{
			//copy the file to the new location
			CString name = orgPathList[nPath].GetFileOrDirectoryName();
			if (::PathFileExists(droppath+_T("\\")+name))
			{
				CString strMessage;
				strMessage.Format(IDS_PROC_OVERWRITE_CONFIRM, (LPCTSTR)(droppath+_T("\\")+name));
				int ret = CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_YESNOCANCEL | MB_ICONQUESTION);
				if (ret == IDYES)
				{
					if (!::CopyFile(orgPathList[nPath].GetWinPath(), droppath+_T("\\")+name, FALSE))
					{
						//the copy operation failed! Get out of here!
						ShowErrorMessage();
						return FALSE;
					}
				}
				if (ret == IDCANCEL)
				{
					return FALSE;		//cancel the whole operation
				}
			}
			else if (!CopyFile(orgPathList[nPath].GetWinPath(), droppath+_T("\\")+name, FALSE))
			{
				//the copy operation failed! Get out of here!
				ShowErrorMessage();
				return FALSE;
			}
			copiedFiles.AddPath(CTGitPath(droppath+_T("\\")+name));		//add the new filepath
		}
	}
	//now add all the newly copied files to the working copy
	CGitProgressDlg progDlg;
	theApp.m_pMainWnd = &progDlg;
	progDlg.SetCommand(CGitProgressDlg::GitProgress_Add);
	if (parser.HasVal(_T("closeonend")))
		progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));
	progDlg.SetPathList(copiedFiles);
	ProjectProperties props;
	props.ReadPropsPathList(copiedFiles);
	progDlg.SetProjectProperties(props);
	progDlg.DoModal();
	bRet = !progDlg.DidErrorsOccur();

	return bRet;
}
Beispiel #8
0
bool CloneCommand::Execute()
{
	CTGitPath cloneDirectory;
	if (!parser.HasKey(_T("hasurlhandler")))
	{
		if (orgCmdLinePath.IsEmpty())
		{
			cloneDirectory.SetFromWin(sOrigCWD, true);
			DWORD len = ::GetTempPath(0, NULL);
			std::unique_ptr<TCHAR[]> tszPath(new TCHAR[len]);
			::GetTempPath(len, tszPath.get());
			if (_tcsncicmp(cloneDirectory.GetWinPath(), tszPath.get(), len-2 /* \\ and \0 */) == 0)
			{
				// if the current directory is set to a temp directory,
				// we don't use that but leave it empty instead.
				cloneDirectory.Reset();
			}
		}
		else
			cloneDirectory = orgCmdLinePath;
	}

	CCloneDlg dlg;
	dlg.m_Directory = cloneDirectory.GetWinPathString();

	if (parser.HasKey(_T("url")))
		dlg.m_URL = parser.GetVal(_T("url"));
	if (parser.HasKey(_T("exactpath")))
		dlg.m_bExactPath = TRUE;

	if(dlg.DoModal()==IDOK)
	{
		CString recursiveStr;
		if(dlg.m_bRecursive)
			recursiveStr = _T("--recursive");
		else
			recursiveStr = _T("");

		CString bareStr;
		if(dlg.m_bBare)
			bareStr = _T("--bare");
		else
			bareStr = _T("");

		CString nocheckoutStr;
		if (dlg.m_bNoCheckout)
			nocheckoutStr = _T("--no-checkout");

		CString branchStr;
		if (dlg.m_bBranch)
			branchStr = _T("--branch ") + dlg.m_strBranch;

		CString originStr;
		if (dlg.m_bOrigin)
			originStr = _T("--origin ") + dlg.m_strOrigin;

		if(dlg.m_bAutoloadPuttyKeyFile)
		{
			CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);
		}

		CAppUtils::RemoveTrailSlash(dlg.m_Directory);
		if (!dlg.m_bSVN)
			CAppUtils::RemoveTrailSlash(dlg.m_URL);

		CString dir=dlg.m_Directory;
		CString url=dlg.m_URL;

		// is this a windows format UNC path, ie starts with \\?
		if (url.Find(_T("\\\\")) == 0)
		{
			// yes, change all \ to /
			// this should not be necessary but msysgit does not support the use \ here yet
			int atSign = url.Find(_T('@'));
			if (atSign > 0)
			{
				CString path = url.Mid(atSign);
				path.Replace(_T('\\'), _T('/'));
				url = url.Mid(0, atSign) + path;
			}
			else
				url.Replace( _T('\\'), _T('/'));
		}

		CString depth;
		if (dlg.m_bDepth)
		{
			depth.Format(_T(" --depth %d"),dlg.m_nDepth);
		}

		g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);

		CString cmd;
		CString progressarg;

		int ver = CAppUtils::GetMsysgitVersion();

		if(ver >= 0x01070002) //above 1.7.0.2
			progressarg = _T("--progress");

		cmd.Format(_T("git.exe clone %s %s %s %s %s %s -v %s \"%s\" \"%s\""),
						nocheckoutStr,
						recursiveStr,
						bareStr,
						branchStr,
						originStr,
						progressarg,
						depth,
						url,
						dir);

		// Handle Git SVN-clone
		if(dlg.m_bSVN)
		{
			//g_Git.m_CurrentDir=dlg.m_Directory;
			cmd.Format(_T("git.exe svn clone \"%s\"  \"%s\""),
				url,dlg.m_Directory);

			if(dlg.m_bSVNTrunk)
				cmd+=_T(" -T ")+dlg.m_strSVNTrunk;

			if(dlg.m_bSVNBranch)
				cmd+=_T(" -b ")+dlg.m_strSVNBranchs;

			if(dlg.m_bSVNTags)
				cmd+=_T(" -t ")+dlg.m_strSVNTags;

			if(dlg.m_bSVNFrom)
			{
				CString str;
				str.Format(_T("%d:HEAD"),dlg.m_nSVNFrom);
				cmd+=_T(" -r ")+str;
			}

			if(dlg.m_bSVNUserName)
			{
				cmd+= _T(" --username ");
				cmd+=dlg.m_strUserName;
			}
		}
		else
		{
			if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE))
			{
				CGitProgressDlg GitDlg;
				CTGitPathList list;
				g_Git.m_CurrentDir = dir;
				list.AddPath(CTGitPath(dir));
				GitDlg.SetCommand(CGitProgressList::GitProgress_Clone);
				GitDlg.SetUrl(url);
				GitDlg.SetPathList(list);
				GitDlg.SetIsBare(!!dlg.m_bBare);
				GitDlg.SetRefSpec(dlg.m_bBranch ? dlg.m_strBranch : CString());
				GitDlg.SetRemote(dlg.m_bOrigin ? dlg.m_strOrigin : CString());
				GitDlg.SetNoCheckout(!!dlg.m_bNoCheckout);
				GitDlg.DoModal();
				return !GitDlg.DidErrorsOccur();
			}
		}
		CProgressDlg progress;
		progress.m_GitCmd=cmd;
		progress.m_PostCmdList.Add(CString(MAKEINTRESOURCE(IDS_MENULOG)));
		progress.m_PostCmdList.Add(CString(MAKEINTRESOURCE(IDS_STATUSLIST_CONTEXT_EXPLORE)));
		INT_PTR ret = progress.DoModal();

		if (dlg.m_bSVN)
			::DeleteFile(g_Git.m_CurrentDir + _T("\\sys$command"));

		if( progress.m_GitStatus == 0)
		{
			if(dlg.m_bAutoloadPuttyKeyFile)
			{
				g_Git.m_CurrentDir = dlg.m_Directory;
				SetCurrentDirectory(g_Git.m_CurrentDir);

				if(g_Git.SetConfigValue(_T("remote.origin.puttykeyfile"), dlg.m_strPuttyKeyFile, CONFIG_LOCAL, CP_UTF8))
				{
					CMessageBox::Show(NULL,_T("Fail set config remote.origin.puttykeyfile"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);
					return FALSE;
				}
			}
			if (ret == IDC_PROGRESS_BUTTON1)
			{
				CString cmd = _T("/command:log");
				cmd += _T(" /path:\"") + dlg.m_Directory + _T("\"");
				CAppUtils::RunTortoiseGitProc(cmd);
				return TRUE;
			}
			if (ret == IDC_PROGRESS_BUTTON1 + 1)
			{
				ShellExecute(nullptr, _T("explore"), dlg.m_Directory, nullptr, nullptr, SW_SHOW);
				return TRUE;
			}
		}
		if(ret == IDOK)
			return TRUE;

	}
	return FALSE;
}
bool CleanupCommand::Execute()
{
	bool bRet = false;

	CCleanTypeDlg dlg;
	if( dlg.DoModal() == IDOK)
	{
		bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath"));

		CString cmd;
		cmd.Format(_T("git.exe clean"));
		if (dlg.m_bDryRun || !dlg.m_bNoRecycleBin)
			cmd += _T(" -n ");
		if(dlg.m_bDir)
			cmd += _T(" -d ");
		switch(dlg.m_CleanType)
		{
		case 0:
			cmd += _T(" -fx");
			break;
		case 1:
			cmd += _T(" -f");
			break;
		case 2:
			cmd += _T(" -fX");
			break;
		}

		STRING_VECTOR submoduleList;
		SubmodulePayload payload(submoduleList);
		if (dlg.m_bSubmodules)
		{
			payload.basePath = CTGitPath(g_Git.m_CurrentDir).GetGitPathString();
			if (pathList.GetCount() != 1 || pathList.GetCount() == 1 && !pathList[0].IsEmpty())
			{
				for (int i = 0; i < pathList.GetCount(); ++i)
				{
					CString path;
					if (pathList[i].IsDirectory())
						payload.prefixList.push_back(pathList[i].GetGitPathString());
					else
						payload.prefixList.push_back(pathList[i].GetContainingDirectory().GetGitPathString());
				}
			}
			if (!GetSubmodulePathList(payload))
				return FALSE;
			std::sort(submoduleList.begin(), submoduleList.end());
		}

		if (dlg.m_bDryRun || dlg.m_bNoRecycleBin)
		{
			while (true)
			{
				CProgressDlg progress;
				for (int i = 0; i < this->pathList.GetCount(); ++i)
				{
					CString path;
					if (this->pathList[i].IsDirectory())
						path = pathList[i].GetGitPathString();
					else
						path = pathList[i].GetContainingDirectory().GetGitPathString();

					progress.m_GitDirList.push_back(g_Git.m_CurrentDir);
					progress.m_GitCmdList.push_back(cmd + _T(" \"") + path + _T("\""));
				}

				if (dlg.m_bSubmodules)
				{
					for (CString dir : submoduleList)
					{
						progress.m_GitDirList.push_back(CTGitPath(dir).GetWinPathString());
						progress.m_GitCmdList.push_back(cmd);
					}
				}

				INT_PTR idRetry = -1;
				if (!dlg.m_bDryRun)
					idRetry = progress.m_PostFailCmdList.Add(CString(MAKEINTRESOURCE(IDS_MSGBOX_RETRY)));
				INT_PTR result = progress.DoModal();
				if (result == IDOK)
					return TRUE;
				if (progress.m_GitStatus && result == IDC_PROGRESS_BUTTON1 + idRetry)
					continue;
				break;
			}
		}
		else
		{
			CSysProgressDlg sysProgressDlg;
			sysProgressDlg.SetAnimation(IDR_CLEANUPANI);
			sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
			sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
			sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
			sysProgressDlg.SetShowProgressBar(false);
			sysProgressDlg.ShowModeless((HWND)NULL, true);

			CTGitPathList delList;
			for (size_t i = 0; i <= submoduleList.size(); ++i)
			{
				CGit git;
				CGit *pGit;
				if (i == 0)
					pGit = &g_Git;
				else
				{
					git.m_CurrentDir = submoduleList[i - 1];
					pGit = &git;
				}
				CString cmdout, cmdouterr;
				if (pGit->Run(cmd, &cmdout, &cmdouterr, CP_UTF8))
				{
					MessageBox(nullptr, cmdouterr, _T("TortoiseGit"), MB_ICONERROR);
					return FALSE;
				}

				if (sysProgressDlg.HasUserCancelled())
				{
					CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
					return FALSE;
				}

				int pos = 0;
				CString token = cmdout.Tokenize(_T("\n"), pos);
				while (!token.IsEmpty())
				{
					if (token.Mid(0, 13) == _T("Would remove "))
					{
						CString tempPath = token.Mid(13).TrimRight();
						if (quotepath)
						{
							tempPath = UnescapeQuotePath(tempPath.Trim(_T('"')));
						}
						if (i == 0)
							delList.AddPath(CTGitPath(tempPath));
						else
							delList.AddPath(CTGitPath(submoduleList[i - 1] + "/" + tempPath));
					}

					token = cmdout.Tokenize(_T("\n"), pos);
				}

				if (sysProgressDlg.HasUserCancelled())
				{
					CMessageBox::Show(nullptr, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
					return FALSE;
				}
			}

			delList.DeleteAllFiles(true, false);

			sysProgressDlg.Stop();
		}
	}
#if 0
	CProgressDlg progress;
	progress.SetTitle(IDS_PROC_CLEANUP);
	progress.SetAnimation(IDR_CLEANUPANI);
	progress.SetShowProgressBar(false);
	progress.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
	progress.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO2)));
	progress.ShowModeless(hwndExplorer);

	CString strSuccessfullPaths, strFailedPaths;
	for (int i=0; i<pathList.GetCount(); ++i)
	{
		SVN svn;
		if (!svn.CleanUp(pathList[i]))
		{
			strFailedPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");
			strFailedPaths += svn.GetLastErrorMessage() + _T("\n\n");
		}
		else
		{
			strSuccessfullPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");

			// after the cleanup has finished, crawl the path downwards and send a change
			// notification for every directory to the shell. This will update the
			// overlays in the left tree view of the explorer.
			CDirFileEnum crawler(pathList[i].GetWinPathString());
			CString sPath;
			bool bDir = false;
			CTSVNPathList updateList;
			while (crawler.NextFile(sPath, &bDir))
			{
				if ((bDir) && (!g_SVNAdminDir.IsAdminDirPath(sPath)))
				{
					updateList.AddPath(CTSVNPath(sPath));
				}
			}
			updateList.AddPath(pathList[i]);
			CShellUpdater::Instance().AddPathsForUpdate(updateList);
			CShellUpdater::Instance().Flush();
			updateList.SortByPathname(true);
			for (INT_PTR i=0; i<updateList.GetCount(); ++i)
			{
				SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, updateList[i].GetWinPath(), NULL);
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": notify change for path %s\n"), updateList[i].GetWinPath());
			}
		}
	}
	progress.Stop();

	CString strMessage;
	if ( !strSuccessfullPaths.IsEmpty() )
	{
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED, (LPCTSTR)strSuccessfullPaths);
		strMessage += tmp;
		bRet = true;
	}
	if ( !strFailedPaths.IsEmpty() )
	{
		if (!strMessage.IsEmpty())
			strMessage += _T("\n");
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED_FAILED, (LPCTSTR)strFailedPaths);
		strMessage += tmp;
		bRet = false;
	}
	CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | (strFailedPaths.IsEmpty()?MB_ICONINFORMATION:MB_ICONERROR));
#endif
	CShellUpdater::Instance().Flush();
	return bRet;
}
void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMenu *popmenu)
{
	POSITION pos = GetFirstSelectedItemPosition();
	int indexNext = GetNextSelectedItem(pos);
	if (indexNext < 0)
		return;

	GitRev* pSelLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(indexNext));

	theApp.DoWaitCursor(1);
	switch (cmd&0xFFFF)
		{
			case ID_COMMIT:
			{
				CTGitPathList pathlist;
				CTGitPathList selectedlist;
				pathlist.AddPath(this->m_Path);
				bool bSelectFilesForCommit = !!DWORD(CRegStdDWORD(_T("Software\\TortoiseGit\\SelectFilesForCommit"), TRUE));
				CString str;
				CAppUtils::Commit(CString(),false,str,
								  pathlist,selectedlist,bSelectFilesForCommit);
				//this->Refresh();
				this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH,0);
			}
			break;
			case ID_MERGE_ABORT:
			{
				if (CAppUtils::MergeAbort())
					this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH, 0);
			}
			break;
			case ID_GNUDIFF1: // compare with WC, unified
			{
				GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
				bool bMerge = false, bCombine = false;
				CString hash2;
				if(!r1->m_CommitHash.IsEmpty())
				{
					CString merge;
					cmd >>= 16;
					if( (cmd&0xFFFF) == 0xFFFF)
						bMerge = true;

					else if((cmd&0xFFFF) == 0xFFFE)
						bCombine = true;
					else
					{
						if(cmd > r1->m_ParentHash.size())
						{
							CString str;
							str.Format(IDS_PROC_NOPARENT, cmd);
							MessageBox(str, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
							return;
						}
						else
						{
							if(cmd>0)
								hash2 = r1->m_ParentHash[cmd-1].ToString();
						}
					}
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), hash2, CTGitPath(), r1->m_CommitHash.ToString(), false, false, false, bMerge, bCombine);
				}
				else
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), _T("HEAD"), CTGitPath(), GitRev::GetWorkingCopy(), false, false, false, bMerge, bCombine);
			}
Beispiel #11
0
LRESULT CSyncDlg::OnProgressUpdateUI(WPARAM wParam,LPARAM lParam)
{
	if(wParam == MSG_PROGRESSDLG_START)
	{
		m_ctrlAnimate.Play(0,-1,-1);
		this->m_ctrlProgress.SetPos(0);
		if (m_pTaskbarList)
		{
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
			m_pTaskbarList->SetProgressValue(m_hWnd, 0, 100);
		}
	}

	if(wParam == MSG_PROGRESSDLG_END || wParam == MSG_PROGRESSDLG_FAILED)
	{
		//m_bDone = true;
		m_ctrlAnimate.Stop();
		m_ctrlProgress.SetPos(100);
		//this->DialogEnableWindow(IDOK,TRUE);
		if (m_pTaskbarList)
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS);

		//if(wParam == MSG_PROGRESSDLG_END)
		if(this->m_CurrentCmd == GIT_COMMAND_PUSH )
		{
			if(!m_GitCmdStatus)
			{
				CTGitPathList list;
				list.AddPath(CTGitPath(g_Git.m_CurrentDir));
				DWORD exitcode;
				CString error;
				if (CHooks::Instance().PostPush(list,exitcode, error))
				{
					if (exitcode)
					{
						CString temp;
						temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
						//ReportError(temp);
						CMessageBox::Show(NULL,temp,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
						return false;
					}
				}

			}
			EnableControlButton(true);
			SwitchToInput();
			this->FetchOutList(true);
		}
		if(this->m_CurrentCmd == GIT_COMMAND_PULL )
		{
			PullComplete();
		}
		if(this->m_CurrentCmd == GIT_COMMAND_FETCH || this->m_CurrentCmd == GIT_COMMAND_FETCHANDREBASE)
		{
			FetchComplete();
		}
		if(this->m_CurrentCmd == GIT_COMMAND_SUBMODULE)
		{
			//this->m_ctrlCmdOut.SetSel(-1,-1);
			//this->m_ctrlCmdOut.ReplaceSel(_T("Done\r\n"));
			//this->m_ctrlCmdOut.SetSel(-1,-1);
			EnableControlButton(true);
			SwitchToInput();
		}
		if(this->m_CurrentCmd == GIT_COMMAND_REMOTE)
		{
			this->FetchOutList(true);
			EnableControlButton(true);
			SwitchToInput();
		}
	}

	if(lParam != 0)
		ParserCmdOutput((char)lParam);

	return 0;
}
Beispiel #12
0
void CSyncDlg::PullComplete()
{
	EnableControlButton(true);
	SwitchToInput();
	this->FetchOutList(true);

	CString newhash;
	newhash = g_Git.GetHash(_T("HEAD"));

	if( this ->m_GitCmdStatus )
	{
		CTGitPathList list;
		if(g_Git.ListConflictFile(list))
		{
			this->m_ctrlCmdOut.SetSel(-1,-1);
			this->m_ctrlCmdOut.ReplaceSel(_T("Get conflict files fail\n"));

			this->ShowTab(IDC_CMD_LOG);
			return;
		}

		if(list.GetCount()>0)
		{
			this->m_ConflictFileList.Clear();
			CTGitPathList list;
			CTGitPath path;
			list.AddPath(path);

			this->m_ConflictFileList.GetStatus(&list,true);
			this->m_ConflictFileList.Show(CTGitPath::LOGACTIONS_UNMERGED,
											CTGitPath::LOGACTIONS_UNMERGED);

			this->ShowTab(IDC_IN_CONFLICT);

			this->GetDlgItem(IDC_BUTTON_COMMIT)->ShowWindow(SW_NORMAL);
		}
		else
			this->ShowTab(IDC_CMD_LOG);

	}
	else
	{
		if(newhash == this->m_oldHash)
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,false);
			this->m_InLogList.ShowText(_T("No commits get after pull"));
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);
		}
		else
		{
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_CHANGELIST-1,true);
			this->m_ctrlTabCtrl.ShowTab(IDC_IN_LOGLIST-1,true);

			CString oldhash=m_oldHash.ToString();
			this->AddDiffFileList(&m_InChangeFileList,&m_arInChangeList,newhash,oldhash);

			m_InLogList.FillGitLog(NULL,CGit::	LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE | CGit::LOG_INFO_SHOW_MERGEDFILE,
				&oldhash,&newhash);
		}
		this->ShowTab(IDC_IN_LOGLIST);
	}
}
Beispiel #13
0
BOOL CTortoiseProcApp::InitInstance()
{
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": InitInstance\n"));
	CheckUpgrade();
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
	CMFCButton::EnableWindowsTheming();
	CHistoryCombo::m_nGitIconIndex = SYS_IMAGE_LIST().AddIcon((HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_GITCONFIG), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));

	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

	//set the resource dll for the required language
	CRegDWORD loc = CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
	long langId = loc;
	{
		CString langStr;
		langStr.Format(_T("%ld"), langId);
		CCrashReport::Instance().AddUserInfoToReport(L"LanguageID", langStr);
	}
	CString langDll;
	CStringA langpath = CStringA(CPathUtils::GetAppParentDirectory());
	langpath += "Languages";
	do
	{
		langDll.Format(_T("%sLanguages\\TortoiseProc%ld.dll"), (LPCTSTR)CPathUtils::GetAppParentDirectory(), langId);

		CString sVer = _T(STRPRODUCTVER);
		CString sFileVer = CPathUtils::GetVersionFromFile(langDll);
		if (sFileVer == sVer)
		{
			HINSTANCE hInst = LoadLibrary(langDll);
			if (hInst != NULL)
			{
				CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Load Language DLL %s\n"), langDll);
				AfxSetResourceHandle(hInst);
				break;
			}
		}
		{
			DWORD lid = SUBLANGID(langId);
			lid--;
			if (lid > 0)
			{
				langId = MAKELANGID(PRIMARYLANGID(langId), lid);
			}
			else
				langId = 0;
		}
	} while (langId != 0);
	TCHAR buf[6] = { 0 };
	_tcscpy_s(buf, _T("en"));
	langId = loc;
	// MFC uses a help file with the same name as the application by default,
	// which means we have to change that default to our language specific help files
	CString sHelppath = CPathUtils::GetAppDirectory() + _T("TortoiseGit_en.chm");
	free((void*)m_pszHelpFilePath);
	m_pszHelpFilePath=_tcsdup(sHelppath);
	sHelppath = CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseGit_en.chm");
	do
	{
		CString sLang = _T("_");
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO639LANGNAME, buf, _countof(buf)))
		{
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, buf, _countof(buf)))
		{
			sLang += _T("_");
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));

		DWORD lid = SUBLANGID(langId);
		lid--;
		if (lid > 0)
		{
			langId = MAKELANGID(PRIMARYLANGID(langId), lid);
		}
		else
			langId = 0;
	} while (langId);
	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Set Help Filename %s\n"), m_pszHelpFilePath);
	setlocale(LC_ALL, "");

	if (!g_Git.CheckMsysGitDir())
	{
		UINT ret = CMessageBox::Show(NULL, IDS_PROC_NOMSYSGIT, IDS_APPNAME, 3, IDI_HAND, IDS_PROC_SETMSYSGITPATH, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON);
		if(ret == 2)
		{
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
		}
		else if(ret == 1)
		{
			// open settings dialog
			CSinglePropSheetDlg(CString(MAKEINTRESOURCE(IDS_PROC_SETTINGS_TITLE)), new CSetMainPage(), this->GetMainWnd()).DoModal();
		}
		return FALSE;
	}
	if (CAppUtils::GetMsysgitVersion() < 0x01070a00)
	{
		int ret = CMessageBox::ShowCheck(NULL, IDS_PROC_OLDMSYSGIT, IDS_APPNAME, 1, IDI_EXCLAMATION, IDS_PROC_GOTOMSYSGITWEBSITE, IDS_ABORTBUTTON, IDS_IGNOREBUTTON, _T("OldMsysgitVersionWarning"), IDS_PROC_NOTSHOWAGAINIGNORE);
		if (ret == 1)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			ShellExecute(NULL, NULL, _T("http://msysgit.github.io/"), NULL, NULL, SW_SHOW);
			return FALSE;
		}
		else if (ret == 2)
		{
			CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
			return FALSE;
		}
	}

	{
		CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Registering Crash Report ...\n"));
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitDir", CGit::ms_LastMsysGitDir);
		CString versionString;
		versionString.Format(_T("%d"), CGit::ms_LastMsysGitVersion);
		CCrashReport::Instance().AddUserInfoToReport(L"msysGitVersion", versionString);
	}

	CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) _T(": Initializing UI components ...\n"));
	// InitCommonControls() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.

	INITCOMMONCONTROLSEX used = {
		sizeof(INITCOMMONCONTROLSEX),
			ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_DATE_CLASSES |
			ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES | ICC_LISTVIEW_CLASSES |
			ICC_NATIVEFNTCTL_CLASS | ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
			ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS |
			ICC_USEREX_CLASSES | ICC_WIN95_CLASSES
	};
	InitCommonControlsEx(&used);
	AfxOleInit();
	AfxEnableControlContainer();
	AfxInitRichEdit5();
	CWinAppEx::InitInstance();
	SetRegistryKey(_T("TortoiseGit"));
	AfxGetApp()->m_pszProfileName = _tcsdup(_T("TortoiseProc")); // w/o this ResizableLib will store data under TortoiseGitProc which is not compatible with older versions

	CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);

	hWndExplorer = NULL;
	CString sVal = parser.GetVal(_T("hwnd"));
	if (!sVal.IsEmpty())
		hWndExplorer = (HWND)_wcstoui64(sVal, nullptr, 16);

	while (GetParent(hWndExplorer)!=NULL)
		hWndExplorer = GetParent(hWndExplorer);
	if (!IsWindow(hWndExplorer))
	{
		hWndExplorer = NULL;
	}

	// if HKCU\Software\TortoiseGit\Debug is not 0, show our command line
	// in a message box
	if (CRegDWORD(_T("Software\\TortoiseGit\\Debug"), FALSE)==TRUE)
		AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);

	if (parser.HasKey(_T("urlhandler")))
	{
		CString url = parser.GetVal(_T("urlhandler"));
		if (url.Find(_T("tgit://clone/")) == 0)
		{
			url = url.Mid(13); // 21 = "tgit://clone/".GetLength()
		}
		else if (url.Find(_T("github-windows://openRepo/")) == 0)
		{
			url = url.Mid(26); // 26 = "github-windows://openRepo/".GetLength()
			int questioMark = url.Find('?');
			if (questioMark > 0)
				url = url.Left(questioMark);
		}
		else if (url.Find(_T("smartgit://cloneRepo/")) == 0)
		{
			url = url.Mid(21); // 21 = "smartgit://cloneRepo/".GetLength()
		}
		else
		{
			CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		CString newCmd;
		newCmd.Format(_T("/command:clone /url:\"%s\" /hasurlhandler"), url);
		parser = CCmdLineParser(newCmd);
	}

	if ( parser.HasKey(_T("path")) && parser.HasKey(_T("pathfile")))
	{
		CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
		return FALSE;
	}

	CTGitPath cmdLinePath;
	CTGitPathList pathList;
	if (g_sGroupingUUID.IsEmpty())
		g_sGroupingUUID = parser.GetVal(L"groupuuid");
	if ( parser.HasKey(_T("pathfile")) )
	{

		CString sPathfileArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("pathfile")));

		cmdLinePath.SetFromUnknown(sPathfileArgument);
		if (pathList.LoadFromFile(cmdLinePath)==false)
			return FALSE;		// no path specified!
		if ( parser.HasKey(_T("deletepathfile")) )
		{
			// We can delete the temporary path file, now that we've loaded it
			::DeleteFile(cmdLinePath.GetWinPath());
		}
		// This was a path to a temporary file - it's got no meaning now, and
		// anybody who uses it again is in for a problem...
		cmdLinePath.Reset();

	}
	else
	{

		CString sPathArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("path")));
		if (parser.HasKey(_T("expaths")))
		{
			// an /expaths param means we're started via the buttons in our Win7 library
			// and that means the value of /expaths is the current directory, and
			// the selected paths are then added as additional parameters but without a key, only a value

			// because of the "strange treatment of quotation marks and backslashes by CommandLineToArgvW"
			// we have to escape the backslashes first. Since we're only dealing with paths here, that's
			// a save bet.
			// Without this, a command line like:
			// /command:commit /expaths:"D:\" "D:\Utils"
			// would fail because the "D:\" is treated as the backslash being the escape char for the quotation
			// mark and we'd end up with:
			// argv[1] = /command:commit
			// argv[2] = /expaths:D:" D:\Utils
			// See here for more details: http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
			CString cmdLine = GetCommandLineW();
			cmdLine.Replace(L"\\", L"\\\\");
			int nArgs = 0;
			LPWSTR *szArglist = CommandLineToArgvW(cmdLine, &nArgs);
			if (szArglist)
			{
				// argument 0 is the process path, so start with 1
				for (int i = 1; i < nArgs; ++i)
				{
					if (szArglist[i][0] != '/')
					{
						if (!sPathArgument.IsEmpty())
							sPathArgument += '*';
						sPathArgument += szArglist[i];
					}
				}
				sPathArgument.Replace(L"\\\\", L"\\");
			}
			LocalFree(szArglist);
		}
		if (sPathArgument.IsEmpty() && parser.HasKey(L"path"))
		{
			CMessageBox::Show(hWndExplorer, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}
		int asterisk = sPathArgument.Find('*');
		cmdLinePath.SetFromUnknown(asterisk >= 0 ? sPathArgument.Left(asterisk) : sPathArgument);
		pathList.LoadFromAsteriskSeparatedString(sPathArgument);
	}

	if (pathList.IsEmpty()) {
		pathList.AddPath(CTGitPath::CTGitPath(g_Git.m_CurrentDir));
	}

	// Set CWD to temporary dir, and restore it later
	{
		DWORD len = GetCurrentDirectory(0, NULL);
		if (len)
		{
			std::unique_ptr<TCHAR[]> originalCurrentDirectory(new TCHAR[len]);
			if (GetCurrentDirectory(len, originalCurrentDirectory.get()))
			{
				sOrigCWD = originalCurrentDirectory.get();
				sOrigCWD = CPathUtils::GetLongPathname(sOrigCWD);
			}
		}
		TCHAR pathbuf[MAX_PATH] = {0};
		GetTortoiseGitTempPath(MAX_PATH, pathbuf);
		SetCurrentDirectory(pathbuf);
	}

	CheckForNewerVersion();

	CAutoGeneralHandle TGitMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe"));
	if (!g_Git.SetCurrentDir(cmdLinePath.GetWinPathString(), parser.HasKey(_T("submodule")) == TRUE))
	{
		for (int i = 0; i < pathList.GetCount(); ++i)
			if(g_Git.SetCurrentDir(pathList[i].GetWinPath()))
				break;
	}

	if(!g_Git.m_CurrentDir.IsEmpty())
	{
		sOrigCWD = g_Git.m_CurrentDir;
		SetCurrentDirectory(g_Git.m_CurrentDir);
	}

	if (g_sGroupingUUID.IsEmpty())
	{
		CRegStdDWORD groupSetting = CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3);
		switch (DWORD(groupSetting))
		{
		case 1:
		case 2:
			// implemented differently to TortoiseSVN atm
			break;
		case 3:
		case 4:
			{
				CString wcroot;
				if (g_GitAdminDir.HasAdminDir(g_Git.m_CurrentDir, true, &wcroot))
				{
					git_oid oid;
					CStringA wcRootA(wcroot + CPathUtils::GetAppDirectory());
					if (!git_odb_hash(&oid, wcRootA, wcRootA.GetLength(), GIT_OBJ_BLOB))
					{
						CStringA hash;
						git_oid_tostr(hash.GetBufferSetLength(GIT_OID_HEXSZ + 1), GIT_OID_HEXSZ + 1, &oid);
						hash.ReleaseBuffer();
						g_sGroupingUUID = hash;
					}
					ProjectProperties pp;
					pp.ReadProps();
					CString icon = pp.sIcon;
					icon.Replace('/', '\\');
					if (icon.IsEmpty())
						g_bGroupingRemoveIcon = true;
					g_sGroupingIcon = icon;
				}
			}
		}
	}

	CString sAppID = GetTaskIDPerUUID(g_sGroupingUUID).c_str();
	InitializeJumpList(sAppID);
	EnsureGitLibrary(false);

	{
		CString err;
		try
		{
			// requires CWD to be set
			CGit::m_LogEncode = CAppUtils::GetLogOutputEncode();

			// make sure all config files are read in order to check that none contains an error
			g_Git.GetConfigValue(_T("doesnot.exist"));
		}
		catch (char* msg)
		{
			err = CString(msg);
		}

		if (!err.IsEmpty())
		{
			UINT choice = CMessageBox::Show(hWndExplorer, err, _T("TortoiseGit"), 1, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_PROC_EDITLOCALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_PROC_EDITGLOBALGITCONFIG)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
			if (choice == 1)
			{
				// open the config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitLocalConfig());
			}
			else if (choice == 2)
			{
				// open the global config file with alternative editor
				CAppUtils::LaunchAlternativeEditor(g_Git.GetGitGlobalConfig());
			}
			return FALSE;
		}
	}

	// execute the requested command
	CommandServer server;
	Command * cmd = server.GetCommand(parser.GetVal(_T("command")));
	if (cmd)
	{
		cmd->SetExplorerHwnd(hWndExplorer);

		cmd->SetParser(parser);
		cmd->SetPaths(pathList, cmdLinePath);

		retSuccess = cmd->Execute();
		delete cmd;
	}

	// Look for temporary files left around by TortoiseSVN and
	// remove them. But only delete 'old' files because some
	// apps might still be needing the recent ones.
	{
		DWORD len = GetTortoiseGitTempPath(0, NULL);
		std::unique_ptr<TCHAR[]> path(new TCHAR[len + 100]);
		len = GetTortoiseGitTempPath (len + 100, path.get());
		if (len != 0)
		{
			CDirFileEnum finder(path.get());
			FILETIME systime_;
			::GetSystemTimeAsFileTime(&systime_);
			__int64 systime = (((_int64)systime_.dwHighDateTime)<<32) | ((__int64)systime_.dwLowDateTime);
			bool isDir;
			CString filepath;
			while (finder.NextFile(filepath, &isDir))
			{
				HANDLE hFile = ::CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, isDir ? FILE_FLAG_BACKUP_SEMANTICS : NULL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					FILETIME createtime_;
					if (::GetFileTime(hFile, &createtime_, NULL, NULL))
					{
						::CloseHandle(hFile);
						__int64 createtime = (((_int64)createtime_.dwHighDateTime)<<32) | ((__int64)createtime_.dwLowDateTime);
						if ((createtime + 864000000000) < systime)		//only delete files older than a day
						{
							::SetFileAttributes(filepath, FILE_ATTRIBUTE_NORMAL);
							if (isDir)
								::RemoveDirectory(filepath);
							else
								::DeleteFile(filepath);
						}
					}
					else
						::CloseHandle(hFile);
				}
			}
		}
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	// application, rather than start the application's message pump.
	return FALSE;
}
Beispiel #14
0
BOOL CTortoiseProcApp::InitInstance()
{
	EnableCrashHandler();
	InitializeJumpList();
	CheckUpgrade();
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
	CMFCButton::EnableWindowsTheming();

	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);

	if(!CheckMsysGitDir())
	{
		UINT ret = CMessageBox::Show(NULL,_T("MSysGit (http://code.google.com/p/msysgit/) not found."),
									_T("TortoiseGit"), 3, IDI_HAND, _T("&Set MSysGit path"), _T("&Goto WebSite"), _T("&Abort"));
		if(ret == 2)
		{
			ShellExecute(NULL, NULL, _T("http://code.google.com/p/msysgit/"), NULL, NULL, SW_SHOW);
		}
		else if(ret == 1)
		{
			// open settings dialog
			CSettings dlg(IDS_PROC_SETTINGS_TITLE);
			dlg.SetTreeViewMode(TRUE, TRUE, TRUE);
			dlg.SetTreeWidth(220);

			dlg.DoModal();
			dlg.HandleRestart();
		}
		return FALSE;
	}

	//set the resource dll for the required language
	CRegDWORD loc = CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
	long langId = loc;
	CString langDll;
	CStringA langpath = CStringA(CPathUtils::GetAppParentDirectory());
	langpath += "Languages";
//	bindtextdomain("subversion", (LPCSTR)langpath);
//	bind_textdomain_codeset("subversion", "UTF-8");
	HINSTANCE hInst = NULL;
	do
	{
		langDll.Format(_T("..\\Languages\\TortoiseProc%d.dll"), langId);

		hInst = LoadLibrary(langDll);

		CString sVer = _T(STRPRODUCTVER);
		CString sFileVer = CPathUtils::GetVersionFromFile(langDll);
		if (sFileVer.Compare(sVer)!=0)
		{
			FreeLibrary(hInst);
			hInst = NULL;
		}
		if (hInst != NULL)
		{
			AfxSetResourceHandle(hInst);
		}
		else
		{
			DWORD lid = SUBLANGID(langId);
			lid--;
			if (lid > 0)
			{
				langId = MAKELANGID(PRIMARYLANGID(langId), lid);
			}
			else
				langId = 0;
		}
	} while ((hInst == NULL) && (langId != 0));
	TCHAR buf[6];
	_tcscpy_s(buf, _T("en"));
	langId = loc;
	CString sHelppath;
	sHelppath = this->m_pszHelpFilePath;
	sHelppath = sHelppath.MakeLower();
	// MFC uses a help file with the same name as the application by default,
	// which means we have to change that default to our language specific help files
	sHelppath.Replace(_T("tortoiseproc.chm"), _T("TortoiseGit_en.chm"));
	free((void*)m_pszHelpFilePath);
	m_pszHelpFilePath=_tcsdup(sHelppath);
	sHelppath = CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseGit_en.chm");
	do
	{
		CString sLang = _T("_");
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO639LANGNAME, buf, _countof(buf)))
		{
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));
		if (GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, buf, _countof(buf)))
		{
			sLang += _T("_");
			sLang += buf;
			sHelppath.Replace(_T("_en"), sLang);
			if (PathFileExists(sHelppath))
			{
				free((void*)m_pszHelpFilePath);
				m_pszHelpFilePath=_tcsdup(sHelppath);
				break;
			}
		}
		sHelppath.Replace(sLang, _T("_en"));

		DWORD lid = SUBLANGID(langId);
		lid--;
		if (lid > 0)
		{
			langId = MAKELANGID(PRIMARYLANGID(langId), lid);
		}
		else
			langId = 0;
	} while (langId);
	setlocale(LC_ALL, "");

	// InitCommonControls() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.

	INITCOMMONCONTROLSEX used = {
		sizeof(INITCOMMONCONTROLSEX),
			ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES | ICC_DATE_CLASSES |
			ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES | ICC_LISTVIEW_CLASSES |
			ICC_NATIVEFNTCTL_CLASS | ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
			ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS |
			ICC_USEREX_CLASSES | ICC_WIN95_CLASSES
	};
	InitCommonControlsEx(&used);
	AfxOleInit();
	AfxEnableControlContainer();
	AfxInitRichEdit2();
	CWinAppEx::InitInstance();
	SetRegistryKey(_T("TortoiseGit"));

	CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);

	// if HKCU\Software\TortoiseGit\Debug is not 0, show our command line
	// in a message box
	if (CRegDWORD(_T("Software\\TortoiseGit\\Debug"), FALSE)==TRUE)
		AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);

	if ( parser.HasKey(_T("path")) && parser.HasKey(_T("pathfile")))
	{
		CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
		return FALSE;
	}

	CTGitPath cmdLinePath;
	CTGitPathList pathList;
	if ( parser.HasKey(_T("pathfile")) )
	{

		CString sPathfileArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("pathfile")));

		cmdLinePath.SetFromUnknown(sPathfileArgument);
		if (pathList.LoadFromFile(cmdLinePath)==false)
			return FALSE;		// no path specified!
		if ( parser.HasKey(_T("deletepathfile")) )
		{
			// We can delete the temporary path file, now that we've loaded it
			::DeleteFile(cmdLinePath.GetWinPath());
		}
		// This was a path to a temporary file - it's got no meaning now, and
		// anybody who uses it again is in for a problem...
		cmdLinePath.Reset();

	}
	else
	{

		CString sPathArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("path")));
		int asterisk = sPathArgument.Find('*');
		cmdLinePath.SetFromUnknown(asterisk >= 0 ? sPathArgument.Left(asterisk) : sPathArgument);
		pathList.LoadFromAsteriskSeparatedString(sPathArgument);
	}

	if (pathList.GetCount() == 0) {
		pathList.AddPath(CTGitPath::CTGitPath(g_Git.m_CurrentDir));
	}

	hWndExplorer = NULL;
	CString sVal = parser.GetVal(_T("hwnd"));
	if (!sVal.IsEmpty())
		hWndExplorer = (HWND)_ttoi64(sVal);

	while (GetParent(hWndExplorer)!=NULL)
		hWndExplorer = GetParent(hWndExplorer);
	if (!IsWindow(hWndExplorer))
	{
		hWndExplorer = NULL;
	}

	// Subversion sometimes writes temp files to the current directory!
	// Since TSVN doesn't need a specific CWD anyway, we just set it
	// to the users temp folder: that way, Subversion is guaranteed to
	// have write access to the CWD
	{
		DWORD len = GetCurrentDirectory(0, NULL);
		if (len)
		{
			TCHAR * originalCurrentDirectory = new TCHAR[len];
			if (GetCurrentDirectory(len, originalCurrentDirectory))
			{
				//sOrigCWD = originalCurrentDirectory;
				//sOrigCWD = CPathUtils::GetLongPathname(sOrigCWD);
			}
			delete [] originalCurrentDirectory;
		}
		TCHAR pathbuf[MAX_PATH];
		GetTempPath(MAX_PATH, pathbuf);
		SetCurrentDirectory(pathbuf);
	}

	// check for newer versions
	if (CRegDWORD(_T("Software\\TortoiseGit\\CheckNewer"), TRUE) != FALSE)
	{
		time_t now;
		struct tm ptm;

		time(&now);
		if ((now != 0) && (localtime_s(&ptm, &now)==0))
		{
			int week = 0;
			// we don't calculate the real 'week of the year' here
			// because just to decide if we should check for an update
			// that's not needed.
			week = ptm.tm_yday / 7;

			CRegDWORD oldweek = CRegDWORD(_T("Software\\TortoiseGit\\CheckNewerWeek"), (DWORD)-1);
			if (((DWORD)oldweek) == -1)
				oldweek = week;		// first start of TortoiseProc, no update check needed
			else
			{
				if ((DWORD)week != oldweek)
				{
					oldweek = week;

					TCHAR com[MAX_PATH+100];
					GetModuleFileName(NULL, com, MAX_PATH);
					_tcscat_s(com, MAX_PATH+100, _T(" /command:updatecheck"));

					CAppUtils::LaunchApplication(com, 0, false);
				}
			}
		}
	}

	if (parser.HasVal(_T("configdir")))
	{
		// the user can override the location of the Subversion config directory here
		CString sConfigDir = parser.GetVal(_T("configdir"));
//		g_GitGlobal.SetConfigDir(sConfigDir);
	}
	// to avoid that SASL will look for and load its plugin dlls all around the
	// system, we set the path here.
	// Note that SASL doesn't have to be initialized yet for this to work
//	sasl_set_path(SASL_PATH_TYPE_PLUGIN, (LPSTR)(LPCSTR)CUnicodeUtils::GetUTF8(CPathUtils::GetAppDirectory().TrimRight('\\')));

	HANDLE TSVNMutex = ::CreateMutex(NULL, FALSE, _T("TortoiseGitProc.exe"));
	if(!g_Git.SetCurrentDir(cmdLinePath.GetWinPathString()))
	{
		int i=0;
		for(i=0;i<pathList.GetCount();i++)
			if(g_Git.SetCurrentDir(pathList[i].GetWinPath()))
				break;
	}

	if(!g_Git.m_CurrentDir.IsEmpty())
		SetCurrentDirectory(g_Git.m_CurrentDir);

	{
		CString err;
		try
		{
			// requires CWD to be set
			CGit::m_LogEncode = CAppUtils::GetLogOutputEncode();
		}
		catch (char* msg)
		{
			err = CString(msg);
		}

		if (!err.IsEmpty())
		{
			UINT choice = CMessageBox::Show(hWndExplorer, err, _T("TortoiseGit Error"), 1, IDI_ERROR, _T("&Edit .git/config"), _T("Edit &global .gitconfig"), _T("&Abort"));
			if (choice == 1)
			{
				// open the config file with alternative editor
				CString path = g_Git.m_CurrentDir;
				path += _T("\\.git\\config");
				CAppUtils::LaunchAlternativeEditor(path);
			}
			else if (choice == 2)
			{
				// open the global config file with alternative editor
				TCHAR buf[MAX_PATH];
				ExpandEnvironmentStrings(_T("%HOMEDRIVE%\\%HOMEPATH%\\.gitconfig"), buf, MAX_PATH);
				CAppUtils::LaunchAlternativeEditor(buf);
			}
			return FALSE;
		}
	}

	// execute the requested command
	CommandServer server;
	Command * cmd = server.GetCommand(parser.GetVal(_T("command")));
	if (cmd)
	{
		cmd->SetExplorerHwnd(hWndExplorer);

		cmd->SetParser(parser);
		cmd->SetPaths(pathList, cmdLinePath);

		retSuccess = cmd->Execute();
		delete cmd;
	}

	if (TSVNMutex)
		::CloseHandle(TSVNMutex);

	// Look for temporary files left around by TortoiseSVN and
	// remove them. But only delete 'old' files because some
	// apps might still be needing the recent ones.
	{
		DWORD len = ::GetTempPath(0, NULL);
		TCHAR * path = new TCHAR[len + 100];
		len = ::GetTempPath (len+100, path);
		if (len != 0)
		{
			CSimpleFileFind finder = CSimpleFileFind(path, _T("*svn*.*"));
			FILETIME systime_;
			::GetSystemTimeAsFileTime(&systime_);
			__int64 systime = (((_int64)systime_.dwHighDateTime)<<32) | ((__int64)systime_.dwLowDateTime);
			while (finder.FindNextFileNoDirectories())
			{
				CString filepath = finder.GetFilePath();
				HANDLE hFile = ::CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					FILETIME createtime_;
					if (::GetFileTime(hFile, &createtime_, NULL, NULL))
					{
						::CloseHandle(hFile);
						__int64 createtime = (((_int64)createtime_.dwHighDateTime)<<32) | ((__int64)createtime_.dwLowDateTime);
						if ((createtime + 864000000000) < systime)		//only delete files older than a day
						{
							::SetFileAttributes(filepath, FILE_ATTRIBUTE_NORMAL);
							::DeleteFile(filepath);
						}
					}
					else
						::CloseHandle(hFile);
				}
			}
		}
		delete[] path;
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	// application, rather than start the application's message pump.
	return FALSE;
}
Beispiel #15
0
bool CleanupCommand::Execute()
{
	bool bRet = false;

	CCleanTypeDlg dlg;
	if( dlg.DoModal() == IDOK)
	{
		bool quotepath = g_Git.GetConfigValueBool(_T("core.quotepath"));

		CString cmd;
		cmd.Format(_T("git clean"));
		if (dlg.m_bDryRun || !dlg.m_bNoRecycleBin)
			cmd += _T(" -n ");
		if(dlg.m_bDir)
			cmd += _T(" -d ");
		switch(dlg.m_CleanType)
		{
		case 0:
			cmd += _T(" -fx");
			break;
		case 1:
			cmd += _T(" -f");
			break;
		case 2:
			cmd += _T(" -fX");
			break;
		}

		if (dlg.m_bDryRun || dlg.m_bNoRecycleBin)
		{
			CProgressDlg progress;
			for (int i = 0; i < this->pathList.GetCount(); ++i)
			{
				CString path;
				if (this->pathList[i].IsDirectory())
					path = pathList[i].GetGitPathString();
				else
					path = pathList[i].GetContainingDirectory().GetGitPathString();

				progress.m_GitCmdList.push_back(cmd + _T(" \"") + path + _T("\""));
			}
			if (progress.DoModal()==IDOK)
				return TRUE;
		}
		else
		{
			CSysProgressDlg sysProgressDlg;
			sysProgressDlg.SetAnimation(IDR_CLEANUPANI);
			sysProgressDlg.SetTitle(CString(MAKEINTRESOURCE(IDS_APPNAME)));
			sysProgressDlg.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
			sysProgressDlg.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROGRESSWAIT)));
			sysProgressDlg.SetShowProgressBar(false);
			sysProgressDlg.ShowModeless((HWND)NULL, true);

			CString cmdout, cmdouterr;
			if (g_Git.Run(cmd, &cmdout, &cmdouterr, CP_UTF8)) {
				MessageBox(NULL, cmdouterr, _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;
			}

			if (sysProgressDlg.HasUserCancelled())
			{
				CMessageBox::Show(NULL, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
				return FALSE;
			}

			int pos = 0;
			CString token = cmdout.Tokenize(_T("\n"), pos);
			CTGitPathList delList;
			while (!token.IsEmpty())
			{
				if (token.Mid(0, 13) == _T("Would remove "))
				{
					CString tempPath = token.Mid(13).TrimRight();
					if (quotepath)
					{
						tempPath = UnescapeQuotePath(tempPath.Trim(_T('"')));
					}
					delList.AddPath(CTGitPath(tempPath));
				}

				token = cmdout.Tokenize(_T("\n"), pos);
			}

			if (sysProgressDlg.HasUserCancelled())
			{
				CMessageBox::Show(NULL, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_OK);
				return FALSE;
			}

			delList.DeleteAllFiles(true, false);

			sysProgressDlg.Stop();
		}
	}
#if 0
	CProgressDlg progress;
	progress.SetTitle(IDS_PROC_CLEANUP);
	progress.SetAnimation(IDR_CLEANUPANI);
	progress.SetShowProgressBar(false);
	progress.SetLine(1, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO1)));
	progress.SetLine(2, CString(MAKEINTRESOURCE(IDS_PROC_CLEANUP_INFO2)));
	progress.ShowModeless(hwndExplorer);

	CString strSuccessfullPaths, strFailedPaths;
	for (int i=0; i<pathList.GetCount(); ++i)
	{
		SVN svn;
		if (!svn.CleanUp(pathList[i]))
		{
			strFailedPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");
			strFailedPaths += svn.GetLastErrorMessage() + _T("\n\n");
		}
		else
		{
			strSuccessfullPaths += _T("- ") + pathList[i].GetWinPathString() + _T("\n");

			// after the cleanup has finished, crawl the path downwards and send a change
			// notification for every directory to the shell. This will update the
			// overlays in the left tree view of the explorer.
			CDirFileEnum crawler(pathList[i].GetWinPathString());
			CString sPath;
			bool bDir = false;
			CTSVNPathList updateList;
			while (crawler.NextFile(sPath, &bDir))
			{
				if ((bDir) && (!g_SVNAdminDir.IsAdminDirPath(sPath)))
				{
					updateList.AddPath(CTSVNPath(sPath));
				}
			}
			updateList.AddPath(pathList[i]);
			CShellUpdater::Instance().AddPathsForUpdate(updateList);
			CShellUpdater::Instance().Flush();
			updateList.SortByPathname(true);
			for (INT_PTR i=0; i<updateList.GetCount(); ++i)
			{
				SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, updateList[i].GetWinPath(), NULL);
				ATLTRACE(_T("notify change for path %s\n"), updateList[i].GetWinPath());
			}
		}
	}
	progress.Stop();

	CString strMessage;
	if ( !strSuccessfullPaths.IsEmpty() )
	{
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED, (LPCTSTR)strSuccessfullPaths);
		strMessage += tmp;
		bRet = true;
	}
	if ( !strFailedPaths.IsEmpty() )
	{
		if (!strMessage.IsEmpty())
			strMessage += _T("\n");
		CString tmp;
		tmp.Format(IDS_PROC_CLEANUPFINISHED_FAILED, (LPCTSTR)strFailedPaths);
		strMessage += tmp;
		bRet = false;
	}
	CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), MB_OK | (strFailedPaths.IsEmpty()?MB_ICONINFORMATION:MB_ICONERROR));
#endif
	CShellUpdater::Instance().Flush();
	return bRet;
}
Beispiel #16
0
void CSyncDlg::OnBnClickedButtonPush()
{
	this->UpdateData();
	UpdateCombox();
	m_ctrlCmdOut.SetWindowTextW(_T(""));
	m_LogText = "";

	if(this->m_strURL.IsEmpty())
	{
		CMessageBox::Show(NULL, IDS_PROC_GITCONFIG_URLEMPTY, IDS_APPNAME, MB_OK | MB_ICONERROR);
		return;
	}

	this->m_regPushButton=(DWORD)this->m_ctrlPush.GetCurrentEntry();
	this->SwitchToRun();
	this->m_bAbort=false;
	this->m_GitCmdList.clear();

	ShowTab(IDC_CMD_LOG);

	CString cmd;
	CString arg;

	CString error;
	DWORD exitcode;
	CTGitPathList list;
	list.AddPath(CTGitPath(g_Git.m_CurrentDir));

	if (CHooks::Instance().PrePush(list,exitcode, error))
	{
		if (exitcode)
		{
			CString temp;
			temp.Format(IDS_ERR_HOOKFAILED, (LPCTSTR)error);
			//ReportError(temp);
			CMessageBox::Show(NULL,temp,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
			return ;
		}
	}

	CString refName = g_Git.FixBranchName(m_strLocalBranch);
	switch (m_ctrlPush.GetCurrentEntry())
	{
	case 1:
		arg += _T(" --tags ");
		break;
	case 2:
		refName = _T("refs/notes/commits");	//default ref for notes
		break;
	}

	if(this->m_bForce)
		arg += _T(" --force ");

	if(m_Gitverion >= 0x01070203) //above 1.7.0.2
		arg += _T("--progress ");

	cmd.Format(_T("git.exe push -v %s \"%s\" %s"),
				arg,
				m_strURL,
				refName);

	if (!m_strRemoteBranch.IsEmpty() && m_ctrlPush.GetCurrentEntry() != 2)
	{
		cmd += _T(":") + m_strRemoteBranch;
	}

	m_GitCmdList.push_back(cmd);

	m_CurrentCmd = GIT_COMMAND_PUSH;

	if(this->m_bAutoLoadPuttyKey)
	{
		CAppUtils::LaunchPAgent(NULL,&this->m_strURL);
	}

	m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
	if (m_pThread==NULL)
	{
//		ReportError(CString(MAKEINTRESOURCE(IDS_ERR_THREADSTARTFAILED)));
	}
	else
	{
		m_pThread->m_bAutoDelete = TRUE;
		m_pThread->ResumeThread();
	}
}
Beispiel #17
0
bool CloneCommand::Execute()
{
	CTGitPath cloneDirectory;
	if (!parser.HasKey(_T("hasurlhandler")))
	{
		if (orgCmdLinePath.IsEmpty())
		{
			cloneDirectory.SetFromWin(sOrigCWD, true);
			DWORD len = ::GetTempPath(0, nullptr);
			auto tszPath = std::make_unique<TCHAR[]>(len);
			::GetTempPath(len, tszPath.get());
			if (_tcsncicmp(cloneDirectory.GetWinPath(), tszPath.get(), len-2 /* \\ and \0 */) == 0)
			{
				// if the current directory is set to a temp directory,
				// we don't use that but leave it empty instead.
				cloneDirectory.Reset();
			}
		}
		else
			cloneDirectory = orgCmdLinePath;
	}

	CCloneDlg dlg;
	dlg.m_Directory = cloneDirectory.GetWinPathString();

	if (parser.HasKey(_T("url")))
		dlg.m_URL = parser.GetVal(_T("url"));
	if (parser.HasKey(_T("exactpath")))
		dlg.m_bExactPath = TRUE;

	if(dlg.DoModal()==IDOK)
	{
		CString recursiveStr;
		if(dlg.m_bRecursive)
			recursiveStr = _T(" --recursive");

		CString bareStr;
		if(dlg.m_bBare)
			bareStr = _T(" --bare");

		CString nocheckoutStr;
		if (dlg.m_bNoCheckout)
			nocheckoutStr = _T(" --no-checkout");

		CString branchStr;
		if (dlg.m_bBranch)
			branchStr = _T(" --branch ") + dlg.m_strBranch;

		CString originStr;
		if (dlg.m_bOrigin && !dlg.m_bSVN)
			originStr = _T(" --origin ") + dlg.m_strOrigin;

		if(dlg.m_bAutoloadPuttyKeyFile)
		{
			CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);
		}

		CAppUtils::RemoveTrailSlash(dlg.m_Directory);
		if (!dlg.m_bSVN)
			CAppUtils::RemoveTrailSlash(dlg.m_URL);

		CString dir=dlg.m_Directory;
		CString url=dlg.m_URL;

		// is this a windows format UNC path, ie starts with \\?
		if (url.Find(_T("\\\\")) == 0)
		{
			// yes, change all \ to /
			// this should not be necessary but msysgit does not support the use \ here yet
			int atSign = url.Find(_T('@'));
			if (atSign > 0)
			{
				CString path = url.Mid(atSign);
				path.Replace(_T('\\'), _T('/'));
				url = url.Mid(0, atSign) + path;
			}
			else
				url.Replace( _T('\\'), _T('/'));
		}

		CString depth;
		if (dlg.m_bDepth)
		{
			depth.Format(_T(" --depth %d"),dlg.m_nDepth);
		}

		CString cmd;
		cmd.Format(_T("git.exe clone --progress%s%s%s%s%s -v%s \"%s\" \"%s\""),
						(LPCTSTR)nocheckoutStr,
						(LPCTSTR)recursiveStr,
						(LPCTSTR)bareStr,
						(LPCTSTR)branchStr,
						(LPCTSTR)originStr,
						(LPCTSTR)depth,
						(LPCTSTR)url,
						(LPCTSTR)dir);

		bool retry = false;
		auto postCmdCallback = [&](DWORD status, PostCmdList& postCmdList)
		{
			if (status)
			{
				postCmdList.emplace_back(IDI_REFRESH, IDS_MSGBOX_RETRY, [&]{ retry = true; });
				return;
			}

			// After cloning, change current directory to the cloned directory
			g_Git.m_CurrentDir = dlg.m_Directory;
			if (dlg.m_bAutoloadPuttyKeyFile) // do this here, since it might be needed for actions performed in Log
				StorePuttyKey(dlg.m_Directory, dlg.m_bOrigin && !dlg.m_strOrigin.IsEmpty() ? dlg.m_strOrigin : _T("origin"), dlg.m_strPuttyKeyFile);

			postCmdList.emplace_back(IDI_LOG, IDS_MENULOG, [&]
			{
				CString cmd = _T("/command:log");
				cmd += _T(" /path:\"") + dlg.m_Directory + _T("\"");
				CAppUtils::RunTortoiseGitProc(cmd);
			});

			postCmdList.emplace_back(IDI_EXPLORER, IDS_STATUSLIST_CONTEXT_EXPLORE, [&]{ CAppUtils::ExploreTo(hWndExplorer, dlg.m_Directory); });
		};

		// Handle Git SVN-clone
		if(dlg.m_bSVN)
		{
			//g_Git.m_CurrentDir=dlg.m_Directory;
			cmd.Format(_T("git.exe svn clone \"%s\" \"%s\""),
				(LPCTSTR)url, (LPCTSTR)dlg.m_Directory);

			if (dlg.m_bOrigin)
			{
				CString str;
				if (dlg.m_strOrigin.IsEmpty())
					str = _T(" --prefix \"\"");
				else
					str.Format(_T(" --prefix \"%s/\""), (LPCTSTR)dlg.m_strOrigin);
				cmd += str;
			}

			if(dlg.m_bSVNTrunk)
				cmd+=_T(" -T ")+dlg.m_strSVNTrunk;

			if(dlg.m_bSVNBranch)
				cmd+=_T(" -b ")+dlg.m_strSVNBranchs;

			if(dlg.m_bSVNTags)
				cmd+=_T(" -t ")+dlg.m_strSVNTags;

			if(dlg.m_bSVNFrom)
			{
				CString str;
				str.Format(_T("%d:HEAD"),dlg.m_nSVNFrom);
				cmd+=_T(" -r ")+str;
			}

			if(dlg.m_bSVNUserName)
			{
				cmd+= _T(" --username ");
				cmd+=dlg.m_strUserName;
			}
		}
		else
		{
			if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE))
			{
				while (true)
				{
					retry = false;
					CGitProgressDlg GitDlg;
					CTGitPathList list;
					g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);
					list.AddPath(CTGitPath(dir));
					CloneProgressCommand cloneProgressCommand;
					GitDlg.SetCommand(&cloneProgressCommand);
					cloneProgressCommand.m_PostCmdCallback = postCmdCallback;
					cloneProgressCommand.SetUrl(url);
					cloneProgressCommand.SetPathList(list);
					cloneProgressCommand.SetIsBare(dlg.m_bBare == TRUE);
					if (dlg.m_bBranch)
						cloneProgressCommand.SetRefSpec(dlg.m_strBranch);
					if (dlg.m_bOrigin)
						cloneProgressCommand.SetRemote(dlg.m_strOrigin);
					cloneProgressCommand.SetNoCheckout(dlg.m_bNoCheckout == TRUE);
					GitDlg.DoModal();
					if (!retry)
						return !GitDlg.DidErrorsOccur();
				}
			}
		}

		while (true)
		{
			retry = false;
			g_Git.m_CurrentDir = GetExistingDirectoryForClone(dlg.m_Directory);
			CProgressDlg progress;
			progress.m_GitCmd=cmd;
			progress.m_PostCmdCallback = postCmdCallback;
			INT_PTR ret = progress.DoModal();

			if (!retry)
				return ret == IDOK;
		}
	}
	return FALSE;
}
void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMenu *popmenu)
{
	POSITION pos = GetFirstSelectedItemPosition();
	int indexNext = GetNextSelectedItem(pos);
	if (indexNext < 0)
		return;

	GitRevLoglist* pSelLogEntry = reinterpret_cast<GitRevLoglist*>(m_arShownList.GetAt(indexNext));

	theApp.DoWaitCursor(1);
	switch (cmd&0xFFFF)
		{
			case ID_COMMIT:
			{
				CTGitPathList pathlist;
				CTGitPathList selectedlist;
				pathlist.AddPath(this->m_Path);
				bool bSelectFilesForCommit = !!DWORD(CRegStdDWORD(_T("Software\\TortoiseGit\\SelectFilesForCommit"), TRUE));
				CString str;
				CAppUtils::Commit(CString(),false,str,
								  pathlist,selectedlist,bSelectFilesForCommit);
				//this->Refresh();
				this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH,0);
			}
			break;
			case ID_MERGE_ABORT:
			{
				if (CAppUtils::MergeAbort())
					this->GetParent()->PostMessage(WM_COMMAND,ID_LOGDLG_REFRESH, 0);
			}
			break;
			case ID_GNUDIFF1: // compare with WC, unified
			{
				GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(FirstSelect));
				bool bMerge = false, bCombine = false;
				CString hash2;
				if(!r1->m_CommitHash.IsEmpty())
				{
					CString merge;
					cmd >>= 16;
					if( (cmd&0xFFFF) == 0xFFFF)
						bMerge = true;
					else if((cmd&0xFFFF) == 0xFFFE)
						bCombine = true;
					else if ((cmd & 0xFFFF) == 0xFFFD)
					{
						CString tempfile = GetTempFile();
						CString gitcmd = _T("git.exe diff-tree --cc ") + r1->m_CommitHash.ToString();
						CString lastErr;
						if (g_Git.RunLogFile(gitcmd, tempfile, &lastErr))
						{
							MessageBox(lastErr, _T("TortoiseGit"), MB_ICONERROR);
							break;
						}

						try
						{
							CStdioFile file(tempfile, CFile::typeText | CFile::modeRead | CFile::shareDenyWrite);
							CString strLine;
							bool isHash = file.ReadString(strLine) && r1->m_CommitHash.ToString() == strLine;
							bool more = isHash && file.ReadString(strLine) && !strLine.IsEmpty();
							if (!more)
							{
								CMessageBox::Show(nullptr, IDS_NOCHANGEAFTERMERGE, IDS_APPNAME, MB_OK);
								break;
							}
						}
						catch (CFileException* e)
						{
							e->Delete();
						}

						CAppUtils::StartUnifiedDiffViewer(tempfile, _T("dd"));
						break;
					}
					else
					{
						if ((size_t)cmd > r1->m_ParentHash.size())
						{
							CString str;
							str.Format(IDS_PROC_NOPARENT, cmd);
							MessageBox(str, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
							return;
						}
						else
						{
							if(cmd>0)
								hash2 = r1->m_ParentHash[cmd-1].ToString();
						}
					}
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), hash2, CTGitPath(), r1->m_CommitHash.ToString(), false, false, false, bMerge, bCombine);
				}
				else
					CAppUtils::StartShowUnifiedDiff(nullptr, CTGitPath(), _T("HEAD"), CTGitPath(), GitRev::GetWorkingCopy(), false, false, false, bMerge, bCombine);
			}
bool DropCopyAddCommand::Execute()
{
	bool bRet = false;
	CString droppath = parser.GetVal(_T("droptarget"));
	if (CTGitPath(droppath).IsAdminDir())
		return FALSE;

	if(!CTGitPath(droppath).HasAdminDir(&g_Git.m_CurrentDir))
		return FALSE;

	int worktreePathLen = g_Git.m_CurrentDir.GetLength();
	orgPathList.RemoveAdminPaths();
	CTGitPathList copiedFiles;
	for(int nPath = 0; nPath < orgPathList.GetCount(); ++nPath)
	{
		if (orgPathList[nPath].IsEquivalentTo(CTGitPath(droppath)))
			continue;

		//copy the file to the new location
		CString name = orgPathList[nPath].GetFileOrDirectoryName();
		if (::PathFileExists(droppath + _T("\\") + name))
		{
			if (::PathIsDirectory(droppath + _T("\\") + name))
			{
				if (orgPathList[nPath].IsDirectory())
					continue;
			}

			CString strMessage;
			strMessage.Format(IDS_PROC_OVERWRITE_CONFIRM, (LPCTSTR)(droppath + _T("\\") + name));
			CString sBtn1(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_OVERWRITE));
			CString sBtn2(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_KEEP));
			CString sBtn3(MAKEINTRESOURCE(IDS_PROC_OVERWRITEEXPORT_CANCEL));
			UINT ret = CMessageBox::Show(hwndExplorer, strMessage, _T("TortoiseGit"), 2, IDI_QUESTION, sBtn1, sBtn2, sBtn3);

			if (ret == 3)
				return FALSE; //cancel the whole operation
			if (ret == 1)
			{
				if (!::CopyFile(orgPathList[nPath].GetWinPath(), droppath + _T("\\") + name, FALSE))
				{
					//the copy operation failed! Get out of here!
					ShowErrorMessage();
					return FALSE;
				}
			}
		}
		else
		{
			if (orgPathList[nPath].IsDirectory())
			{
				CString fromPath = orgPathList[nPath].GetWinPathString() + L"||";
				CString toPath = droppath + L"\\" + name + L"||";
				std::unique_ptr<TCHAR[]> fromBuf(new TCHAR[fromPath.GetLength() + 2]);
				std::unique_ptr<TCHAR[]> toBuf(new TCHAR[toPath.GetLength() + 2]);
				wcscpy_s(fromBuf.get(), fromPath.GetLength() + 2, fromPath);
				wcscpy_s(toBuf.get(), toPath.GetLength() + 2, toPath);
				CStringUtils::PipesToNulls(fromBuf.get(), fromPath.GetLength() + 2);
				CStringUtils::PipesToNulls(toBuf.get(), toPath.GetLength() + 2);

				SHFILEOPSTRUCT fileop = {0};
				fileop.wFunc = FO_COPY;
				fileop.pFrom = fromBuf.get();
				fileop.pTo = toBuf.get();
				fileop.fFlags = FOF_NO_CONNECTED_ELEMENTS | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS | FOF_SILENT;
				if (!SHFileOperation(&fileop))
				{
					// add all copied files WITH special handling for repos/submodules (folders which include a .git entry)
					CDirFileEnum finder(droppath + L"\\" + name);
					bool isDir = true;
					CString filepath;
					CString lastRepo;
					bool isRepo = false;
					while (finder.NextFile(filepath, &isDir, !isRepo)) // don't recurse into .git directories
					{
						if (!lastRepo.IsEmpty())
						{
							if (filepath.Find(lastRepo) == 0)
								continue;
							else
								lastRepo.Empty();
						}
						int pos = -1;
						if ((pos = filepath.Find(L"\\" + g_GitAdminDir.GetAdminDirName())) >= 0)
							isRepo = (pos == filepath.GetLength() - g_GitAdminDir.GetAdminDirName().GetLength() - 1);
						else
							isRepo = false;
						if (isRepo)
						{
							lastRepo = filepath.Mid(0, filepath.GetLength() - g_GitAdminDir.GetAdminDirName().GetLength());
							CString msg;
							if (!isDir)
								msg.Format(IDS_PROC_COPY_SUBMODULE, lastRepo);
							else
								msg.Format(IDS_PROC_COPY_REPOSITORY, lastRepo);
							int ret = CMessageBox::Show(hwndExplorer, msg, _T("TortoiseGit"), 1, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_DELETEBUTTON)), CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON)));
							if (ret == 3)
								return FALSE;
							if (ret == 1)
							{
								CTGitPath(filepath).Delete(false);
								lastRepo.Empty();
							}
							continue;
						}
						if (!isDir)
							copiedFiles.AddPath(CTGitPath(filepath.Mid(worktreePathLen + 1))); //add the new filepath
					}
				}
				continue; // do not add a directory to copiedFiles
			}
			else if (!CopyFile(orgPathList[nPath].GetWinPath(), droppath+_T("\\")+name, FALSE))
			{
				//the copy operation failed! Get out of here!
				ShowErrorMessage();
				return FALSE;
			}
		}
		CString destPath(droppath + _T("\\") + name);
		copiedFiles.AddPath(CTGitPath(destPath.Mid(worktreePathLen + 1))); //add the new filepath
	}
	//now add all the newly copied files to the working copy
	CGitProgressDlg progDlg;
	theApp.m_pMainWnd = &progDlg;
	AddProgressCommand addCommand;
	progDlg.SetCommand(&addCommand);
	addCommand.SetPathList(copiedFiles);
	progDlg.DoModal();
	bRet = !progDlg.DidErrorsOccur();

	return bRet;
}
BOOL CTortoiseSIProcApp::ProcessCommandLine()
{
	CCmdLineParser parser(AfxGetApp()->m_lpCmdLine);

	CString sVal = parser.GetVal(_T("hwnd"));

	if (!sVal.IsEmpty()) {
		m_hWndExplorer = (HWND)_wcstoui64(sVal, nullptr, 16);
	}

	while (GetParent(m_hWndExplorer) != NULL) {
		m_hWndExplorer = GetParent(m_hWndExplorer);
	}

	if (!IsWindow(m_hWndExplorer))
	{
		m_hWndExplorer = NULL;
	}

#if _DEBUG
	if (CRegDWORD(_T("Software\\TortoiseSI\\Debug"), FALSE) == TRUE) {
		AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);
	}
#endif

	// The path and pathfile arguments are mutually exclusive
	if (parser.HasKey(_T("path")) && parser.HasKey(_T("pathfile")))
	{
		CMessageBox::Show(NULL, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
		return FALSE;
	}

	CTGitPath cmdLinePath;
	CTGitPathList pathList;

	if (parser.HasKey(_T("pathfile")))
	{
		// Process /pathfile argument

		CString sPathFileArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("pathfile")));

		cmdLinePath.SetFromUnknown(sPathFileArgument);

		if (pathList.LoadFromFile(cmdLinePath) == false) {
			// no path specified!
			return FALSE;		
	    }

		if (parser.HasKey(_T("deletepathfile")))
		{
			// We can delete the temporary path file, now that we've loaded it
			::DeleteFile(cmdLinePath.GetWinPath());
		}

		// This was a path to a temporary file - it's got no meaning now, and
		// anybody who uses it again is in for a problem...
		cmdLinePath.Reset();

	} else {

		// Process /path and /expaths argument
		// Build-uo /path value as /path:<value>*<arg1>*<arg2>...
		// Where <arg1>, <arg2> etc are extracted from /expath arguments.
		// Since all arguments are passed in the form of /parameter:<argument>
		// We process only those arguments which are not preceded by a /parameter:
		// This only includes arguments specified following /expaths (See comments below)

		CString sPathArgument = CPathUtils::GetLongPathname(parser.GetVal(_T("path")));

		if (parser.HasKey(_T("expaths")))
		{
			// An /expaths param means we are started via the buttons in our Win7 library
			// and that means the value of /expaths is the current directory and
			// the selected paths are then added as additional parameters but without a key, only a value
			//
			//     e.g. /expaths:"D:\" "D:\Utils"
			//
			// Because of the "strange treatment of quotation marks and backslashes by CommandLineToArgvW",
			// we have to escape the backslashes first.  Since we're only dealing with paths here, that's
			// a safe bet.  Without this, a command line like:
			//
			//     /command:commit /expaths:"D:\" "D:\Utils"
			// 
			// would fail because the "D:\" is treated as the backslash being the escape char for the quotation
			// mark and we'd end up with:
			//
			//     argv[1] = /command:commit
			//     argv[2] = /expaths:D:" D:\Utils
			//
			// See here for more details: http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx

			CString cmdLine = GetCommandLineW();

			// Escape backslashes
			cmdLine.Replace(L"\\", L"\\\\");

			int nArgs = 0;
			LPWSTR *szArgList = CommandLineToArgvW(cmdLine, &nArgs);

			if (szArgList)
			{
				// Argument 0 is the process path, so start with 1
				for (int i = 1; i < nArgs; i++)
				{
					if (szArgList[i][0] != '/')
					{
						if (!sPathArgument.IsEmpty()) {
							sPathArgument += '*';
						}
						sPathArgument += szArgList[i];
					}
				}

				sPathArgument.Replace(L"\\\\", L"\\");
			}

			LocalFree(szArgList);
		}

		if (sPathArgument.IsEmpty() && parser.HasKey(L"path"))
		{
			CMessageBox::Show(m_hWndExplorer, IDS_ERR_INVALIDPATH, IDS_APPNAME, MB_ICONERROR);
			return FALSE;
		}

		int asterisk = sPathArgument.Find('*');
		cmdLinePath.SetFromUnknown(asterisk >= 0 ? sPathArgument.Left(asterisk) : sPathArgument);
		pathList.LoadFromAsteriskSeparatedString(sPathArgument);
	}

	if (pathList.IsEmpty()) {
		pathList.AddPath(CTGitPath::CTGitPath(g_Git.m_CurrentDir));
	}

	// Set CWD to temporary dir, and restore it later
	{
		DWORD len = GetCurrentDirectory(0, NULL);

		if (len)
		{
			std::unique_ptr<TCHAR[]> originalCurrentDirectory(new TCHAR[len]);

			if (GetCurrentDirectory(len, originalCurrentDirectory.get()))
			{
				m_sOrigCWD = originalCurrentDirectory.get();
				m_sOrigCWD = CPathUtils::GetLongPathname(m_sOrigCWD);
			}
		}

		TCHAR pathbuf[MAX_PATH] = { 0 };
		GetTortoiseGitTempPath(MAX_PATH, pathbuf);
		SetCurrentDirectory(pathbuf);
	}

	if (!g_Git.m_CurrentDir.IsEmpty())
	{
		m_sOrigCWD = g_Git.m_CurrentDir;
		SetCurrentDirectory(m_sOrigCWD);
	}

	// Execute the requested command
	CommandServer server;

	Command *cmd = server.GetCommand(parser.GetVal(_T("command")));

	if (cmd)
	{
		cmd->SetExplorerHwnd(m_hWndExplorer);
		cmd->SetParser(parser);
		cmd->SetPaths(pathList, cmdLinePath);
		m_bRetSuccess = cmd->Execute();
		delete cmd;
	}

	return TRUE;
}