OSDN Git Service

Fixed issue #157: SVN Rebase doesn't fast-forward
authorFrank Li <lznuaa@gmail.com>
Fri, 4 Sep 2009 14:56:14 +0000 (22:56 +0800)
committerFrank Li <lznuaa@gmail.com>
Fri, 4 Sep 2009 14:56:14 +0000 (22:56 +0800)
Signed-off-by: Frank Li <lznuaa@gmail.com>
src/Git/Git.cpp
src/Git/Git.h
src/Resources/TortoiseProcENG.rc
src/TortoiseProc/RebaseDlg.cpp
src/TortoiseProc/RebaseDlg.h
src/TortoiseProc/resource.h

index 4e6f847..1f5b3c2 100644 (file)
@@ -1246,4 +1246,24 @@ int CGit::ListConflictFile(CTGitPathList &list,CTGitPath *path)
        list.ParserFromLsFile(vector);\r
 \r
        return 0;\r
+}\r
+\r
+bool CGit::IsFastForward(CString &from, CString &to)\r
+{\r
+       CString base,hash;\r
+       CString cmd;\r
+       cmd.Format(_T("git.exe merge-base %s %s"), to,from);\r
+\r
+       if(g_Git.Run(cmd,&base,CP_ACP))\r
+       {\r
+               //CMessageBox::Show(NULL,base,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+               return false;\r
+       }\r
+       base=base.Left(40);\r
+\r
+       hash=g_Git.GetHash(from);\r
+\r
+       hash=hash.Left(40);\r
+       \r
+       return hash == base;\r
 }
\ No newline at end of file
index f025ff6..6b39095 100644 (file)
@@ -44,6 +44,8 @@ public:
 \r
        int RunAsync(CString cmd,PROCESS_INFORMATION *pi, HANDLE* hRead, CString *StdioFile=NULL);\r
        int RunLogFile(CString cmd, CString &filename);\r
+\r
+       bool IsFastForward(CString &from, CString &to);\r
        CString GetConfigValue(CString name);\r
        CString GetUserName(void);\r
        CString GetUserEmail(void);\r
index b274db3..9009cf4 100644 (file)
Binary files a/src/Resources/TortoiseProcENG.rc and b/src/Resources/TortoiseProcENG.rc differ
index 91d875e..6bc54c0 100644 (file)
@@ -24,6 +24,7 @@ CRebaseDlg::CRebaseDlg(CWnd* pParent /*=NULL*/)
        m_bThreadRunning =FALSE;\r
        this->m_IsCherryPick = FALSE;\r
        m_bForce=FALSE;\r
+       m_IsFastForward=FALSE;\r
 }\r
 \r
 CRebaseDlg::~CRebaseDlg()\r
