OSDN Git Service

RebaseDlg: Add Squash Support. but there are problem at last commit message.
authorFrank Li <lznuaa@gmail.com>
Wed, 18 Feb 2009 16:19:20 +0000 (00:19 +0800)
committerFrank Li <lznuaa@gmail.com>
Wed, 18 Feb 2009 16:19:20 +0000 (00:19 +0800)
src/TortoiseProc/RebaseDlg.cpp
src/TortoiseProc/RebaseDlg.h

index e256980..0faf90b 100644 (file)
@@ -177,6 +177,7 @@ BOOL CRebaseDlg::OnInitDialog()
 \r
        FetchLogList();\r
        SetContinueButtonText();\r
+       this->SetControlEnable();\r
        return TRUE;\r
 }\r
 // CRebaseDlg message handlers\r
@@ -531,13 +532,24 @@ void CRebaseDlg::OnBnClickedContinue()
                OnOK();\r
        }\r
 \r
+       if( m_RebaseStage == REBASE_SQUASH_CONFLICT)\r
+       {\r
+               if(VerifyNoConflict())\r
+                       return;\r
+               GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+               m_RebaseStage=REBASE_CONTINUE;\r
+               curRev->m_Action|=CTGitPath::LOGACTIONS_REBASE_DONE;\r
+               this->UpdateCurrentStatus();\r
+\r
+       }\r
+\r
        if( m_RebaseStage == REBASE_CONFLICT )\r
        {\r
                if(VerifyNoConflict())\r
                        return;\r
 \r
                GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
-       \r
+               \r
                CString out =_T("");\r
                CString cmd;\r
                cmd.Format(_T("git.exe commit -C %s"), curRev->m_CommitHash);\r
@@ -569,7 +581,7 @@ void CRebaseDlg::OnBnClickedContinue()
                \r
        }\r
 \r
-       if( m_RebaseStage == REBASE_EDIT )\r
+       if( m_RebaseStage == REBASE_EDIT ||  m_RebaseStage == REBASE_SQUASH_EDIT )\r
        {\r
                CString str;\r
                GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
@@ -590,7 +602,10 @@ void CRebaseDlg::OnBnClickedContinue()
        \r
                CString out,cmd;\r
                \r
-               cmd.Format(_T("git.exe commit --amend -F \"%s\""), tempfile);\r
+               if(  m_RebaseStage == REBASE_SQUASH_EDIT )\r
+                       cmd.Format(_T("git.exe commit -F \"%s\""), tempfile);\r
+               else\r
+                       cmd.Format(_T("git.exe commit --amend -F \"%s\""), tempfile);\r
 \r
                if(g_Git.Run(cmd,&out,CP_UTF8))\r
                {\r
@@ -620,6 +635,40 @@ void CRebaseDlg::OnBnClickedContinue()
                SetControlEnable();\r
        }\r
 }\r
+int CRebaseDlg::CheckNextCommitIsSquash()\r
+{\r
+       int index;\r
+       if(m_CommitList.m_IsOldFirst)\r
+               index=m_CurrentRebaseIndex+1;\r
+       else\r
+               index=m_CurrentRebaseIndex-1;\r
+\r
+       GitRev *curRev;\r
+       do\r
+       {\r
+               curRev=(GitRev*)m_CommitList.m_arShownList[index];\r
+               \r
+               if( curRev->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH )\r
+                       return 0;\r
+               if( curRev->m_Action&CTGitPath::LOGACTIONS_REBASE_SKIP)\r
+               {\r
+                       if(m_CommitList.m_IsOldFirst)\r
+                               index++;\r
+                       else\r
+                               index--;\r
+               }else\r
+                       return -1;\r
+\r
+               if(index<0)\r
+                       return -1;\r
+               if(index>= m_CommitList.GetItemCount())\r
+                       return -1;\r
+\r
+       }while(curRev->m_Action&CTGitPath::LOGACTIONS_REBASE_SKIP);\r
+       \r
+       return -1;\r
+\r
+}\r
 int CRebaseDlg::GoNext()\r
 {\r
        if(m_CommitList.m_IsOldFirst)\r
@@ -656,6 +705,7 @@ void CRebaseDlg::SetContinueButtonText()
 \r
        case REBASE_START:\r
        case REBASE_CONTINUE:\r
+       case REBASE_SQUASH_CONFLICT:\r
                Text = _T("Continue");\r
                break;\r
 \r
@@ -666,6 +716,10 @@ void CRebaseDlg::SetContinueButtonText()
                Text = _T("Amend");\r
                break;\r
 \r
+       case REBASE_SQUASH_EDIT:\r
+               Text = _T("Commit");\r
+               break;\r
+\r
        case REBASE_ABORT:\r
        case REBASE_FINISH:\r
                Text = _T("Finish");\r
@@ -695,6 +749,7 @@ void CRebaseDlg::SetControlEnable()
        case REBASE_FINISH:\r
        case REBASE_CONFLICT:\r
        case REBASE_EDIT:\r
+       case REBASE_SQUASH_CONFLICT:\r
                this->GetDlgItem(IDC_PICK_ALL)->EnableWindow(FALSE);\r
                this->GetDlgItem(IDC_EDIT_ALL)->EnableWindow(FALSE);\r
                this->GetDlgItem(IDC_SQUASH_ALL)->EnableWindow(FALSE);\r
@@ -805,60 +860,85 @@ int CRebaseDlg::DoRebase()
        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
+       CString nocommit;\r
+\r
+       if( mode== CTGitPath::LOGACTIONS_REBASE_SKIP)\r
        {\r
-       case CTGitPath::LOGACTIONS_REBASE_EDIT:\r
-       case CTGitPath::LOGACTIONS_REBASE_PICK: \r
-               AddLogString(CTGitPath::GetActionName(mode)+pRev->m_CommitHash);\r
-               AddLogString(pRev->m_Subject);\r
-               cmd.Format(_T("git.exe cherry-pick %s"),pRev->m_CommitHash);\r
-               if(g_Git.Run(cmd,&out,CP_UTF8))\r
-               {\r
-                       AddLogString(out);\r
-                       CTGitPathList list;\r
-                       if(g_Git.ListConflictFile(list))\r
-                       {\r
-                               AddLogString(_T("Get conflict files fail"));\r
-                               return -1;\r
-                       }\r
-                       if(list.GetCount() == 0 )\r
-                       {\r
-                               if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)\r
-                                       pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
-                               else\r
-                                       return -1; // Edit return -1 to stop rebase. \r
-                               break;\r
-                       }\r
+               pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+               return 0;\r
+       }\r
+       \r
+       if( mode != CTGitPath::LOGACTIONS_REBASE_PICK )\r
+       {\r
+               this->m_SquashMessage+= pRev->m_Subject;\r
+               this->m_SquashMessage+= _T("\n");\r
+               this->m_SquashMessage+= pRev->m_Body;\r
+       }\r
+       else\r
+               this->m_SquashMessage.Empty();\r
 \r
-                       this->m_RebaseStage = REBASE_CONFLICT;\r
-                       return -1;      \r
+       if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+               nocommit=_T(" --no-commit ");\r
 \r
-               }else\r
+       AddLogString(CTGitPath::GetActionName(mode)+_T(":")+pRev->m_CommitHash);\r
+       AddLogString(pRev->m_Subject);\r
+       cmd.Format(_T("git.exe cherry-pick %s %s"),nocommit,pRev->m_CommitHash);\r
+\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+       {\r
+               AddLogString(out);\r
+               CTGitPathList list;\r
+               if(g_Git.ListConflictFile(list))\r
+               {\r
+                       AddLogString(_T("Get conflict files fail"));\r
+                       return -1;\r
+               }\r
+               if(list.GetCount() == 0 )\r
                {\r
-                       AddLogString(out);\r
                        if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)\r
-                               pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
-                       else\r
                        {\r
-                               this->m_RebaseStage = REBASE_EDIT;\r
+                               pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+                               return 0;\r
+                       }\r
+                       if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)\r
                                return -1; // Edit return -1 to stop rebase. \r
