Пример #1
0
int CGitLogList::CherryPickFrom(CString from, CString to)
{
	CLogDataVector logs(&m_LogCache);
	if(logs.ParserFromLog(NULL,-1,0,&from,&to))
		return -1;

	if(logs.size() == 0)
		return 0;

	CSysProgressDlg progress;
	if (progress.IsValid())
	{
		progress.SetTitle(_T("Cherry Pick"));
		progress.SetAnimation(IDR_MOVEANI);
		progress.SetTime(true);
		progress.ShowModeless(this);
	}

	CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir);

	for(int i=logs.size()-1;i>=0;i--)
	{
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, _T("Pick up %s"), logs.GetGitRevAt(i).m_CommitHash.ToString());
			progress.FormatPathLine(2, _T("%s"), logs.GetGitRevAt(i).GetSubject());
			progress.SetProgress(logs.size()-i, logs.size());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			//CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			throw std::exception(CUnicodeUtils::GetUTF8(CString(_T("User canceled\r\n\r\n"))));
			return -1;
		}
		CString cmd,out;
		cmd.Format(_T("git.exe cherry-pick %s"),logs.GetGitRevAt(i).m_CommitHash.ToString());
		out.Empty();
		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			throw std::exception(CUnicodeUtils::GetUTF8(CString(_T("Cherry Pick Failure\r\n\r\n"))+out));
			return -1;
		}
	}

	return 0;
}
Пример #2
0
int CGitLogList::CherryPickFrom(CString from, CString to)
{
	CLogDataVector logs(&m_LogCache);
	CString range;
	range.Format(_T("%s..%s"), (LPCTSTR)from, (LPCTSTR)to);
	if (logs.ParserFromLog(nullptr, 0, 0, &range))
		return -1;

	if (logs.empty())
		return 0;

	CSysProgressDlg progress;
	progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROGS_TITLE_CHERRYPICK)));
	progress.SetAnimation(IDR_MOVEANI);
	progress.SetTime(true);
	progress.ShowModeless(this);

	CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir);

	for (int i = (int)logs.size() - 1; i >= 0; i--)
	{
		if (progress.IsVisible())
		{
			progress.FormatNonPathLine(1, IDS_PROC_PICK, logs.GetGitRevAt(i).m_CommitHash.ToString());
			progress.FormatNonPathLine(2, _T("%s"), (LPCTSTR)logs.GetGitRevAt(i).GetSubject());
			progress.SetProgress64(logs.size() - i, logs.size());
		}
		if (progress.HasUserCancelled())
		{
			throw std::exception(CUnicodeUtils::GetUTF8(CString(MAKEINTRESOURCE(IDS_USERCANCELLED))));
		}
		CString cmd,out;
		cmd.Format(_T("git.exe cherry-pick %s"), (LPCTSTR)logs.GetGitRevAt(i).m_CommitHash.ToString());
		out.Empty();
		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			throw std::exception(CUnicodeUtils::GetUTF8(CString(MAKEINTRESOURCE(IDS_PROC_CHERRYPICKFAILED)) + _T(":\r\n\r\n") + out));
		}
	}

	return 0;
}
Пример #3
0
bool DropCopyCommand::Execute()
{

    CString sDroppath = parser.GetVal(_T("droptarget"));
    if (CTGitPath(sDroppath).IsAdminDir())
    {
        CMessageBox::Show(NULL,_T("Can't drop to .git repository directory\n"),
                          _T("TortoiseGit"),MB_OK|MB_ICONERROR);
        return FALSE;
    }
    unsigned long count = 0;

    CString sNewName;
    pathList.RemoveAdminPaths();
    if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1))
    {
        // ask for a new name of the source item
        do
        {
            CRenameDlg renDlg;
            renDlg.m_windowtitle.LoadString(IDS_PROC_COPYRENAME);
            renDlg.m_name = pathList[0].GetFileOrDirectoryName();
            if (renDlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            sNewName = renDlg.m_name;
        } while(sNewName.IsEmpty() || PathFileExists(sDroppath+_T("\\")+sNewName));
    }
    CSysProgressDlg progress;
    progress.SetTitle(IDS_PROC_COPYING);
    progress.SetAnimation(IDR_MOVEANI);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
    for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
    {
        const CTGitPath& sourcePath = orgPathList[nPath];

        CTGitPath fullDropPath(sDroppath);

        if (sNewName.IsEmpty())
            fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
        else
            fullDropPath.AppendPathString(sNewName);

        // Check for a drop-on-to-ourselves
        if (sourcePath.IsEquivalentTo(fullDropPath))
        {
            // Offer a rename
            progress.Stop();
            CRenameDlg dlg;
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            // rebuild the progress dialog
            progress.EnsureValid();
            progress.SetTitle(IDS_PROC_COPYING);
            progress.SetAnimation(IDR_MOVEANI);
            progress.SetTime(true);
            progress.SetProgress(count, pathList.GetCount());
            progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
            // Rebuild the destination path, with the new name
            fullDropPath.SetFromUnknown(sDroppath);
            fullDropPath.AppendPathString(dlg.m_name);
        }

        if( CopyFile( sourcePath.GetWinPath(), fullDropPath.GetWinPath(), true))
        {
            CString ProjectTopDir;
            if(fullDropPath.HasAdminDir(&ProjectTopDir))
            {
                g_Git.SetCurrentDir(ProjectTopDir);
                SetCurrentDirectory(ProjectTopDir);
                CString cmd;
                cmd = _T("git.exe add \"");

                CString path;
                path=fullDropPath.GetGitPathString().Mid(ProjectTopDir.GetLength());
                if(path.GetLength()>0)
                    if(path[0]==_T('\\') || path[0]==_T('/'))
                        path=path.Mid(1);
                cmd += path;
                cmd +=_T('\"');

                CString output;
                if (g_Git.Run(cmd, &output, CP_UTF8))
                {
                    CMessageBox::Show(NULL, output, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
                } else
                    CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
            }

        } else
        {
            CString str;
            str+=_T("Copy file fail:");
            str+=sourcePath.GetWinPath();

            CMessageBox::Show(NULL, str, _T("TortoiseGit"), MB_OK|MB_ICONERROR);
        }

        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
            progress.SetProgress(count, pathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
            return false;
        }
    }

    return true;
}
Пример #4
0
bool PasteCopyCommand::Execute()
{
    CString sDroppath = parser.GetVal(_T("droptarget"));
    CTGitPath dropPath(sDroppath);
    ProjectProperties props;
    props.ReadProps(dropPath);
    if (dropPath.IsAdminDir())
        return FALSE;

    if(!dropPath.HasAdminDir(&g_Git.m_CurrentDir))
        return FALSE;
    //SVN svn;
    //SVNStatus status;
    unsigned long count = 0;
    CString sNewName;
    orgPathList.RemoveAdminPaths();
    CSysProgressDlg progress;
    progress.SetTitle(IDS_PROC_COPYING);
    progress.SetAnimation(IDR_MOVEANI);
    progress.SetTime(true);
    progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
    for(int nPath = 0; nPath < orgPathList.GetCount(); nPath++)
    {
        const CTGitPath& sourcePath = orgPathList[nPath];

        CTGitPath fullDropPath = dropPath;
        if (sNewName.IsEmpty())
            fullDropPath.AppendPathString(sourcePath.GetFileOrDirectoryName());
        else
            fullDropPath.AppendPathString(sNewName);

        // Check for a drop-on-to-ourselves
        if (sourcePath.IsEquivalentTo(fullDropPath))
        {
            // Offer a rename
            progress.Stop();
            CRenameDlg dlg;
            dlg.m_windowtitle.Format(IDS_PROC_NEWNAMECOPY, (LPCTSTR)sourcePath.GetUIFileOrDirectoryName());
            if (dlg.DoModal() != IDOK)
            {
                return FALSE;
            }
            // rebuild the progress dialog
            progress.EnsureValid();
            progress.SetTitle(IDS_PROC_COPYING);
            progress.SetAnimation(IDR_MOVEANI);
            progress.SetTime(true);
            progress.SetProgress(count, orgPathList.GetCount());
            progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
            // Rebuild the destination path, with the new name
            fullDropPath.SetFromUnknown(sDroppath);
            fullDropPath.AppendPathString(dlg.m_name);
        }

        //svn_wc_status_kind s = status.GetAllStatus(sourcePath);
        //if ((s == svn_wc_status_none)||(s == svn_wc_status_unversioned)||(s == svn_wc_status_ignored))
        {
            // source file is unversioned: move the file to the target, then add it
            CopyFile(sourcePath.GetWinPath(), fullDropPath.GetWinPath(), FALSE);
            CString cmd,output;
            cmd.Format(_T("git.exe add \"%s\""),fullDropPath.GetWinPath());
            if( g_Git.Run(cmd,&output,CP_ACP))
            {
                TRACE(_T("%s\n"), (LPCTSTR)output);
                CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
                return FALSE;		//get out of here
            }
            else
                CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
        }
        //else
        //{
        //	if (!svn.Copy(CTSVNPathList(sourcePath), fullDropPath, SVNRev::REV_WC, SVNRev()))
        //	{
        //		TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
        //		CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);
        //		return FALSE;		//get out of here
        //	}
        //	else
        //		CShellUpdater::Instance().AddPathForUpdate(fullDropPath);
        //}
        count++;
        if (progress.IsValid())
        {
            progress.FormatPathLine(1, IDS_PROC_COPYINGPROG, sourcePath.GetWinPath());
            progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, fullDropPath.GetWinPath());
            progress.SetProgress(count, orgPathList.GetCount());
        }
        if ((progress.IsValid())&&(progress.HasUserCancelled()))
        {
            CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
            return false;
        }
    }
    return true;
}
Пример #5
0
bool DropMoveCommand::Execute()
{
	CString droppath = parser.GetVal(_T("droptarget"));
	CString ProjectTop;
	if (!CTGitPath(droppath).HasAdminDir(&ProjectTop))
		return FALSE;
	
	if (ProjectTop != g_Git.m_CurrentDir )
	{
		CMessageBox::Show(NULL,_T("Target and source must be the same git repository"),_T("TortoiseGit"),MB_OK);
		return FALSE;
	}

	droppath = droppath.Right(droppath.GetLength()-ProjectTop.GetLength()-1);

	unsigned long count = 0;
	pathList.RemoveAdminPaths();
	CString sNewName;

	if ((parser.HasKey(_T("rename")))&&(pathList.GetCount()==1))
	{
		// ask for a new name of the source item
		do 
		{
			CRenameDlg renDlg;
			renDlg.m_windowtitle.LoadString(IDS_PROC_MOVERENAME);
			renDlg.m_name = pathList[0].GetFileOrDirectoryName();
			if (renDlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			sNewName = renDlg.m_name;
		} while(sNewName.IsEmpty() || PathFileExists(droppath+_T("\\")+sNewName));
	}
	CSysProgressDlg progress;
	if (progress.IsValid())
	{
		progress.SetTitle(IDS_PROC_MOVING);
		progress.SetAnimation(IDR_MOVEANI);
		progress.SetTime(true);
		progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
	}
	for(int nPath = 0; nPath < pathList.GetCount(); nPath++)
	{
		CTGitPath destPath;
		if (sNewName.IsEmpty())
			destPath = CTGitPath(droppath+_T("\\")+pathList[nPath].GetFileOrDirectoryName());
		else
			destPath = CTGitPath(droppath+_T("\\")+sNewName);
		if (destPath.Exists())
		{
			CString name = pathList[nPath].GetFileOrDirectoryName();
			if (!sNewName.IsEmpty())
				name = sNewName;
			progress.Stop();
			CRenameDlg dlg;
			dlg.m_name = name;
			dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
			if (dlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			destPath.SetFromWin(droppath+_T("\\")+dlg.m_name);
		} 
		CString cmd,out;
		
		cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),pathList[nPath].GetGitPathString(),destPath.GetGitPathString());
		if(g_Git.Run(cmd,&out,CP_ACP))
		{
			if (CMessageBox::Show(hwndExplorer, out, _T("TortoiseGit"), MB_YESNO)==IDYES)
			{
#if 0
					if (!svn.Move(CTSVNPathList(pathList[nPath]), destPath, TRUE))
					{
						CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
						return FALSE;		//get out of here
					}
					CShellUpdater::Instance().AddPathForUpdate(destPath);
#endif
			}
			else
			{
				//TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());
				CMessageBox::Show(hwndExplorer, _T("Cancel"), _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
		} 
		else
			CShellUpdater::Instance().AddPathForUpdate(destPath);
		count++;
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, pathList[nPath].GetWinPath());
			progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
			progress.SetProgress(count, pathList.GetCount());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			CMessageBox::Show(hwndExplorer, IDS_SVN_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			return FALSE;
		}
	}
	return true;
}
Пример #6
0
bool PasteMoveCommand::Execute()
{
	CString sDroppath = parser.GetVal(_T("droptarget"));
	CTGitPath dropPath(sDroppath);
	if (dropPath.IsAdminDir())
		return FALSE;

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

	GitStatus status;
	unsigned long count = 0;
	orgPathList.RemoveAdminPaths();
	CString sNewName;
	CSysProgressDlg progress;
	progress.SetTitle(IDS_PROC_MOVING);
	progress.SetAnimation(IDR_MOVEANI);
	progress.SetTime(true);
	progress.ShowModeless(CWnd::FromHandle(hwndExplorer));
	for (int nPath = 0; nPath < orgPathList.GetCount(); ++nPath)
	{
		CTGitPath destPath;
		if (sNewName.IsEmpty())
			destPath = CTGitPath(sDroppath+_T("\\")+orgPathList[nPath].GetFileOrDirectoryName());
		else
			destPath = CTGitPath(sDroppath+_T("\\")+sNewName);
		if (destPath.Exists())
		{
			CString name = orgPathList[nPath].GetFileOrDirectoryName();
			if (!sNewName.IsEmpty())
				name = sNewName;
			progress.Stop();
			CRenameDlg dlg;
			dlg.m_name = name;
			dlg.m_windowtitle.Format(IDS_PROC_NEWNAMEMOVE, (LPCTSTR)name);
			if (dlg.DoModal() != IDOK)
			{
				return FALSE;
			}
			destPath.SetFromWin(sDroppath+_T("\\")+dlg.m_name);
		}
		CString top;
		top.Empty();
		orgPathList[nPath].HasAdminDir(&top);
		git_wc_status_kind s = status.GetAllStatus(orgPathList[nPath]);
		if ((s == git_wc_status_none)||(s == git_wc_status_unversioned)||(s == git_wc_status_ignored)||top != g_Git.m_CurrentDir)
		{
			// source file is unversioned: move the file to the target, then add it
			MoveFile(orgPathList[nPath].GetWinPath(), destPath.GetWinPath());
			CString cmd,output;
			cmd.Format(_T("git.exe add -- \"%s\""),destPath.GetWinPath());
			if (g_Git.Run(cmd, &output, CP_UTF8))
			//if (!Git.Add(CTGitorgPathList(destPath), &props, Git_depth_infinity, true, false, true))
			{
				TRACE(_T("%s\n"), output);
				CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
				return FALSE;		//get out of here
			}
			CShellUpdater::Instance().AddPathForUpdate(destPath);
		}
		else
		{
			CString cmd,output;
			cmd.Format(_T("git.exe mv \"%s\" \"%s\""),orgPathList[nPath].GetGitPathString(),destPath.GetGitPathString());
			if (g_Git.Run(cmd, &output, CP_UTF8))
			//if (!Git.Move(CTGitorgPathList(orgPathList[nPath]), destPath, FALSE))
			{
#if 0
				if (Git.Err && (Git.Err->apr_err == Git_ERR_UNVERSIONED_RESOURCE ||
					Git.Err->apr_err == Git_ERR_CLIENT_MODIFIED))
				{
					// file/folder seems to have local modifications. Ask the user if
					// a force is requested.
					CString temp = Git.GetLastErrorMessage();
					CString sQuestion(MAKEINTRESOURCE(IDS_PROC_FORCEMOVE));
					temp += _T("\n") + sQuestion;
					if (CMessageBox::Show(hwndExplorer, temp, _T("TortoiseGit"), MB_YESNO)==IDYES)
					{
						if (!Git.Move(CTGitPathList(pathList[nPath]), destPath, TRUE))
						{
							CMessageBox::Show(hwndExplorer, Git.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);
							return FALSE;		//get out of here
						}
						CShellUpdater::Instance().AddPathForUpdate(destPath);
					}
				}
				else
#endif
				{
					TRACE(_T("%s\n"), (LPCTSTR)output);
					CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_ICONERROR);
					return FALSE;		//get out of here
				}
			}
			else
				CShellUpdater::Instance().AddPathForUpdate(destPath);
		}
		++count;
		if (progress.IsValid())
		{
			progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, orgPathList[nPath].GetWinPath());
			progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, destPath.GetWinPath());
			progress.SetProgress(count, orgPathList.GetCount());
		}
		if ((progress.IsValid())&&(progress.HasUserCancelled()))
		{
			CMessageBox::Show(hwndExplorer, IDS_USERCANCELLED, IDS_APPNAME, MB_ICONINFORMATION);
			return FALSE;
		}
	}
	return true;
}
Пример #7
0
int CGitLogList::RevertSelectedCommits()
{
	CSysProgressDlg progress;
	int ret = -1;

#if 0
	if(!g_Git.CheckCleanWorkTree())
	{
		CMessageBox::Show(NULL,_T("Revert requires a clean working tree"),_T("TortoiseGit"),MB_OK);

	}
#endif

	if (progress.IsValid() && (this->GetSelectedCount() > 1) )
	{
		progress.SetTitle(_T("Revert Commit"));
		progress.SetAnimation(IDR_MOVEANI);
		progress.SetTime(true);
		progress.ShowModeless(this);
	}

	POSITION pos = GetFirstSelectedItemPosition();
	int i=0;
	while(pos)
	{
		int index = GetNextSelectedItem(pos);
		GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index));

		if (progress.IsValid() && (this->GetSelectedCount() > 1) )
		{
			progress.FormatPathLine(1, _T("Revert %s"), r1->m_CommitHash.ToString());
			progress.FormatPathLine(2, _T("%s"),        r1->GetSubject());
			progress.SetProgress(i,         this->GetSelectedCount());
		}
		i++;

		if(r1->m_CommitHash.IsEmpty())
			continue;

		CString cmd, output;
		cmd.Format(_T("git.exe revert --no-edit --no-commit %s"), r1->m_CommitHash.ToString());
		if(g_Git.Run(cmd, &output, CP_ACP))
		{
			CString str;
			str=_T("Revert fail\n");
			str+= cmd;
			str+= _T("\n")+output;
			if( GetSelectedCount() == 1)
				CMessageBox::Show(NULL,str, _T("TortoiseGit"),MB_OK|MB_ICONERROR);
			else
			{
				if(CMessageBox::Show(NULL, str, _T("TortoiseGit"),2 , IDI_ERROR, _T("&Skip"), _T("&Abort")) == 2)
				{
					return ret;
				}
			}
		}
		else
		{
			ret =0;
		}

		if ((progress.IsValid())&&(progress.HasUserCancelled()))
			break;
	}
	return ret;
}
Пример #8
0
int CGitLogList::RevertSelectedCommits(int parent)
{
	CSysProgressDlg progress;
	int ret = -1;

#if 0
	if(!g_Git.CheckCleanWorkTree())
	{
		CMessageBox::Show(NULL, IDS_PROC_NOCLEAN, IDS_APPNAME, MB_OK);

	}
#endif

	if (this->GetSelectedCount() > 1)
	{
		progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROGS_TITLE_REVERTCOMMIT)));
		progress.SetAnimation(IDR_MOVEANI);
		progress.SetTime(true);
		progress.ShowModeless(this);
	}

	CBlockCacheForPath cacheBlock(g_Git.m_CurrentDir);

	POSITION pos = GetFirstSelectedItemPosition();
	int i=0;
	while(pos)
	{
		int index = GetNextSelectedItem(pos);
		GitRev * r1 = reinterpret_cast<GitRev*>(m_arShownList.GetAt(index));

		if (progress.IsVisible())
		{
			progress.FormatNonPathLine(1, IDS_PROC_REVERTCOMMIT, r1->m_CommitHash.ToString());
			progress.FormatNonPathLine(2, _T("%s"), (LPCTSTR)r1->GetSubject());
			progress.SetProgress(i, this->GetSelectedCount());
		}
		++i;

		if(r1->m_CommitHash.IsEmpty())
			continue;

		if (g_Git.GitRevert(parent, r1->m_CommitHash))
		{
			CString str;
			str.LoadString(IDS_SVNACTION_FAILEDREVERT);
			str = g_Git.GetGitLastErr(str, CGit::GIT_CMD_REVERT);
			if( GetSelectedCount() == 1)
				CMessageBox::Show(NULL, str, _T("TortoiseGit"), MB_OK | MB_ICONERROR);
			else
			{
				if(CMessageBox::Show(NULL, str, _T("TortoiseGit"),2 , IDI_ERROR, CString(MAKEINTRESOURCE(IDS_SKIPBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
				{
					return ret;
				}
			}
		}
		else
		{
			ret =0;
		}

		if (progress.HasUserCancelled())
			break;
	}
	return ret;
}