@@ -421,18 +422,43 @@ void CRebaseDlg::OnCbnSelchangeUpstream()
 \r
 void CRebaseDlg::FetchLogList()\r
 {\r
-       if(!this->m_bForce)\r
+       CString base,hash;\r
+       CString cmd;\r
+       m_IsFastForward=FALSE;\r
+       cmd.Format(_T("git.exe merge-base %s %s"), m_UpstreamCtrl.GetString(),m_BranchCtrl.GetString());\r
+       if(g_Git.Run(cmd,&base,CP_ACP))\r
        {\r
-               CString base,hash;\r
-               CString cmd;\r
-               cmd.Format(_T("git.exe merge-base %s %s"), m_UpstreamCtrl.GetString(),m_BranchCtrl.GetString());\r
-               if(g_Git.Run(cmd,&base,CP_ACP))\r
-               {\r
-                       CMessageBox::Show(NULL,base,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
-                       return;\r
-               }\r
-               base=base.Left(40);\r
+               CMessageBox::Show(NULL,base,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+               return;\r
+       }\r
+       base=base.Left(40);\r
+\r
+       hash=g_Git.GetHash(m_BranchCtrl.GetString());\r
+\r
+       hash=hash.Left(40);\r
+       \r
+       if(hash == base )\r
+       {\r
+               //fast forword\r
+               this->m_IsFastForward=TRUE;\r
+\r
+               m_CommitList.Clear();\r
+               CString text,fmt;\r
+               fmt.LoadString(IDS_REBASE_FASTFORWARD_FMT);\r
+               text.Format(fmt,m_BranchCtrl.GetString(),this->m_UpstreamCtrl.GetString(),\r
+                                               m_BranchCtrl.GetString(),this->m_UpstreamCtrl.GetString());\r
 \r
+               m_CommitList.ShowText(text);\r
+               this->GetDlgItem(IDC_REBASE_CONTINUE)->EnableWindow(true);\r
+               SetContinueButtonText();\r
+               \r
+               return ;\r
+       }\r
+\r
+       hash.Empty();\r
+\r
+       if(!this->m_bForce)\r
+       {\r
                cmd.Format(_T("git.exe rev-parse %s"), m_UpstreamCtrl.GetString());\r
                if( g_Git.Run(cmd,&hash,CP_ACP))\r
                {\r
@@ -449,6 +475,7 @@ void CRebaseDlg::FetchLogList()
                        text.Format(fmt,m_BranchCtrl.GetString());\r
                        m_CommitList.ShowText(text);\r
                        this->GetDlgItem(IDC_REBASE_CONTINUE)->EnableWindow(m_CommitList.GetItemCount());\r
+                       SetContinueButtonText();\r
                        return;\r
                }\r
        }\r
@@ -458,7 +485,7 @@ void CRebaseDlg::FetchLogList()
        if( m_CommitList.GetItemCount() == 0 )\r
                m_CommitList.ShowText(_T("Nothing to Rebase"));\r
 \r
-       CString hash=g_Git.GetHash(m_UpstreamCtrl.GetString());\r
+       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
@@ -488,6 +515,7 @@ void CRebaseDlg::FetchLogList()
                this->m_CurrentRebaseIndex = m_CommitList.m_logEntries.size();\r
        \r
        this->GetDlgItem(IDC_REBASE_CONTINUE)->EnableWindow(m_CommitList.GetItemCount());\r
+       SetContinueButtonText();\r
 }\r
 \r
 void CRebaseDlg::AddBranchToolTips(CHistoryCombo *pBranch)\r
@@ -651,6 +679,41 @@ int CRebaseDlg::FinishRebase()
 }\r
 void CRebaseDlg::OnBnClickedContinue()\r
 {\r
+       if( m_RebaseStage == REBASE_DONE)\r
+       {\r
+               OnOK();\r
+       }\r
+\r
+       if( this->m_IsFastForward )\r
+       {\r
+               m_OrigBranchHash = g_Git.GetHash(m_BranchCtrl.GetString());\r
+               m_OrigUpstreamHash = g_Git.GetHash(this->m_UpstreamCtrl.GetString());\r
+                       \r
+               if(!g_Git.IsFastForward(this->m_BranchCtrl.GetString(),this->m_UpstreamCtrl.GetString()))\r
+               {\r
+                       this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+                       AddLogString(_T("No fast forward\r\nMaybe repository changed"));\r
+                       return;\r
+               }\r
+               CString cmd,out;\r
+               cmd.Format(_T("git.exe reset --hard %s"),this->m_UpstreamCtrl.GetString());\r
+               this->AddLogString(CString(_T("Fast forward to "))+m_UpstreamCtrl.GetString());\r
+\r
+               AddLogString(cmd);\r
+               this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+               if(g_Git.Run(cmd,&out,CP_ACP))\r
+               {\r
+                       AddLogString(_T("Fail"));\r
+                       AddLogString(out);\r
+                       return;\r
+               }\r
+               AddLogString(out);\r
+               AddLogString(_T("Done"));\r
+               m_RebaseStage = REBASE_DONE;\r
+               UpdateCurrentStatus();\r
+               return;\r
+\r
+       }\r
        if( m_RebaseStage == CHOOSE_BRANCH|| m_RebaseStage == CHOOSE_COMMIT_PICK_MODE )\r
        {\r
                if(CheckRebaseCondition())\r
@@ -658,10 +721,6 @@ void CRebaseDlg::OnBnClickedContinue()
                m_RebaseStage = REBASE_START;\r
        }\r
 \r
-       if( m_RebaseStage == REBASE_DONE)\r
-       {\r
-               OnOK();\r
-       }\r
 \r
        if( m_RebaseStage == REBASE_FINISH )\r
        {\r
@@ -847,7 +906,10 @@ void CRebaseDlg::SetContinueButtonText()
        {\r
        case CHOOSE_BRANCH:\r
        case CHOOSE_COMMIT_PICK_MODE:\r
-               Text = _T("Start");\r
+               if(this->m_IsFastForward)\r
+                       Text = _T("Start(FastFwd)");\r
+               else\r
+                       Text = _T("Start");\r
                break;\r
 \r
        case REBASE_START:\r
@@ -1257,6 +1319,17 @@ void CRebaseDlg::OnBnClickedAbort()
        if(CMessageBox::Show(NULL,_T("Are you sure you want to abort the rebase process?"),_T("TortoiseGit"),MB_YESNO) != IDYES)\r
                return;\r
 \r
+       if(this->m_IsFastForward)\r
+       {\r
+               cmd.Format(_T("git.exe reset --hard  %s"),this->m_OrigBranchHash.Left(40));\r
+               if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               {\r
+                       AddLogString(out);\r
+                       return ;\r
+               }\r
+               __super::OnCancel();\r
+               return;\r
+       }\r
        cmd.Format(_T("git.exe checkout -f %s"),this->m_UpstreamCtrl.GetString());\r
        if(g_Git.Run(cmd,&out,CP_UTF8))\r
        {\r
index 2a301e1..15ef958 100644 (file)
@@ -77,6 +77,8 @@ protected:
        static UINT RebaseThreadEntry(LPVOID pVoid){return ((CRebaseDlg *)pVoid)->RebaseThread();};\r
        BOOL IsEnd();\r
 \r
+       BOOL m_IsFastForward;\r
+\r
        CString m_OrigBranchHash;\r
        CString m_OrigUpstreamHash;\r
 \r
index 6c10e0e..dd3d395 100644 (file)
Binary files a/src/TortoiseProc/resource.h and b/src/TortoiseProc/resource.h differ