#include "TortoiseProc.h"\r
#include "RebaseDlg.h"\r
#include "AppUtils.h"\r
-\r
+#include "MessageBox.h"\r
+#include "UnicodeUtils.h"\r
// CRebaseDlg dialog\r
\r
IMPLEMENT_DYNAMIC(CRebaseDlg, CResizableStandAloneDialog)\r
{\r
m_RebaseStage=CHOOSE_BRANCH;\r
m_CurrentRebaseIndex=-1;\r
+ m_bThreadRunning =FALSE;\r
}\r
\r
CRebaseDlg::~CRebaseDlg()\r
\r
CString hash=g_Git.GetHash(m_UpstreamCtrl.GetString());\r
\r
+#if 0\r
if(m_CommitList.m_logEntries[m_CommitList.m_logEntries.size()-1].m_ParentHash.size() >=0 )\r
{\r
if(hash == m_CommitList.m_logEntries[m_CommitList.m_logEntries.size()-1].m_ParentHash[0])\r
m_CommitList.ShowText(_T("Nothing Rebase"));\r
}\r
}\r
- \r
+#endif\r
+\r
m_tooltips.Pop();\r
AddBranchToolTips(&this->m_BranchCtrl);\r
AddBranchToolTips(&this->m_UpstreamCtrl);\r
m_tooltips.RelayEvent(pMsg);\r
return CResizableStandAloneDialog::PreTranslateMessage(pMsg);\r
}\r
-\r
-void CRebaseDlg::OnBnClickedContinue()\r
+int CRebaseDlg::CheckRebaseCondition()\r
{\r
- GitRev *prevRev,*curRev;\r
- prevRev=curRev=NULL;\r
- CRect rect;\r
- int prevIndex=m_CurrentRebaseIndex;\r
- \r
- UpdateCurrentStatus();\r
+ this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
\r
- if( m_CurrentRebaseIndex >= 0 && m_CurrentRebaseIndex< m_CommitList.m_arShownList.GetSize())\r
+ if( !g_Git.CheckCleanWorkTree() )\r
{\r
- prevRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+ CMessageBox::Show(NULL,_T("Rebase Need Clean Working Tree"),_T("TortoiseGit"),MB_OK);\r
+ return -1;\r
}\r
- \r
- if(m_CommitList.m_IsOldFirst)\r
- m_CurrentRebaseIndex++;\r
- else\r
- m_CurrentRebaseIndex--;\r
+ //Todo Check $REBASE_ROOT\r
+ //Todo Check $DOTEST\r
\r
- if(m_CurrentRebaseIndex >= 0 && m_CurrentRebaseIndex<m_CommitList.m_arShownList.GetSize())\r
- {\r
- curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+ CString cmd;\r
+ cmd=_T("git.exe var GIT_COMMITTER_IDENT");\r
+ if(g_Git.Run(cmd,NULL,CP_UTF8))\r
+ return -1;\r
\r
- }\r
+ //Todo call pre_rebase_hook\r
+}\r
+int CRebaseDlg::StartRebase()\r
+{\r
+ CString cmd,out;\r
+ //Todo call comment_for_reflog\r
+ cmd.Format(_T("git.exe checkout %s"),this->m_BranchCtrl.GetString());\r
+ this->AddLogString(cmd);\r
\r
- if(prevRev)\r
- {\r
- prevRev->m_Action &= ~ CTGitPath::LOGACTIONS_REBASE_CURRENT;\r
- prevRev->m_Action |= CTGitPath::LOGACTIONS_REBASE_DONE;\r
- m_CommitList.GetItemRect(prevIndex,&rect,LVIR_BOUNDS);\r
- m_CommitList.InvalidateRect(rect);\r
+ if(g_Git.Run(cmd,&out,CP_UTF8))\r
+ return -1;\r
+\r
+ this->AddLogString(out);\r
\r
+ cmd=_T("git.exe rev-parse --verify HEAD");\r
+ if(g_Git.Run(cmd,&out,CP_UTF8))\r
+ {\r
+ AddLogString(_T("No Head"));\r
+ return -1;\r
}\r
+ //Todo \r
+ //git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
+ // echo "detached HEAD" > "$DOTEST"/head-name\r
\r
- if(curRev)\r
+ cmd.Format(_T("git.exe update-ref ORIG_HEAD HEAD"));\r
+ if(g_Git.Run(cmd,&out,CP_UTF8))\r
{\r
- curRev->m_Action |= CTGitPath::LOGACTIONS_REBASE_CURRENT;\r
- m_CommitList.GetItemRect(m_CurrentRebaseIndex,&rect,LVIR_BOUNDS);\r
- m_CommitList.InvalidateRect(rect);\r
+ AddLogString(_T("update ORIG_HEAD Fail"));\r
+ return -1;\r
}\r
+ \r
+ cmd.Format(_T("git.exe update-ref ORIG_HEAD HEAD"));\r
\r
+ cmd.Format(_T("git.exe checkout %s"),this->m_UpstreamCtrl.GetString());\r
+ this->AddLogString(cmd);\r
+\r
+ out.Empty();\r
+ if(g_Git.Run(cmd,&out,CP_UTF8))\r
+ {\r
+ return -1;\r
+ }\r
\r
- UpdateCurrentStatus();\r
+ this->AddLogString(_T("Start Rebase\r\n"));\r
+ return 0;\r
+}\r
+void CRebaseDlg::OnBnClickedContinue()\r
+{\r
+ if( m_RebaseStage == CHOOSE_BRANCH|| m_RebaseStage == CHOOSE_COMMIT_PICK_MODE )\r
+ {\r
+ if(CheckRebaseCondition())\r
+ return ;\r
+ m_RebaseStage = REBASE_START;\r
+ }\r
\r
- m_CommitList.EnsureVisible(m_CurrentRebaseIndex,FALSE);\r
+ InterlockedExchange(&m_bThreadRunning, TRUE);\r
+ SetControlEnable();\r
\r
- this->SetContinueButtonText();\r
- this->SetControlEnable();\r
- UpdateProgress();\r
+ if (AfxBeginThread(RebaseThreadEntry, this)==NULL)\r
+ {\r
+ InterlockedExchange(&m_bThreadRunning, FALSE);\r
+ CMessageBox::Show(NULL, _T("Create Rebase Thread Fail"), _T("TortoiseGit"), MB_OK | MB_ICONERROR);\r
+ SetControlEnable();\r
+ }\r
+}\r
+int CRebaseDlg::GoNext()\r
+{\r
+ if(m_CommitList.m_IsOldFirst)\r
+ m_CurrentRebaseIndex++;\r
+ else\r
+ m_CurrentRebaseIndex--; \r
+ return 0;\r
+\r
}\r
+int CRebaseDlg::StateAction()\r
+{\r
+ switch(this->m_RebaseStage)\r
+ {\r
+ case CHOOSE_BRANCH:\r
+ case CHOOSE_COMMIT_PICK_MODE:\r
+ if(StartRebase())\r
+ return -1;\r
+ m_RebaseStage = REBASE_START;\r
+ GoNext();\r
+ break;\r
+ }\r
\r
+ return 0; \r
+}\r
void CRebaseDlg::SetContinueButtonText()\r
{\r
CString Text;\r
this->m_CommitList.m_IsEnableRebaseMenu=FALSE;\r
break;\r
}\r
+\r
+ if(m_bThreadRunning)\r
+ {\r
+ this->GetDlgItem(IDC_REBASE_CONTINUE)->EnableWindow(FALSE);\r
+ this->GetDlgItem(IDC_REBASE_ABORT)->EnableWindow(FALSE);\r
+\r
+ }else\r
+ {\r
+ this->GetDlgItem(IDC_REBASE_CONTINUE)->EnableWindow(TRUE);\r
+ this->GetDlgItem(IDC_REBASE_ABORT)->EnableWindow(TRUE);\r
+ }\r
}\r
\r
void CRebaseDlg::UpdateProgress()\r
{\r
int index;\r
+ CRect rect;\r
\r
if(m_CommitList.m_IsOldFirst)\r
index = m_CurrentRebaseIndex+1;\r
m_CtrlStatusText.SetWindowText(text);\r
\r
}\r
+\r
+ GitRev *prevRev=NULL, *curRev=NULL;\r
+ int prevIndex;\r
+\r
+ if( m_CurrentRebaseIndex >= 0 && m_CurrentRebaseIndex< m_CommitList.m_arShownList.GetSize())\r
+ {\r
+ curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+ }\r
+ \r
+ if(m_CommitList.m_IsOldFirst)\r
+ prevIndex=m_CurrentRebaseIndex+1;\r
+ else\r
+ prevIndex=m_CurrentRebaseIndex-1;\r
+\r
+ if(prevIndex >= 0 && prevIndex<m_CommitList.m_arShownList.GetSize())\r
+ {\r
+ curRev=(GitRev*)m_CommitList.m_arShownList[prevIndex];\r
+ }\r
+\r
+ if(prevRev)\r
+ {\r
+ prevRev->m_Action &= ~ CTGitPath::LOGACTIONS_REBASE_CURRENT;\r
+ prevRev->m_Action |= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+ m_CommitList.GetItemRect(prevIndex,&rect,LVIR_BOUNDS);\r
+ m_CommitList.InvalidateRect(rect);\r
+ }\r
+\r
+ if(curRev)\r
+ {\r
+ curRev->m_Action |= CTGitPath::LOGACTIONS_REBASE_CURRENT;\r
+ m_CommitList.GetItemRect(m_CurrentRebaseIndex,&rect,LVIR_BOUNDS);\r
+ m_CommitList.InvalidateRect(rect);\r
+ }\r
+ m_CommitList.EnsureVisible(m_CurrentRebaseIndex,FALSE);\r
+\r
}\r
\r
void CRebaseDlg::UpdateCurrentStatus()\r
SetContinueButtonText();\r
SetControlEnable();\r
UpdateProgress();\r
+}\r
+\r
+void CRebaseDlg::AddLogString(CString str)\r
+{\r
+ this->m_wndOutputRebase.SendMessage(SCI_SETREADONLY, FALSE);\r
+ CStringA sTextA = m_wndOutputRebase.StringForControl(str);//CUnicodeUtils::GetUTF8(str);\r
+ this->m_wndOutputRebase.SendMessage(SCI_REPLACESEL, 0, (LPARAM)(LPCSTR)sTextA);\r
+ this->m_wndOutputRebase.SendMessage(SCI_REPLACESEL, 0, (LPARAM)(LPCSTR)"\n");\r
+ this->m_wndOutputRebase.SendMessage(SCI_SETREADONLY, TRUE);\r
+}\r
+\r
+int CRebaseDlg::DoRebase()\r
+{ \r
+ if(m_CurrentRebaseIndex <0)\r
+ return 0;\r
+ if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() )\r
+ return 0;\r
+\r
+ this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+\r
+ GitRev *pRev = (GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+ int mode=pRev->m_Action & CTGitPath::LOGACTIONS_REBASE_MODE_MASK;\r
+ switch(mode)\r
+ {\r
+ case CTGitPath::LOGACTIONS_REBASE_PICK:\r
+ AddLogString(CString(_T("Pick "))+pRev->m_CommitHash);\r
+ pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+ break;\r
+ case CTGitPath::LOGACTIONS_REBASE_SQUASH:\r
+ break;\r
+ case CTGitPath::LOGACTIONS_REBASE_EDIT:\r
+ break;\r
+ case CTGitPath::LOGACTIONS_REBASE_SKIP:\r
+ pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+ return 0;\r
+ break;\r
+ default:\r
+ AddLogString(CString(_T("Unknow Action for "))+pRev->m_CommitHash);\r
+ break;\r
+ }\r
+ return 0;\r
+}\r
+\r
+BOOL CRebaseDlg::IsEnd()\r
+{\r
+ if(m_CommitList.m_IsOldFirst)\r
+ return m_CurrentRebaseIndex>= this->m_CommitList.GetItemCount();\r
+ else\r
+ return m_CurrentRebaseIndex<0;\r
+}\r
+\r
+int CRebaseDlg::RebaseThread()\r
+{\r
+ int ret=0;\r
+ while(1)\r
+ {\r
+ if( m_RebaseStage == REBASE_START )\r
+ {\r
+ if( this->StartRebase() )\r
+ {\r
+ InterlockedExchange(&m_bThreadRunning, FALSE);\r
+ ret = -1;\r
+ break;\r
+ }\r
+ m_RebaseStage = REBASE_CONTINUE;\r
+ }\r
+\r
+ if( m_RebaseStage == REBASE_CONTINUE )\r
+ {\r
+ this->GoNext(); \r
+ if(IsEnd())\r
+ {\r
+ ret = 0;\r
+ m_RebaseStage = REBASE_FINISH;\r
+ break;\r
+ }\r
+\r
+ ret = DoRebase();\r
+\r
+ if( ret )\r
+ { \r
+ break;\r
+ }\r
+ }\r
+ this->UpdateCurrentStatus();\r
+ }\r
+\r
+ InterlockedExchange(&m_bThreadRunning, FALSE);\r
+ this->UpdateCurrentStatus();\r
+ this->SetControlEnable();\r
+ this->SetContinueButtonText();\r
+ return ret;\r
}
\ No newline at end of file