+                       \r
+                       // Squash Case\r
+                       if(CheckNextCommitIsSquash())\r
+                       {   // no squash\r
+                               // let user edit last commmit message\r
+                               this->m_RebaseStage = REBASE_SQUASH_EDIT;\r
+                               return -1;\r
                        }\r
                }\r
-               break;\r
-       case CTGitPath::LOGACTIONS_REBASE_SQUASH:\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
+               if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+                       m_RebaseStage = REBASE_SQUASH_CONFLICT;\r
+               else\r
+                       m_RebaseStage = REBASE_CONFLICT;\r
+               return -1;      \r
+\r
+       }else\r
+       {\r
+               AddLogString(out);\r
+               if(mode ==  CTGitPath::LOGACTIONS_REBASE_PICK)\r
+               {\r
+                       pRev->m_Action|= CTGitPath::LOGACTIONS_REBASE_DONE;\r
+                       return 0;\r
+               }\r
+               if(mode == CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+                       return -1; // Edit return -1 to stop rebase. \r
+\r
+               // Squash Case\r
+               if(CheckNextCommitIsSquash())\r
+               {   // no squash\r
+                       // let user edit last commmit message\r
+                       this->m_RebaseStage = REBASE_SQUASH_EDIT;\r
+                       return -1;\r
+               }\r
        }\r
+       \r
        return 0;\r
 }\r
 \r
@@ -940,6 +1020,7 @@ LRESULT CRebaseDlg::OnRebaseUpdateUI(WPARAM,LPARAM)
        switch(m_RebaseStage)\r
        {\r
        case REBASE_CONFLICT:\r
+       case REBASE_SQUASH_CONFLICT:\r
                ListConflictFile();                     \r
                this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_CONFLICT);\r
                this->m_LogMessageCtrl.SetText(curRev->m_Subject+_T("\n")+curRev->m_Body);\r
@@ -948,6 +1029,10 @@ LRESULT CRebaseDlg::OnRebaseUpdateUI(WPARAM,LPARAM)
                this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE);\r
                this->m_LogMessageCtrl.SetText(curRev->m_Subject+_T("\n")+curRev->m_Body);\r
                break;\r
+       case REBASE_SQUASH_EDIT:\r
+               this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE);\r
+               this->m_LogMessageCtrl.SetText(this->m_SquashMessage);\r
+               break;\r
        default:\r
                this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
        }       \r
index 8a3a34c..df77a2e 100644 (file)
@@ -38,6 +38,8 @@ public:
                REBASE_FINISH,\r
                REBASE_CONFLICT,\r
                REBASE_EDIT,\r
+               REBASE_SQUASH_EDIT,\r
+               REBASE_SQUASH_CONFLICT,\r
        };\r
 \r
 protected:\r
@@ -79,6 +81,10 @@ protected:
        int VerifyNoConflict();\r
        CString GetRebaseModeName(int rebasemode);\r
 \r
+       CString m_SquashMessage;\r
+\r
+       int CheckNextCommitIsSquash();\r
+\r
 public:\r
    \r
     afx_msg void OnBnClickedPickAll();\r