Exemplo n.º 1
0
int CRebaseDlg::FinishRebase()
{
	if(this->m_IsCherryPick) //cherry pick mode no "branch", working at upstream branch
		return 0;

	git_revnum_t head = g_Git.GetHash(_T("HEAD"));
	CString out,cmd;

	out.Empty();
	cmd.Format(_T("git.exe checkout -f %s"),this->m_BranchCtrl.GetString());
	AddLogString(cmd);
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return -1;
	}
	AddLogString(out);

	out.Empty();
	cmd.Format(_T("git.exe reset --hard %s"),head);
	AddLogString(cmd);
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return -1;
	}
	AddLogString(out);

	m_ctrlTabCtrl.RemoveTab(0);
	m_ctrlTabCtrl.RemoveTab(0);
	m_CtrlStatusText.SetWindowText(_T("Finished rebasing."));

	return 0;
}
Exemplo n.º 2
0
int CRebaseDlg::VerifyNoConflict()
{
	CTGitPathList list;
	if(g_Git.ListConflictFile(list))
	{
		AddLogString(_T("Get conflict files fail"));
		return -1;
	}
	if( list.GetCount() != 0 )
	{
		CMessageBox::Show(NULL,_T("There are conflict file, you should mark it resolve"),_T("TortoiseGit"),MB_OK);
		return -1;
	}
	return 0;

}
Exemplo n.º 3
0
void CRebaseDlg::OnBnClickedContinue()
{
	if( m_RebaseStage == REBASE_DONE)
	{
		OnOK();
		return;
	}

	if( this->m_IsFastForward )
	{
		CString cmd,out;
		CString oldbranch = g_Git.GetCurrentBranch();
		if( oldbranch != m_BranchCtrl.GetString() )
		{
			cmd.Format(_T("git.exe checkout %s"),m_BranchCtrl.GetString());
			AddLogString(cmd);
			if( g_Git.Run(cmd,&out,CP_ACP) )
			{
				this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);
				AddLogString(out);
				return;
			}
		}
		AddLogString(out);
		out.Empty();
		m_OrigBranchHash = g_Git.GetHash(m_BranchCtrl.GetString());
		m_OrigUpstreamHash = g_Git.GetHash(this->m_UpstreamCtrl.GetString());

		if(!g_Git.IsFastForward(this->m_BranchCtrl.GetString(),this->m_UpstreamCtrl.GetString()))
		{
			this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);
			AddLogString(_T("No fast forward\r\nMaybe repository changed"));
			return;
		}

		cmd.Format(_T("git.exe reset --hard %s"),g_Git.FixBranchName(this->m_UpstreamCtrl.GetString()));
		this->AddLogString(CString(_T("Fast forward to "))+m_UpstreamCtrl.GetString());

		AddLogString(cmd);
		this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);
		if(g_Git.Run(cmd,&out,CP_ACP))
		{
			AddLogString(_T("Fail"));
			AddLogString(out);
			return;
		}
		AddLogString(out);
		AddLogString(_T("Done"));
		m_RebaseStage = REBASE_DONE;
		UpdateCurrentStatus();
		return;

	}
	if( m_RebaseStage == CHOOSE_BRANCH|| m_RebaseStage == CHOOSE_COMMIT_PICK_MODE )
	{
		if(CheckRebaseCondition())
			return ;
		m_RebaseStage = REBASE_START;
		m_FileListCtrl.Clear();
		m_FileListCtrl.m_CurrentVersion = L"";
		m_ctrlTabCtrl.SetTabLabel(REBASE_TAB_CONFLICT, _T("Conflict Files"));
		m_ctrlTabCtrl.AddTab(&m_wndOutputRebase,_T("Log"),2);
	}

	if( m_RebaseStage == REBASE_FINISH )
	{
		if(FinishRebase())
			return ;

		OnOK();
	}

	if( m_RebaseStage == REBASE_SQUASH_CONFLICT)
	{
		if(VerifyNoConflict())
			return;
		GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];
		if(this->CheckNextCommitIsSquash())
		{//next commit is not squash;
			m_RebaseStage = REBASE_SQUASH_EDIT;
			this->OnRebaseUpdateUI(0,0);
			this->UpdateCurrentStatus();
			return ;

		}
		m_RebaseStage=REBASE_CONTINUE;
		curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE;
		this->UpdateCurrentStatus();

	}

	if( m_RebaseStage == REBASE_CONFLICT )
	{
		if(VerifyNoConflict())
			return;

		GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];

		CString out =_T("");
		CString cmd;
		cmd.Format(_T("git.exe commit -a -C %s"), curRev->m_CommitHash.ToString());

		AddLogString(cmd);

		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			AddLogString(out);
			if(!g_Git.CheckCleanWorkTree())
			{
				CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
				return;
			}
		}

		AddLogString(out);
		this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);
		if( curRev->GetAction(&m_CommitList) & CTGitPath::LOGACTIONS_REBASE_EDIT)
		{
			m_RebaseStage=REBASE_EDIT;
			this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE);
			this->UpdateCurrentStatus();
			return;
		}
		else
		{
			m_RebaseStage=REBASE_CONTINUE;
			curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE;
			this->UpdateCurrentStatus();
		}
	}

	if( m_RebaseStage == REBASE_EDIT ||  m_RebaseStage == REBASE_SQUASH_EDIT )
	{
		CString str;
		GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];

		str=this->m_LogMessageCtrl.GetText();
		if(str.Trim().IsEmpty())
		{
			CMessageBox::Show(NULL,_T("Commit Message Is Empty"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);
				return;
		}

		CString tempfile=::GetTempFile();
		CFile file(tempfile,CFile::modeReadWrite|CFile::modeCreate );
		CStringA log=CUnicodeUtils::GetUTF8( str);
		file.Write(log,log.GetLength());
		//file.WriteString(m_sLogMessage);
		file.Close();

		CString out,cmd;

		if(  m_RebaseStage == REBASE_SQUASH_EDIT )
			cmd.Format(_T("git.exe commit -F \"%s\""), tempfile);
		else
			cmd.Format(_T("git.exe commit --amend -F \"%s\""), tempfile);

		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			if(!g_Git.CheckCleanWorkTree())
			{
				CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);
				return;
			}
		}

		CFile::Remove(tempfile);
		AddLogString(out);
		this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);
		m_RebaseStage=REBASE_CONTINUE;
		curRev->GetAction(&m_CommitList)|=CTGitPath::LOGACTIONS_REBASE_DONE;
		this->UpdateCurrentStatus();
	}


	InterlockedExchange(&m_bThreadRunning, TRUE);
	SetControlEnable();

	if (AfxBeginThread(RebaseThreadEntry, this)==NULL)
	{
		InterlockedExchange(&m_bThreadRunning, FALSE);
		CMessageBox::Show(NULL, _T("Create Rebase Thread Fail"), _T("TortoiseGit"), MB_OK | MB_ICONERROR);
		SetControlEnable();
	}
}
Exemplo n.º 4
0
int CRebaseDlg::StartRebase()
{
	CString cmd,out;
	m_FileListCtrl.m_bIsRevertTheirMy = !m_IsCherryPick;
	if(!this->m_IsCherryPick)
	{
		//Todo call comment_for_reflog
		cmd.Format(_T("git.exe checkout %s"),this->m_BranchCtrl.GetString());
		this->AddLogString(cmd);

		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			this->AddLogString(out);
			return -1;
		}

		this->AddLogString(out);
	}

	cmd=_T("git.exe rev-parse --verify HEAD");
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(_T("No Head"));
		return -1;
	}
	//Todo
	//git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
	//		echo "detached HEAD" > "$DOTEST"/head-name

	cmd.Format(_T("git.exe update-ref ORIG_HEAD HEAD"));
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(_T("update ORIG_HEAD Fail"));
		return -1;
	}

	m_OrigUpstreamHash.Empty();
	m_OrigUpstreamHash= g_Git.GetHash(this->m_UpstreamCtrl.GetString());
	if(m_OrigUpstreamHash.IsEmpty())
	{
		this->AddLogString(m_OrigUpstreamHash);
		return -1;
	}

	if( !this->m_IsCherryPick )
	{
		cmd.Format(_T("git.exe checkout -f %s"), m_OrigUpstreamHash.ToString());
		this->AddLogString(cmd);

		out.Empty();
		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			this->AddLogString(out);
			return -1;
		}
	}

	if( !this->m_IsCherryPick )
	{
		m_OrigBranchHash = g_Git.GetHash(this->m_BranchCtrl.GetString());
		if(m_OrigBranchHash.IsEmpty())
		{
			this->AddLogString(m_OrigBranchHash.ToString());
			return -1;
		}
		this->AddLogString(_T("Start Rebase\r\n"));

	}
	else
		this->AddLogString(_T("Start Cherry-pick\r\n"));

	return 0;
}
Exemplo n.º 5
0
void CRebaseDlg::OnBnClickedAbort()
{
	if (m_pTaskbarList)
		m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NOPROGRESS);

	CString cmd,out;
	CString pron = m_OrigUpstreamHash.ToString();
	if(m_OrigUpstreamHash.IsEmpty())
	{
		__super::OnCancel();
	}

	if(m_RebaseStage == CHOOSE_BRANCH || m_RebaseStage== CHOOSE_COMMIT_PICK_MODE)
	{
		return;
	}

	if(CMessageBox::Show(NULL,_T("Are you sure you want to abort the rebase process?"),_T("TortoiseGit"),MB_YESNO) != IDYES)
		return;

	if(this->m_IsFastForward)
	{
		cmd.Format(_T("git.exe reset --hard  %s"),this->m_OrigBranchHash.ToString());
		if(g_Git.Run(cmd,&out,CP_UTF8))
		{
			AddLogString(out);
			return ;
		}
		__super::OnCancel();
		return;
	}
	cmd.Format(_T("git.exe checkout -f %s"),g_Git.FixBranchName(this->m_UpstreamCtrl.GetString()));
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return ;
	}

	cmd.Format(_T("git.exe reset --hard  %s"),this->m_OrigUpstreamHash.ToString());
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return ;
	}

	if(this->m_IsCherryPick) //there are not "branch" at cherry pick mode
	{
		__super::OnCancel();
		return;
	}

	cmd.Format(_T("git checkout -f %s"),this->m_BranchCtrl.GetString());
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return ;
	}

	cmd.Format(_T("git.exe reset --hard  %s"),this->m_OrigBranchHash.ToString());
	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		return ;
	}
	__super::OnCancel();
}
Exemplo n.º 6
0
int CRebaseDlg::DoRebase()
{
	CString cmd,out;
	if(m_CurrentRebaseIndex <0)
		return 0;
	if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() )
		return 0;

	GitRev *pRev = (GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];
	int mode=pRev->GetAction(&m_CommitList) & CTGitPath::LOGACTIONS_REBASE_MODE_MASK;
	CString nocommit;

	if( mode== CTGitPath::LOGACTIONS_REBASE_SKIP)
	{
		pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
		return 0;
	}

	if( mode != CTGitPath::LOGACTIONS_REBASE_PICK )
	{
		this->m_SquashMessage+= pRev->GetSubject();
		this->m_SquashMessage+= _T("\n");
		this->m_SquashMessage+= pRev->GetBody();
	}
	else
		this->m_SquashMessage.Empty();

	if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
		nocommit=_T(" --no-commit ");

	CString log;
	log.Format(_T("%s %d: %s"),CTGitPath::GetActionName(mode),this->GetCurrentCommitID(),pRev->m_CommitHash.ToString());
	AddLogString(log);
	AddLogString(pRev->GetSubject());
	if (pRev->GetSubject().IsEmpty())
	{
		CMessageBox::Show(m_hWnd, _T("Found an empty commit message. You have to enter one or rebase cannot proceed."), _T("TortoiseGit"), MB_OK | MB_ICONEXCLAMATION);
		mode = CTGitPath::LOGACTIONS_REBASE_EDIT;
	}

	cmd.Format(_T("git.exe cherry-pick %s %s"),nocommit,pRev->m_CommitHash.ToString());

	if(g_Git.Run(cmd,&out,CP_UTF8))
	{
		AddLogString(out);
		CTGitPathList list;
		if(g_Git.ListConflictFile(list))
		{
			AddLogString(_T("Get conflict files fail"));
			return -1;
		}
		if(list.GetCount() == 0 )
		{
			if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)
			{
				pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
				return 0;
			}
			if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)
			{
				this->m_RebaseStage = REBASE_EDIT ;
				return -1; // Edit return -1 to stop rebase.
			}
			// Squash Case
			if(CheckNextCommitIsSquash())
			{   // no squash
				// let user edit last commmit message
				this->m_RebaseStage = REBASE_SQUASH_EDIT;
				return -1;
			}
		}
		if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
			m_RebaseStage = REBASE_SQUASH_CONFLICT;
		else
			m_RebaseStage = REBASE_CONFLICT;
		return -1;

	}
	else
	{
		AddLogString(out);
		if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)
		{
			pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
			return 0;
		}
		if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)
		{
			this->m_RebaseStage = REBASE_EDIT ;
			return -1; // Edit return -1 to stop rebase.
		}

		// Squash Case
		if(CheckNextCommitIsSquash())
		{   // no squash
			// let user edit last commmit message
			this->m_RebaseStage = REBASE_SQUASH_EDIT;
			return -1;
		}
		else if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)
			pRev->GetAction(&m_CommitList)|= CTGitPath::LOGACTIONS_REBASE_DONE;
	}

	return 0;
}
Exemplo n.º 7
0
UINT CImportPatchDlg::PatchThread()
{
	CTGitPath path;
	path.SetFromWin(g_Git.m_CurrentDir);

	int i=0;
	UpdateOkCancelText();
	for(i=m_CurrentItem;i<m_cList.GetItemCount();i++)
	{
		if (m_pTaskbarList)
		{
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
			m_pTaskbarList->SetProgressValue(m_hWnd, i, m_cList.GetItemCount());
		}

		m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLYING|m_cList.GetItemData(i));

		CRect rect;
		this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
		this->m_cList.InvalidateRect(rect);

		if(m_bExitThread)
			break;

		if(m_cList.GetCheck(i))
		{
			CString cmd;

			while(path.HasRebaseApply())
			{
				if (m_pTaskbarList)
					m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);

				int ret = CMessageBox::Show(NULL, _T("<ct=0x0000FF>previous rebase directory rebase-apply still exists but mbox given</ct>\n\n Do you want to"),
												  _T("TortoiseGit"),
												   1,IDI_ERROR ,_T("&Abort"), _T("&Skip"),_T("&Resolved"));

				switch(ret)
				{
				case 1:
					cmd = _T("git.exe am --abort");
					break;
				case 2:
					cmd = _T("git.exe am --skip");
					i++;
					break;
				case 3:
					cmd = _T("git.exe am --resolved");
					break;
				default:
					cmd.Empty();
				}
				if(cmd.IsEmpty())
				{
					m_bExitThread = TRUE;
					break;
				}

				this->AddLogString(cmd);
				CString output;
				if(g_Git.Run(cmd, &output, CP_ACP))
				{
					this->AddLogString(output);
					this->AddLogString(_T("Fail"));
				}
				else
				{
					this->AddLogString(_T("Done"));
				}
			}

			if(m_bExitThread)
				break;

			cmd = _T("git.exe am ");

			if(this->m_bAddSignedOffBy)
				cmd += _T("--signoff ");

			if(this->m_b3Way)
				cmd += _T("--3way ");

			if(this->m_bIgnoreSpace)
				cmd += _T("--ignore-space-change ");

			if(this->m_bKeepCR)
				cmd += _T("--keep-cr ");

			cmd += _T("\"");
			cmd += m_cList.GetItemText(i,0);
			cmd += _T("\"");

			this->AddLogString(cmd);
			CString output;
			if(g_Git.Run(cmd,&output,CP_ACP))
			{
				//keep STATUS_APPLYING to let user retry failed patch
				m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_FAIL|CPatchListCtrl::STATUS_APPLYING);
				this->AddLogString(output);
				this->AddLogString(_T("Fail"));
				if (m_pTaskbarList)
					m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);
				break;

			}
			else
			{
				m_cList.SetItemData(i,  CPatchListCtrl::STATUS_APPLY_SUCCESS);
				this->AddLogString(_T("Success"));
			}

		}
		else
		{
			AddLogString(CString(_T("Skip Patch: "))+m_cList.GetItemText(i,0));
			m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_SKIP);
		}

		m_cList.SetItemData(m_CurrentItem, (~CPatchListCtrl::STATUS_APPLYING)&m_cList.GetItemData(i));
		m_CurrentItem++;

		this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
		this->m_cList.InvalidateRect(rect);

		UpdateOkCancelText();
	}

	//in case am fail, need refresh finial item status
	CRect rect;
	this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
	this->m_cList.InvalidateRect(rect);

	this->m_cList.GetItemRect(m_CurrentItem,&rect,LVIR_BOUNDS);
	this->m_cList.InvalidateRect(rect);

	if (m_pTaskbarList)
	{
		m_pTaskbarList->SetProgressValue(m_hWnd, m_CurrentItem, m_cList.GetItemCount());
		if (m_bExitThread && m_CurrentItem != m_cList.GetItemCount())
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED);
		else if (!m_bExitThread && m_CurrentItem == m_cList.GetItemCount())
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
	}

	EnableInputCtrl(true);
	InterlockedExchange(&m_bThreadRunning, FALSE);
	UpdateOkCancelText();
	return 0;
}
Exemplo n.º 8
0
UINT CImportPatchDlg::PatchThread()
{
	CTGitPath path;
	path.SetFromWin(g_Git.m_CurrentDir);

	int i=0;
	UpdateOkCancelText();
	for (i = m_CurrentItem; i < m_cList.GetItemCount(); ++i)
	{
		if (m_pTaskbarList)
		{
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
			m_pTaskbarList->SetProgressValue(m_hWnd, i, m_cList.GetItemCount());
		}

		m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLYING|m_cList.GetItemData(i));

		CRect rect;
		this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
		this->m_cList.InvalidateRect(rect);

		if(m_bExitThread)
			break;

		if(m_cList.GetCheck(i))
		{
			CString cmd;

			while(path.HasRebaseApply())
			{
				if (m_pTaskbarList)
					m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);

				int ret = CMessageBox::Show(NULL, IDS_PROC_APPLYPATCH_REBASEDIRFOUND,
												  IDS_APPNAME,
												   1, IDI_ERROR, IDS_ABORTBUTTON, IDS_SKIPBUTTON, IDS_RESOLVEDBUTTON);

				switch(ret)
				{
				case 1:
					cmd = _T("git.exe am --abort");
					break;
				case 2:
					cmd = _T("git.exe am --skip");
					++i;
					break;
				case 3:
					cmd = _T("git.exe am --resolved");
					break;
				default:
					cmd.Empty();
				}
				if(cmd.IsEmpty())
				{
					m_bExitThread = TRUE;
					break;
				}

				this->AddLogString(cmd);
				CString output;
				if (g_Git.Run(cmd, &output, CP_UTF8))
				{
					this->AddLogString(output);
					this->AddLogString(CString(MAKEINTRESOURCE(IDS_FAIL)));
				}
				else
				{
					this->AddLogString(CString(MAKEINTRESOURCE(IDS_DONE)));
				}
			}

			if(m_bExitThread)
				break;

			cmd = _T("git.exe am ");

			if(this->m_bAddSignedOffBy)
				cmd += _T("--signoff ");

			if(this->m_b3Way)
				cmd += _T("--3way ");

			if(this->m_bIgnoreSpace)
				cmd += _T("--ignore-space-change ");

			if(this->m_bKeepCR)
				cmd += _T("--keep-cr ");

			cmd += _T("\"");
			cmd += m_cList.GetItemText(i,0);
			cmd += _T("\"");

			this->AddLogString(cmd);
			CString output;
			if (g_Git.Run(cmd, &output, CP_UTF8))
			{
				//keep STATUS_APPLYING to let user retry failed patch
				m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_FAIL|CPatchListCtrl::STATUS_APPLYING);
				this->AddLogString(output);
				this->AddLogString(CString(MAKEINTRESOURCE(IDS_FAIL)));
				if (m_pTaskbarList)
					m_pTaskbarList->SetProgressState(m_hWnd, TBPF_ERROR);
				break;

			}
			else
			{
				m_cList.SetItemData(i,  CPatchListCtrl::STATUS_APPLY_SUCCESS);
				this->AddLogString(CString(MAKEINTRESOURCE(IDS_SUCCESS)));
			}

		}
		else
		{
			CString sMessage;
			sMessage.Format(IDS_PROC_SKIPPATCH, m_cList.GetItemText(i,0));
			AddLogString(sMessage);
			m_cList.SetItemData(i, CPatchListCtrl::STATUS_APPLY_SKIP);
		}

		m_cList.SetItemData(m_CurrentItem, (~CPatchListCtrl::STATUS_APPLYING)&m_cList.GetItemData(i));
		++m_CurrentItem;

		this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
		this->m_cList.InvalidateRect(rect);

		UpdateOkCancelText();
	}

	//in case am fail, need refresh finial item status
	CRect rect;
	this->m_cList.GetItemRect(i,&rect,LVIR_BOUNDS);
	this->m_cList.InvalidateRect(rect);

	this->m_cList.GetItemRect(m_CurrentItem,&rect,LVIR_BOUNDS);
	this->m_cList.InvalidateRect(rect);

	if (m_pTaskbarList)
	{
		m_pTaskbarList->SetProgressValue(m_hWnd, m_CurrentItem, m_cList.GetItemCount());
		if (m_bExitThread && m_CurrentItem != m_cList.GetItemCount())
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_PAUSED);
		else if (!m_bExitThread && m_CurrentItem == m_cList.GetItemCount())
			m_pTaskbarList->SetProgressState(m_hWnd, TBPF_NORMAL);
	}

	EnableInputCtrl(true);
	InterlockedExchange(&m_bThreadRunning, FALSE);
	UpdateOkCancelText();
	return 0;
}