OSDN Git Service

Merge remove x86 build
authorFrank Li <lznuaa@gmail.com>
Fri, 20 Feb 2009 05:19:38 +0000 (13:19 +0800)
committerFrank Li <lznuaa@gmail.com>
Fri, 20 Feb 2009 05:19:38 +0000 (13:19 +0800)
67 files changed:
Languages/Tortoise.pot
Languages/TortoiseLang.vcproj
ext/igit.exe [new file with mode: 0644]
ext/wingit/wingit.dll [deleted file]
ext/wingit/wingit.h [deleted file]
ext/wingit/wingit.lib [deleted file]
src/Git/Git.cpp
src/Git/Git.h
src/Git/GitFolderStatus.cpp
src/Git/GitFolderStatus.h
src/Git/GitStatus.cpp
src/Git/GitStatus.h
src/Git/GitStatusListCtrl.cpp
src/Git/GitStatusListCtrl.h
src/Git/TGitPath.cpp
src/Git/TGitPath.h
src/Resources/TortoiseProcENG.rc
src/TGitCache/CacheInterface.h
src/TGitCache/CachedDirectory.cpp
src/TGitCache/CachedDirectory.h
src/TGitCache/FolderCrawler.cpp
src/TGitCache/SVNStatusCache.cpp
src/TGitCache/StatusCacheEntry.cpp
src/TGitCache/StatusCacheEntry.h
src/TGitCache/TSVNCache.cpp
src/TGitCache/TSVNCache.vcproj
src/TortoiseGitBlame/TortoiseGitBlame.vcproj
src/TortoiseGitSetup/StructureFragment.wxi
src/TortoiseProc/Commands/Command.cpp
src/TortoiseProc/Commands/RebaseCommand.cpp [new file with mode: 0644]
src/TortoiseProc/Commands/RebaseCommand.h [new file with mode: 0644]
src/TortoiseProc/CommitDlg.cpp
src/TortoiseProc/FileDiffDlg.cpp
src/TortoiseProc/GitDiff.cpp
src/TortoiseProc/GitLogCache.cpp
src/TortoiseProc/GitLogList.h
src/TortoiseProc/GitLogListAction.cpp
src/TortoiseProc/GitLogListBase.cpp
src/TortoiseProc/GitLogListBase.h
src/TortoiseProc/LogDataVector.cpp
src/TortoiseProc/LogDlgHelper.h
src/TortoiseProc/ProgressDlg.cpp
src/TortoiseProc/ProgressDlg.h
src/TortoiseProc/RebaseDlg.cpp [new file with mode: 0644]
src/TortoiseProc/RebaseDlg.h [new file with mode: 0644]
src/TortoiseProc/Settings/SetLookAndFeelPage.cpp
src/TortoiseProc/Settings/SetLookAndFeelPage.h
src/TortoiseProc/Settings/SetOverlayPage.cpp
src/TortoiseProc/TortoiseProc.vcproj
src/TortoiseProc/gitlogcache.h
src/TortoiseProc/resource.h
src/TortoiseShell/ColumnProvider.cpp
src/TortoiseShell/ContextMenu.cpp
src/TortoiseShell/Globals.h
src/TortoiseShell/IconOverlay.cpp
src/TortoiseShell/RemoteCacheLink.cpp
src/TortoiseShell/RemoteCacheLink.h
src/TortoiseShell/ShellCache.h
src/TortoiseShell/ShellExt.cpp
src/TortoiseShell/ShellExt.h
src/TortoiseShell/TortoiseShell.vcproj
src/TortoiseShell/register_recover.reg
src/TortoiseShell/resource.h
src/TortoiseShell/resourceshell.rc
src/Utils/MiscUI/HistoryCombo.cpp
src/Utils/MiscUI/HistoryCombo.h
src/Utils/MiscUI/SciEdit.cpp

index 5cc1f16..d7d72d0 100644 (file)
@@ -1870,7 +1870,7 @@ msgid "Clipboard"
 msgstr ""
 
 #. Resource IDs: (14)
-msgid "Clone"
+msgid "Clone..."
 msgstr ""
 
 #. Resource IDs: (65535)
@@ -3240,7 +3240,7 @@ msgid "Git URL"
 msgstr ""
 
 #. Resource IDs: (297)
-msgid "Git clone..."
+msgid "Git clone"
 msgstr ""
 
 #. Resource IDs: (17)
index 7ed9b03..9169f2c 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="9.00"\r
+       Version="9,00"\r
        Name="TortoiseLangs"\r
        ProjectGUID="{EC88E7EC-3074-4841-BA45-B938D098EFF6}"\r
        RootNamespace="TortoiseLangs"\r
@@ -50,8 +50,8 @@
                                BuildCommandLine="nmake /f Makefile outdir=$(OutDir)  ConfigurationName=$(ConfigurationName)"\r
                                ReBuildCommandLine="nmake /f Makefile outdir=$(OutDir)  ConfigurationName=$(ConfigurationName)"\r
                                CleanCommandLine="nmake /f Makefile clean "\r
-                               Output=""\r
-                               PreprocessorDefinitions="WIN32;_DEBUG"\r
+                               Output="TortoiseLangs.exe"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG"\r
                                IncludeSearchPath=""\r
                                ForcedIncludes=""\r
                                AssemblySearchPath=""\r
diff --git a/ext/igit.exe b/ext/igit.exe
new file mode 100644 (file)
index 0000000..60501a4
Binary files /dev/null and b/ext/igit.exe differ
diff --git a/ext/wingit/wingit.dll b/ext/wingit/wingit.dll
deleted file mode 100644 (file)
index d29c333..0000000
Binary files a/ext/wingit/wingit.dll and /dev/null differ
diff --git a/ext/wingit/wingit.h b/ext/wingit/wingit.h
deleted file mode 100644 (file)
index 8794c3f..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-// wingit.h\r
-//\r
-// Windows GIT wrapper (under msysgit)\r
-//\r
-// This is NOT a full git API, it only exposes a few helper functions that\r
-// third party windows apps might find useful, to avoid having to parse\r
-// console output from the command-line tools.\r
-//\r
-// Make sure wingit.dll is placed in the bin directory of the msysgit installation.\r
-//\r
-// Created by Georg Fischer\r
-\r
-#ifndef _WINGIT_H_\r
-#define _WINGIT_H_\r
-\r
-#define WG_VERSION "0.1.7"\r
-\r
-\r
-#define DLLIMPORT __declspec(dllimport) __stdcall\r
-#define DLLEXPORT __declspec(dllexport) __stdcall\r
-\r
-#ifdef WINGIT_EXPORTS\r
-#define WINGIT_API DLLEXPORT\r
-#else // GAME_EXPORTS\r
-#define WINGIT_API DLLIMPORT\r
-#endif // GAME_EXPORTS\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-// Flags for wgEnumFiles\r
-enum WGENUMFILEFLAGS\r
-{\r
-       WGEFF_NoRecurse         = (1<<0),       // only enumerate files directly in the specified path\r
-       WGEFF_FullPath          = (1<<1),       // enumerated filenames are specified with full path (instead of relative to proj root)\r
-       WGEFF_DirStatusDelta= (1<<2),   // include directories, in enumeration, that have a recursive status != WGFS_Normal (may have a slightly better performance than WGEFF_DirStatusAll)\r
-       WGEFF_DirStatusAll      = (1<<3),       // include directories, in enumeration, with recursive status\r
-       WGEFF_EmptyAsNormal     = (1<<4),       // report sub-directories, with no versioned files, as WGFS_Normal instead of WGFS_Empty\r
-       WGEFF_SingleFile        = (1<<5)        // indicates that the status of a single file or dir, specified by pszSubPath, is wanted\r
-};\r
-\r
-// NOTE: Special behavior for directories when specifying WGEFF_SingleFile:\r
-//\r
-//       * when combined with WGEFF_SingleFile the returned status will only reflect the immediate files in the dir,\r
-//         NOT the recusrive status of immediate sub-dirs\r
-//       * unlike a normal enumeration where the project root dir always is returned as WGFS_Normal regardless\r
-//         of WGEFF_EmptyAsNormal, the project root will return WGFS_Empty if no immediate versioned files\r
-//         unless WGEFF_EmptyAsNormal is specified\r
-//       * WGEFF_DirStatusDelta and WGEFF_DirStatusAll are ignored and can be omitted even for dirs\r
-\r
-\r
-// File status\r
-enum WGFILESTATUS\r
-{\r
-       WGFS_Normal,\r
-       WGFS_Modified,\r
-       //WGFS_Staged,\r
-       //WGFS_Added,\r
-       WGFS_Conflicted,\r
-       WGFS_Deleted,\r
-\r
-       WGFS_Unknown = -1,\r
-       WGFS_Empty = -2\r
-};\r
-\r
-\r
-// File flags\r
-enum WGFILEFLAGS\r
-{\r
-       WGFF_Directory          = (1<<0)        // enumerated file is a directory\r
-};\r
-\r
-\r
-struct wgFile_s\r
-{\r
-       const char *sFileName;                  // filename or directory relative to project root (using forward slashes)\r
-       int nStatus;                                    // the WGFILESTATUS of the file\r
-       int nFlags;                                             // a combination of WGFILEFLAGS\r
-\r
-       const BYTE* sha1;                               // points to the BYTE[20] sha1 (NULL for directories, WGFF_Directory)\r
-};\r
-\r
-\r
-// Application-defined callback function for wgEnumFiles, returns TRUE to abort enumeration\r
-// NOTE: do NOT store the pFile pointer or any pointers in wgFile_s for later use, the data is only valid for a single callback call\r
-typedef BOOL (__cdecl WGENUMFILECB)(const struct wgFile_s *pFile, void *pUserData);\r
-\r
-\r
-// Init git framework\r
-BOOL WINGIT_API wgInit(void);\r
-\r
-// Get the lib version\r
-LPCSTR WINGIT_API wgGetVersion(void);\r
-\r
-// Get the git version that is used in this lib\r
-LPCSTR WINGIT_API wgGetGitVersion(void);\r
-\r
-// Enumerate files in a git project\r
-// Ex: wgEnumFiles("C:\\Projects\\MyProject", "src/core", WGEFF_NoRecurse, MyEnumFunc, NULL)\r
-BOOL WINGIT_API wgEnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData);\r
-\r
-// Get the SHA1 of pszName (NULL is same as "HEAD", "HEAD^" etc. expression allowed), returns NULL on failure\r
-// NOTE: do not store returned pointer for later used, data must be used/copied right away before further wg calls\r
-LPBYTE WINGIT_API wgGetRevisionID(const char *pszProjectPath, const char *pszName);\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif\r
diff --git a/ext/wingit/wingit.lib b/ext/wingit/wingit.lib
deleted file mode 100644 (file)
index fdb1784..0000000
Binary files a/ext/wingit/wingit.lib and /dev/null differ
index 1bb0531..6208576 100644 (file)
@@ -99,6 +99,8 @@ static BOOL FindGitPath()
                if ( FileExists(buf) )\r
                {\r
                        // dir found\r
+                       pfin[1] = 0;\r
+                       CGit::ms_LastMsysGitDir = buf;\r
                        return TRUE;\r
                }\r
        }\r
@@ -112,31 +114,17 @@ static BOOL FindGitPath()
 \r
 CString CGit::ms_LastMsysGitDir;\r
 CGit g_Git;\r
-BOOL g_IsWingitDllload = TRUE;\r
 \r
-LPBYTE wgGetRevisionID_safe(const char *pszProjectPath, const char *pszName)\r
-{\r
-       //if(g_IsWingitDllload)\r
-       //      return wgGetRevisionID(pszProjectPath,pszName);\r
-       //else\r
-       return NULL;\r
-}\r
+// contains system environment that should be used by child processes (RunAsync)\r
+// initialized by CheckMsysGitDir\r
+static LPTSTR l_processEnv = NULL;\r
 \r
-BOOL wgEnumFiles_safe(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData)\r
-{\r
-       //if(g_IsWingitDllload)\r
-       //      return wgEnumFiles(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
-       //else\r
-       //      return g_Git.EnumFiles(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
-       return FALSE;\r
-}\r
 \r
 BOOL CGit::IsVista()\r
 {\r
 \r
        if( CRegStdWORD(_T("Software\\TortoiseGit\\CacheType") ) == 0)\r
        {\r
-               g_IsWingitDllload=FALSE;\r
                return TRUE;\r
        }\r
 \r
@@ -154,40 +142,12 @@ BOOL CGit::IsVista()
                return FALSE;\r
 }\r
 \r
-static void InitWinGitDll()\r
-{\r
-       __try\r
-       {\r
-\r
-               if( CGit::IsVista () )\r
-               {\r
-                       g_IsWingitDllload=FALSE;\r
-                       return;\r
-               }\r
-               if ( !wgInit() )\r
-               {\r
-                               // TODO\r
-               }\r
-       }\r
-       __except(1)\r
-       {\r
-               g_IsWingitDllload=FALSE;\r
-               return;\r
-       }\r
-\r
-}\r
 CGit::CGit(void)\r
 {\r
-#if 0\r
        GetCurrentDirectory(MAX_DIRBUFFER,m_CurrentDir.GetBuffer(MAX_DIRBUFFER));\r
        m_CurrentDir.ReleaseBuffer();\r
-       // make sure git/bin is in PATH before wingit.dll gets (delay) loaded by wgInit()\r
-       if ( !CheckMsysGitDir() )\r
-       {\r
-               // TODO\r
-       }\r
-       InitWinGitDll();\r
-#endif\r
+\r
+       CheckMsysGitDir();\r
 }\r
 \r
 CGit::~CGit(void)\r
@@ -230,7 +190,10 @@ int CGit::RunAsync(CString cmd,PROCESS_INFORMATION *piOut,HANDLE *hReadOut,CStri
        si.wShowWindow=SW_HIDE;\r
        si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;\r
 \r
-       if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,NULL,NULL,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))\r
+       LPTSTR pEnv = l_processEnv;\r
+       DWORD dwFlags = pEnv ? CREATE_UNICODE_ENVIRONMENT : 0;\r
+\r
+       if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,dwFlags,pEnv,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))\r
        {\r
                LPVOID lpMsgBuf;\r
                FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,\r
@@ -255,6 +218,9 @@ void CGit::StringAppend(CString *str,BYTE *p,int code,int length)
 {\r
      //USES_CONVERSION;\r
         //str->Append(A2W_CP((LPCSTR)p,code));\r
+       if(str == NULL)\r
+               return ;\r
+\r
        WCHAR * buf;\r
 \r
        int len ;\r
@@ -425,14 +391,14 @@ int CGit::BuildOutputFormat(CString &format,bool IsFull)
        return 0;\r
 }\r
 \r
-int CGit::GetLog(BYTE_VECTOR& logOut, CString &hash,  CTGitPath *path ,int count,int mask)\r
+int CGit::GetLog(BYTE_VECTOR& logOut, CString &hash,  CTGitPath *path ,int count,int mask,CString *from,CString *to)\r
 {\r
        CGitCall_ByteVector gitCall(CString(),&logOut);\r
-       return GetLog(&gitCall,hash,path,count,mask);\r
+       return GetLog(&gitCall,hash,path,count,mask,from,to);\r
 }\r
 \r
 //int CGit::GetLog(CGitCall* pgitCall, CString &hash,  CTGitPath *path ,int count,int mask)\r
-int CGit::GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path, int count, int mask)\r
+int CGit::GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path, int count, int mask,CString *from,CString *to)\r
 {\r
 \r
        CString cmd;\r
@@ -479,6 +445,12 @@ int CGit::GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path, int count,
        if(mask& CGit::LOG_INFO_FOLLOW)\r
                param += _T(" --follow ");\r
 \r
+       if(from != NULL && to != NULL)\r
+       {\r
+               CString range;\r
+               range.Format(_T(" %s..%s "),*from,*to);\r
+               param += range;\r
+       }\r
        param+=hash;\r
 \r
        cmd.Format(_T("git.exe log %s -z --topo-order %s --parents --pretty=format:\""),\r
@@ -598,8 +570,6 @@ int CGit::RunLogFile(CString cmd,CString &filename)
 \r
 git_revnum_t CGit::GetHash(CString &friendname)\r
 {\r
-       // NOTE: could replace this with wgGetRevisionID call\r
-\r
        CString cmd;\r
        CString out;\r
        cmd.Format(_T("git.exe rev-parse %s" ),friendname);\r
@@ -787,6 +757,7 @@ BOOL CGit::CheckMsysGitDir()
 \r
        _tputenv_s(_T("PATH"),path);\r
 \r
+       CString sOldPath = oldpath;\r
        free(oldpath);\r
 \r
 \r
@@ -796,6 +767,12 @@ BOOL CGit::CheckMsysGitDir()
        }\r
        else\r
        {\r
+#ifdef _TORTOISESHELL\r
+               l_processEnv = GetEnvironmentStrings();\r
+               // updated environment is now duplicated for use in CreateProcess, restore original PATH for current process\r
+               _tputenv_s(_T("PATH"),sOldPath);\r
+#endif\r
+\r
                bInitialized = TRUE;\r
                return true;\r
        }\r
@@ -823,70 +800,97 @@ public:
        void *                  m_pUserData;\r
 \r
        BYTE_VECTOR             m_DataCollector;\r
-       TStrCharMap             m_FileStatus;\r
 \r
        virtual bool    OnOutputData(const BYTE* data, size_t size)\r
        {\r
                m_DataCollector.append(data,size);\r
                while(true)\r
                {\r
-                       int found=m_DataCollector.findData((const BYTE*)"\n",1);\r
+                       // lines from igit.exe are 0 terminated\r
+                       int found=m_DataCollector.findData((const BYTE*)"",1);\r
                        if(found<0)\r
                                return false;\r
-                       CStringA line;\r
-                       char* pline=line.GetBuffer(found+1);\r
-                       memcpy(pline,&*m_DataCollector.begin(),found);\r
-                       pline[found]='\0';\r
-                       line.ReleaseBuffer();\r
-                       OnSingleLine(line);\r
-                       m_DataCollector.erase(m_DataCollector.begin(),m_DataCollector.begin()+found+1);\r
+                       OnSingleLine( (LPCSTR)&*m_DataCollector.begin() );\r
+                       m_DataCollector.erase(m_DataCollector.begin(), m_DataCollector.begin()+found+1);\r
                }\r
                return false;//Should never reach this\r
        }\r
        virtual void    OnEnd()\r
        {\r
-               for(TStrCharMap::iterator itFileStatus=m_FileStatus.begin();itFileStatus!=m_FileStatus.end();++itFileStatus)\r
-               {\r
-                       wgFile_s fileStatus;\r
-                       fileStatus.sFileName=itFileStatus->first;\r
-                       switch(itFileStatus->second)\r
-                       {\r
-                       case 'C':       fileStatus.nStatus=WGFS_Modified;break;\r
-                       case 'H':       fileStatus.nStatus=WGFS_Normal;break;\r
-                       case 'R':       fileStatus.nStatus=WGFS_Deleted;break;\r
-                       case '?':       fileStatus.nStatus=WGFS_Empty;break;//Other?\r
-                       case 'K'://Todo: Killed?\r
-                       case 'M'://Todo: What to do with this state? WGFS_Conflicted?\r
-                       default://Unexpected status. Show as normal.\r
-                               fileStatus.nStatus=WGFS_Normal;\r
-                       }\r
-                       fileStatus.sha1=NULL;//Unknown with this call\r
-                       fileStatus.nFlags=0;//Never a directory with this call. Git doesnt track directories as such.\r
-                       (*m_pEnumCb)(&fileStatus,m_pUserData);\r
-               }\r
        }\r
-       bool OnSingleLine(CStringA line)\r
+\r
+       UINT HexChar(char ch)\r
        {\r
-               //Parse single line\r
-               int space=line.Find(' ');\r
-               if(space<0)\r
-                       return false;\r
-               char status=line[0];\r
-               CStringA path=line;\r
-               path=path.Mid(space+1);\r
-               m_FileStatus[path]=status;\r
-               return true;\r
+               if (ch >= '0' && ch <= '9')\r
+                       return (UINT)(ch - '0');\r
+               else if (ch >= 'A' && ch <= 'F')\r
+                       return (UINT)(ch - 'A') + 10;\r
+               else if (ch >= 'a' && ch <= 'f')\r
+                       return (UINT)(ch - 'a') + 10;\r
+               else\r
+                       return 0;\r
        }\r
 \r
+       bool OnSingleLine(LPCSTR line)\r
+       {\r
+               //Parse single line\r
+\r
+               wgFile_s fileStatus;\r
+\r
+               // file/dir type\r
+\r
+               fileStatus.nFlags = 0;\r
+               if (*line == 'D')\r
+                       fileStatus.nFlags |= WGFF_Directory;\r
+               line += 2;\r
 \r
+               // status\r
 \r
+               fileStatus.nStatus = WGFS_Unknown;\r
+               switch (*line)\r
+               {\r
+               case 'N': fileStatus.nStatus = WGFS_Normal; break;\r
+               case 'M': fileStatus.nStatus = WGFS_Modified; break;\r
+               case 'S': fileStatus.nStatus = WGFS_Staged; break;\r
+               case 'A': fileStatus.nStatus = WGFS_Added; break;\r
+               case 'C': fileStatus.nStatus = WGFS_Conflicted; break;\r
+               case 'D': fileStatus.nStatus = WGFS_Deleted; break;\r
+               case 'I': fileStatus.nStatus = WGFS_Ignored; break;\r
+               case 'U': fileStatus.nStatus = WGFS_Unversioned; break;\r
+               case 'E': fileStatus.nStatus = WGFS_Empty; break;\r
+               }\r
+               line += 2;\r
+\r
+               // file sha1\r
 \r
+               BYTE sha1[20];\r
+               fileStatus.sha1 = NULL;\r
+               if ( !(fileStatus.nFlags & WGFF_Directory) )\r
+               {\r
+                       for (int i=0; i<20; i++)\r
+                       {\r
+                               sha1[i] = (HexChar(line[0]) << 8) | HexChar(line[1]);\r
+                               line += 2;\r
+                       }\r
+\r
+                       line++;\r
+               }\r
+\r
+               // filename\r
+               fileStatus.sFileName = line;\r
+\r
+               if ( (*m_pEnumCb)(&fileStatus,m_pUserData) )\r
+                       return false;\r
+\r
+               return true;\r
+       }\r
 };\r
 \r
 BOOL CGit::EnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData)\r
 {\r
-       if(*pszProjectPath=='\0')\r
+       if(!pszProjectPath || *pszProjectPath=='\0')\r
                return FALSE;\r
+\r
        CGitCall_EnumFiles W_GitCall(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
        CString cmd;\r
 \r
@@ -899,8 +903,77 @@ BOOL CGit::EnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigne
        GetCurrentDirectoryA(sizeof(W_szToDir)-1,W_szToDir);\r
 */\r
        SetCurrentDir(CUnicodeUtils::GetUnicode(pszProjectPath));\r
-       cmd.Format(_T("git.exe ls-files -t -c -d -m"));// -- %s"),CUnicodeUtils::GetUnicode(pszProjectPath));\r
+\r
+       CString sMode;\r
+       if (nFlags)\r
+       {\r
+               if (nFlags & WGEFF_NoRecurse) sMode += _T("r");\r
+               if (nFlags & WGEFF_FullPath) sMode += _T("f");\r
+               if (nFlags & WGEFF_DirStatusDelta) sMode += _T("d");\r
+               if (nFlags & WGEFF_DirStatusAll) sMode += _T("D");\r
+               if (nFlags & WGEFF_EmptyAsNormal) sMode += _T("e");\r
+               if (nFlags & WGEFF_SingleFile) sMode += _T("s");\r
+       }\r
+       else\r
+       {\r
+               sMode = _T("-");\r
+       }\r
+\r
+       if (pszSubPath)\r
+               cmd.Format(_T("igit.exe \"%s\" status %s \"%s\""), CUnicodeUtils::GetUnicode(pszProjectPath), sMode, CUnicodeUtils::GetUnicode(pszSubPath));\r
+       else\r
+               cmd.Format(_T("igit.exe \"%s\" status %s"), CUnicodeUtils::GetUnicode(pszProjectPath), sMode);\r
+\r
        W_GitCall.SetCmd(cmd);\r
-       Run(&W_GitCall);\r
+       // NOTE: should igit get added as a part of msysgit then use below line instead of the above one\r
+       //W_GitCall.SetCmd(CGit::ms_LastMsysGitDir + cmd);\r
+\r
+       if ( Run(&W_GitCall) )\r
+               return FALSE;\r
+\r
        return TRUE;\r
 }\r
+\r
+BOOL CGit::CheckCleanWorkTree()\r
+{\r
+       CString out;\r
+       CString cmd;\r
+       cmd=_T("git.exe rev-parse --verify HEAD");\r
+\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               return FALSE;\r
+\r
+       cmd=_T("git.exe update-index --ignore-submodules --refresh");\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               return FALSE;\r
+\r
+       cmd=_T("git.exe diff-files --quiet --ignore-submodules");\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               return FALSE;\r
+\r
+       cmd=_T("git diff-index --cached --quiet HEAD --ignore-submodules");\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               return FALSE;\r
+\r
+       return TRUE;\r
+}\r
+\r
+int CGit::ListConflictFile(CTGitPathList &list,CTGitPath *path)\r
+{\r
+       BYTE_VECTOR vector;\r
+\r
+       CString cmd;\r
+       if(path)\r
+               cmd.Format(_T("git.exe ls-files -u -t -z -- \"%s\""),path->GetGitPathString());\r
+       else\r
+               cmd=_T("git.exe ls-files -u -t -z");\r
+\r
+       if(g_Git.Run(cmd,&vector))\r
+       {\r
+               return -1;\r
+       }\r
+\r
+       list.ParserFromLsFile(vector);\r
+\r
+       return 0;\r
+}
\ No newline at end of file
index 632ddb3..856c71c 100644 (file)
@@ -47,6 +47,7 @@ public:
        CString GetUserName(void);\r
        CString GetUserEmail(void);\r
        CString GetCurrentBranch(void);\r
+       BOOL CheckCleanWorkTree();\r
 \r
        bool SetCurrentDir(CString path)\r
        {\r
@@ -84,8 +85,10 @@ public:
        \r
        //hash is empty means all. -1 means all\r
 \r
-       int GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME);\r
-       int GetLog(BYTE_VECTOR& logOut,CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME);\r
+       int GetLog(CGitCall* pgitCall, CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME,\r
+                                                               CString *from=NULL,CString *to=NULL);\r
+       int GetLog(BYTE_VECTOR& logOut,CString &hash, CTGitPath *path = NULL,int count=-1,int InfoMask=LOG_INFO_STAT|LOG_INFO_FILESTATE|LOG_INFO_BOUNDARY|LOG_INFO_DETECT_COPYRENAME,\r
+                                                               CString *from=NULL,CString *to=NULL);\r
 \r
        BOOL EnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData);\r
 \r
@@ -97,6 +100,7 @@ public:
 \r
        BOOL IsInitRepos();\r
        static BOOL IsVista();\r
+       int ListConflictFile(CTGitPathList &list,CTGitPath *path=NULL);\r
        \r
 };\r
 extern void GetTempPath(CString &path);\r
@@ -105,5 +109,4 @@ extern CString GetTempFile();
 \r
 extern CGit g_Git;\r
 \r
-extern LPBYTE wgGetRevisionID_safe(const char *pszProjectPath, const char *pszName);\r
-extern BOOL wgEnumFiles_safe(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData);\r
+inline static BOOL wgEnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData) { return g_Git.EnumFiles(pszProjectPath, pszSubPath, nFlags, pEnumCb, pUserData); }\r
index 17f1b3f..507070b 100644 (file)
@@ -116,7 +116,7 @@ const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepa
 //     apr_hash_t *                            statushash;\r
 //     apr_pool_t *                            pool;\r
        //git_error_t *                         err = NULL; // If svn_client_status comes out through catch(...), err would else be unassigned\r
-       BOOL err = FALSE;\r
+       git_error_t err = 0;\r
 \r
        //dont' build the cache if an instance of TortoiseProc is running\r
        //since this could interfere with svn commands running (concurrent\r
@@ -231,40 +231,53 @@ const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepa
 //     rev.kind = git_opt_revision_unspecified;\r
        try\r
        {\r
-               // extract the sub-path (relative to project root)\r
-//MessageBox(NULL, filepath.GetDirectory().GetWinPathString(), sProjectRoot, MB_OK);\r
-//             LPCSTR lpszSubPath = NULL;\r
-               CString sSubPath;\r
-               CString s = filepath.GetWinPathString();\r
-               if (s.GetLength() > sProjectRoot.GetLength())\r
+               if (g_ShellCache.GetCacheType() == ShellCache::dll)\r
                {\r
-                       sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/);\r
-//                     lpszSubPath = sSubPath;\r
+                       // gitindex.h based status\r
+\r
+                       // extract the sub-path (relative to project root)\r
+                       CString sSubPath;\r
+                       CString s = filepath.GetWinPathString();\r
+                       if (s.GetLength() > sProjectRoot.GetLength())\r
+                       {\r
+                                       sSubPath = s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/);\r
+                       }\r
+\r
+                       git_wc_status_kind status;\r
+\r
+                       err = g_IndexFileMap.GetFileStatus((CString&)sProjectRoot,sSubPath,&status,true,true,fillstatusmap_idx,this);\r
                }\r
+               else\r
+               {\r
+                       // extract the sub-path (relative to project root)\r
+//MessageBox(NULL, filepath.GetDirectory().GetWinPathString(), sProjectRoot, MB_OK);\r
+                       LPCSTR lpszSubPath = NULL;\r
+                       CStringA sSubPath;\r
+                       CString s = filepath.GetDirectory().GetWinPathString();\r
+                       if (s.GetLength() > sProjectRoot.GetLength())\r
+                       {\r
+                               sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+                               lpszSubPath = sSubPath;\r
+                       }\r
 \r
 //if (lpszSubPath) MessageBoxA(NULL, lpszSubPath, "BuildCache", MB_OK);\r
 //MessageBoxA(NULL, CStringA(sProjectRoot), sSubPath, MB_OK);\r
-               //err = !wgEnumFiles_safe(CStringA(sProjectRoot), lpszSubPath, WGEFF_NoRecurse|WGEFF_FullPath|WGEFF_DirStatusAll, &fillstatusmap, this);\r
-               //CTGitPath path;\r
-               //path.SetFromWin(sSubPath);\r
-               git_wc_status_kind status;\r
-\r
-               err = g_IndexFileMap.GetFileStatus((CString&)sProjectRoot,sSubPath,&status,true,true,fillstatusmap,this);\r
-               \r
-               //err = g_IndexFileMap.GetFileStatus(sProjectRoot,&path,\r
-               /*err = svn_client_status4 (&youngest,\r
-                       filepath.GetDirectory().GetSVNApiPath(pool),\r
-                       &rev,\r
-                       fillstatusmap,\r
-                       this,\r
-                       svn_depth_immediates,           //depth\r
-                       TRUE,           //getall\r
-                       FALSE,          //update\r
-                       TRUE,           //noignore\r
-                       FALSE,          //ignore externals\r
-                       NULL,\r
-                       localctx,\r
-                       pool);*/\r
+                       err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, WGEFF_NoRecurse|WGEFF_FullPath|WGEFF_DirStatusAll, &fillstatusmap, this);\r
+\r
+                       /*err = svn_client_status4 (&youngest,\r
+                               filepath.GetDirectory().GetSVNApiPath(pool),\r
+                               &rev,\r
+                               fillstatusmap,\r
+                               this,\r
+                               svn_depth_immediates,           //depth\r
+                               TRUE,           //getall\r
+                               FALSE,          //update\r
+                               TRUE,           //noignore\r
+                               FALSE,          //ignore externals\r
+                               NULL,\r
+                               localctx,\r
+                               pool);*/\r
+               }\r
        }\r
        catch ( ... )\r
        {\r
@@ -405,7 +418,48 @@ const FileStatusCacheEntry * GitFolderStatus::GetCachedItem(const CTGitPath& fil
        return NULL;\r
 }\r
 \r
-void GitFolderStatus::fillstatusmap(CString &path,git_wc_status_kind status,void *pUserData)\r
+BOOL GitFolderStatus::fillstatusmap(const struct wgFile_s *pFile, void *pUserData)\r
+{\r
+       GitFolderStatus *Stat = (GitFolderStatus*)pUserData;\r
+\r
+       FileStatusMap &cache = Stat->m_cache;\r
+       FileStatusCacheEntry s;\r
+       s.needslock = false;\r
+       s.tree_conflict = false;\r
+\r
+       s.author = Stat->authors.GetString(NULL);\r
+       s.url = Stat->urls.GetString(NULL);\r
+       if (pFile->sha1)\r
+               s.rev = ConvertHashToRevnum(pFile->sha1);\r
+       s.owner = Stat->owners.GetString(NULL);\r
+\r
+       s.status = git_wc_status_none;\r
+\r
+       //s.status = GitStatus::GetMoreImportant(s.status, status->text_status);\r
+       //s.status = GitStatus::GetMoreImportant(s.status, status->prop_status);\r
+       s.status = GitStatusFromWingit(pFile->nStatus);\r
+\r
+       // TODO ?: s.blaha = pFile->nStage\r
+\r
+       //s.lock = status->repos_lock;\r
+       //s.tree_conflict = (status->tree_conflict != NULL);\r
+\r
+       s.askedcounter = GITFOLDERSTATUS_CACHETIMES;\r
+       stdstring str;\r
+       if (pFile->sFileName)\r
+       {\r
+               str = CUnicodeUtils::StdGetUnicode(pFile->sFileName);\r
+               std::replace(str.begin(), str.end(), '/', '\\');\r
+//MessageBox(NULL, str.c_str(), _T(""), MB_OK);\r
+       }\r
+       else\r
+               str = _T(" ");\r
+       cache[str] = s;\r
+\r
+       return FALSE;\r
+}\r
+\r
+void GitFolderStatus::fillstatusmap_idx(CString &path,git_wc_status_kind status,void *pUserData)\r
 {\r
        GitFolderStatus *Stat = (GitFolderStatus*)pUserData;\r
 \r
index dba9f4f..646d7f3 100644 (file)
@@ -78,7 +78,7 @@ typedef struct FileStatusCacheEntry
        const char*                             url;            ///< points to a (possibly) shared value\r
        const char*                             owner;          ///< points to a (possible) lock owner\r
        bool                                    needslock;\r
-       //git_revnum_t                  rev;\r
+       git_revnum_t                    rev;\r
        int                                             askedcounter;\r
        //git_lock_t *                  lock;\r
        bool                                    tree_conflict;\r
@@ -117,7 +117,8 @@ private:
        DWORD                           GetTimeoutValue();\r
        //static git_error_t*   fillstatusmap (void *baton, const char *path, git_wc_status2_t *status, apr_pool_t *pool);\r
        //static git_error_t*   findfolderstatus (void *baton, const char *path, git_wc_status2_t *status, apr_pool_t *pool);\r
-       static void                     fillstatusmap(CString &path,git_wc_status_kind status,void *pdata);\r
+       static BOOL                     fillstatusmap(const struct wgFile_s *pFile, void *pUserData);\r
+       static void                     fillstatusmap_idx(CString &path,git_wc_status_kind status,void *pdata);\r
 \r
        static CTGitPath        folderpath;\r
        void                            ClearCache();\r
index 9aeca87..c2032a8 100644 (file)
 //\r
 \r
 #include "stdafx.h"\r
+#ifdef _TORTOISESHELL\r
+#include "ShellExt.h"\r
+#else\r
+#include "registry.h"\r
+#endif\r
 //#include "resource.h"\r
 #include "..\TortoiseShell\resource.h"\r
 //#include "git_config.h"\r
@@ -217,35 +222,52 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t de
 \r
        const BOOL bIsRecursive = (depth == git_depth_infinity || depth == git_depth_unknown); // taken from SVN source\r
 \r
-       //LPCSTR lpszSubPath = NULL;\r
-       CString sSubPath;\r
-       CString s = path.GetWinPathString();\r
-       if (s.GetLength() > sProjectRoot.GetLength())\r
+#ifdef _TORTOISESHELL\r
+       if (g_ShellCache.GetCacheType() == ShellCache::dll)\r
+#else\r
+       if ((DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\CacheType"), GetSystemMetrics(SM_REMOTESESSION) ? 2 : 1) == 2)\r
+#endif\r
        {\r
-               sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
-       //      lpszSubPath = sSubPath;\r
+               // gitindex.h based status\r
+\r
+               CString sSubPath;\r
+               CString s = path.GetWinPathString();\r
+               if (s.GetLength() > sProjectRoot.GetLength())\r
+               {\r
+                       sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+               }\r
+\r
+               err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&statuskind);\r
        }\r
+       else\r
+       {\r
+               LPCSTR lpszSubPath = NULL;\r
+               CStringA sSubPath;\r
+               CString s = path.GetWinPathString();\r
+               if (s.GetLength() > sProjectRoot.GetLength())\r
+               {\r
+                       sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+                       lpszSubPath = sSubPath;\r
+               }\r
 \r
 #if 1\r
-       // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here\r
-       //UINT nFlags = WGEFF_SingleFile;\r
-       //if (!bIsRecursive)\r
-       //      nFlags |= WGEFF_NoRecurse;\r
-       //if (!lpszSubPath)\r
-               // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?)\r
-       //      nFlags |= WGEFF_EmptyAsNormal;\r
+               // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here\r
+               UINT nFlags = WGEFF_SingleFile;\r
+               if (!bIsRecursive)\r
+                       nFlags |= WGEFF_NoRecurse;\r
+               if (!lpszSubPath)\r
+                       // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?)\r
+                       nFlags |= WGEFF_EmptyAsNormal;\r
 #else\r
-       // enumerate all files, recursively if requested\r
-       UINT nFlags = 0;\r
-       if (!bIsRecursive)\r
-               nFlags |= WGEFF_NoRecurse;\r
+               // enumerate all files, recursively if requested\r
+               UINT nFlags = 0;\r
+               if (!bIsRecursive)\r
+                       nFlags |= WGEFF_NoRecurse;\r
 #endif\r
 \r
-       //err = !wgEnumFiles_safe(CStringA(sProjectRoot), lpszSubPath, nFlags, &getallstatus, &statuskind);\r
-       \r
-       err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&statuskind);\r
+               err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, nFlags, &getallstatus, &statuskind);\r
 \r
-       /*err = git_client_status4 (&youngest,\r
+               /*err = git_client_status4 (&youngest,\r
                                                        path.GetSVNApiPath(pool),\r
                                                        &rev,\r
                                                        getallstatus,\r
@@ -258,6 +280,7 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, git_depth_t de
                                                        NULL,\r
                                                        ctx,\r
                                                        pool);*/\r
+       }\r
 \r
        // Error present\r
        if (err != NULL)\r
@@ -348,30 +371,48 @@ git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false
 //     hashbaton.exthash = exthash;\r
        hashbaton.pThis = this;\r
 \r
-       //LPCSTR lpszSubPath = NULL;\r
-       CString sSubPath;\r
-       CString s = path.GetWinPathString();\r
-       if (s.GetLength() > sProjectRoot.GetLength())\r
+#ifdef _TORTOISESHELL\r
+       if (g_ShellCache.GetCacheType() == ShellCache::dll)\r
+#else\r
+       if ((DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\CacheType"), GetSystemMetrics(SM_REMOTESESSION) ? 2 : 1) == 2)\r
+#endif\r
        {\r
-               sSubPath = CString(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
-       //      lpszSubPath = sSubPath;\r
+               // gitindex.h based status\r
+\r
+               CString sSubPath;\r
+               CString s = path.GetWinPathString();\r
+               if (s.GetLength() > sProjectRoot.GetLength())\r
+               {\r
+                       sSubPath = CString(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+               }\r
+\r
+               m_status.prop_status = m_status.text_status = git_wc_status_none;\r
+\r
+               m_err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&m_status.text_status);\r
        }\r
+       else\r
+       {\r
+               LPCSTR lpszSubPath = NULL;\r
+               CStringA sSubPath;\r
+               CString s = path.GetWinPathString();\r
+               if (s.GetLength() > sProjectRoot.GetLength())\r
+               {\r
+                       sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+                       lpszSubPath = sSubPath;\r
+               }\r
 \r
-       \r
-       // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here\r
-       //UINT nFlags = WGEFF_SingleFile | WGEFF_NoRecurse;\r
-       //if (!lpszSubPath)\r
-       //      // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?)\r
-       //      nFlags |= WGEFF_EmptyAsNormal;\r
+               // when recursion enabled, let wingit determine the recursive status for folders instead of enumerating all files here\r
+               UINT nFlags = WGEFF_SingleFile | WGEFF_NoRecurse;\r
+               if (!lpszSubPath)\r
+                       // report root dir as normal (otherwise it could be considered git_wc_status_unversioned, which would be wrong?)\r
+                       nFlags |= WGEFF_EmptyAsNormal;\r
 \r
-       m_status.prop_status = m_status.text_status = git_wc_status_none;\r
+               m_status.prop_status = m_status.text_status = git_wc_status_none;\r
 \r
-       // NOTE: currently wgEnumFiles_safe_safe_safe will not enumerate file if it isn't versioned (so status will be git_wc_status_none)\r
-       //m_err = !wgEnumFiles_safe(CStringA(sProjectRoot), lpszSubPath, nFlags, &getstatus, &m_status);\r
+               // NOTE: currently wgEnumFiles will not enumerate file if it isn't versioned (so status will be git_wc_status_none)\r
+               m_err = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, nFlags, &getstatus, &m_status);\r
 \r
-       m_err = g_IndexFileMap.GetFileStatus(sProjectRoot,sSubPath,&m_status.text_status);\r
-       \r
-       /*m_err = git_client_status4 (&youngest,\r
+               /*m_err = git_client_status4 (&youngest,\r
                                                        path.GetGitApiPath(m_pool),\r
                                                        &rev,\r
                                                        getstatushash,\r
@@ -384,7 +425,7 @@ git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false
                                                        NULL,\r
                                                        ctx,\r
                                                        m_pool);*/\r
-\r
+       }\r
 \r
        // Error present if function is not under version control\r
        if (m_err) /*|| (apr_hash_count(statushash) == 0)*/\r
@@ -407,9 +448,9 @@ git_revnum_t GitStatus::GetStatus(const CTGitPath& path, bool update /* = false
 \r
        if (update)\r
        {\r
-               //const BYTE *sha1 = wgGetRevisionID_safe(CStringA(sProjectRoot), NULL);\r
-               //if (sha1)\r
-               //      youngest = ConvertHashToRevnum(sha1);\r
+               // done to match TSVN functionality of this function (not sure if any code uses the reutrn val)\r
+               // if TGit does not need this, then change the return type of function\r
+               youngest = g_Git.GetHash(CString(_T("HEAD")));\r
        }\r
 \r
        return youngest;\r
index 9e16536..aa21fa3 100644 (file)
@@ -15,7 +15,6 @@ typedef std::basic_string<wchar_t> wide_string;
 #pragma warning (pop)\r
 \r
 #include "TGitPath.h"\r
-#include "../../ext/wingit/wingit.h"\r
 \r
 typedef enum type_git_wc_status_kind\r
 {\r
@@ -51,6 +50,15 @@ typedef enum
 typedef CString git_revnum_t;\r
 typedef int git_error_t;\r
 \r
+typedef struct git_wc_entry_t\r
+{\r
+       // url in repository\r
+       const char *url;\r
+\r
+       TCHAR cmt_rev[41];\r
+} git_wc_entry_t;\r
+\r
+\r
 typedef struct git_wc_status2_t\r
 { \r
   /** The status of the entries text. */\r
@@ -58,11 +66,66 @@ typedef struct git_wc_status2_t
 \r
   /** The status of the entries properties. */\r
   git_wc_status_kind prop_status;\r
+\r
+  //git_wc_entry_t *entry;\r
 }git_wc_status2;\r
 \r
 #define MAX_STATUS_STRING_LENGTH               256\r
 \r
 \r
+/////////////////////////////////////////////////////////////////////\r
+// WINGIT API (replaced by commandline tool, but defs and data types kept so old code still works)\r
+\r
+// Flags for wgEnumFiles\r
+enum WGENUMFILEFLAGS\r
+{\r
+       WGEFF_NoRecurse         = (1<<0),       // only enumerate files directly in the specified path\r
+       WGEFF_FullPath          = (1<<1),       // enumerated filenames are specified with full path (instead of relative to proj root)\r
+       WGEFF_DirStatusDelta= (1<<2),   // include directories, in enumeration, that have a recursive status != WGFS_Normal (may have a slightly better performance than WGEFF_DirStatusAll)\r
+       WGEFF_DirStatusAll      = (1<<3),       // include directories, in enumeration, with recursive status\r
+       WGEFF_EmptyAsNormal     = (1<<4),       // report sub-directories, with no versioned files, as WGFS_Normal instead of WGFS_Empty\r
+       WGEFF_SingleFile        = (1<<5)        // indicates that the status of a single file or dir, specified by pszSubPath, is wanted\r
+};\r
+\r
+// File status\r
+enum WGFILESTATUS\r
+{\r
+       WGFS_Normal,\r
+       WGFS_Modified,\r
+       WGFS_Staged,\r
+       WGFS_Added,\r
+       WGFS_Conflicted,\r
+       WGFS_Deleted,\r
+\r
+       WGFS_Ignored = -1,\r
+       WGFS_Unversioned = -2,\r
+       WGFS_Empty = -3,\r
+       WGFS_Unknown = -4\r
+};\r
+\r
+// File flags\r
+enum WGFILEFLAGS\r
+{\r
+       WGFF_Directory          = (1<<0)        // enumerated file is a directory\r
+};\r
+\r
+struct wgFile_s\r
+{\r
+       const char *sFileName;                  // filename or directory relative to project root (using forward slashes)\r
+       int nStatus;                                    // the WGFILESTATUS of the file\r
+       int nFlags;                                             // a combination of WGFILEFLAGS\r
+\r
+       const BYTE* sha1;                               // points to the BYTE[20] sha1 (NULL for directories, WGFF_Directory)\r
+};\r
+\r
+// Application-defined callback function for wgEnumFiles, returns TRUE to abort enumeration\r
+// NOTE: do NOT store the pFile pointer or any pointers in wgFile_s for later use, the data is only valid for a single callback call\r
+typedef BOOL (__cdecl WGENUMFILECB)(const struct wgFile_s *pFile, void *pUserData);\r
+\r
+//\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+\r
 // convert wingit.dll status to git_wc_status_kind\r
 inline static git_wc_status_kind GitStatusFromWingit(int nStatus)\r
 {\r
@@ -70,11 +133,13 @@ inline static git_wc_status_kind GitStatusFromWingit(int nStatus)
        {\r
        case WGFS_Normal: return git_wc_status_normal;\r
        case WGFS_Modified: return git_wc_status_modified;\r
-       //case WGFS_Staged: return git_wc_status_modified;\r
-       //case WGFS_Added: return git_wc_status_added;\r
+       case WGFS_Staged: return git_wc_status_modified;\r
+       case WGFS_Added: return git_wc_status_added;\r
        case WGFS_Conflicted: return git_wc_status_conflicted;\r
        case WGFS_Deleted: return git_wc_status_deleted;\r
 \r
+       case WGFS_Ignored: return git_wc_status_ignored;\r
+       case WGFS_Unversioned: return git_wc_status_unversioned;\r
        case WGFS_Empty: return git_wc_status_unversioned;\r
        }\r
 \r
index dc19db7..df54196 100644 (file)
@@ -1083,6 +1083,7 @@ void CGitStatusListCtrl::Show(DWORD dwShow, DWORD dwCheck /*=0*/, bool bShowFold
                        m_arStatusArray.push_back((CTGitPath*)&m_IgnoreFileList[i]);\r
                }\r
        }\r
+       int index =0;\r
        for(int i=0;i<this->m_arStatusArray.size();i++)\r
        {\r
                //set default checkbox status\r
@@ -1090,7 +1091,10 @@ void CGitStatusListCtrl::Show(DWORD dwShow, DWORD dwCheck /*=0*/, bool bShowFold
                        ((CTGitPath*)m_arStatusArray[i])->m_Checked=true;\r
 \r
                if(((CTGitPath*)m_arStatusArray[i])->m_Action & dwShow)\r
-                       AddEntry((CTGitPath*)m_arStatusArray[i],langID,i);\r
+               {\r
+                       AddEntry((CTGitPath*)m_arStatusArray[i],langID,index);\r
+                       index++;\r
+               }\r
        }\r
        \r
        int maxcol = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;\r
@@ -1449,7 +1453,7 @@ void CGitStatusListCtrl::AddEntry(CTGitPath * GitPath, WORD langID, int listInde
        // relative path\r
        CString rename;\r
        rename.Format(_T("(from %s)"),GitPath->GetGitOldPathString());\r
-       if(GitPath->m_Action & CTGitPath::LOGACTIONS_REPLACED)\r
+       if(GitPath->m_Action & (CTGitPath::LOGACTIONS_REPLACED|CTGitPath::LOGACTIONS_COPY))\r
                entryname+=rename;\r
        \r
        InsertItem(index, entryname, icon_idx);\r
@@ -2060,7 +2064,7 @@ bool CGitStatusListCtrl::BuildStatistics()
        {\r
                int status=((CTGitPath*)m_arStatusArray[i])->m_Action;\r
 \r
-               if(status&CTGitPath::LOGACTIONS_ADDED)\r
+               if(status&(CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY))\r
                        m_nAdded++;\r
                \r
                if(status&CTGitPath::LOGACTIONS_DELETED)\r
@@ -2228,14 +2232,14 @@ void CGitStatusListCtrl::OnContextMenuGroup(CWnd * /*pWnd*/, CPoint point)
                                                lv.mask = LVIF_GROUPID;\r
                                                lv.iItem = i;\r
                                                GetItem(&lv);\r
-#if 0\r
+\r
                                                if (lv.iGroupId == group)\r
                                                {\r
-                                                       FileEntry * entry = GetListEntry(i);\r
+                                                       CTGitPath * entry = (CTGitPath*)GetItemData(i);\r
                                                        if (entry)\r
                                                        {\r
-                                                               bool bOldCheck = !!GetCheck(i);\r
-                                                               //SetEntryCheck(entry, i, bCheck);\r
+                                                               bool bOldCheck = entry->m_Checked;\r
+                                                               SetEntryCheck(entry, i, bCheck);\r
                                                                if (bCheck != bOldCheck)\r
                                                                {\r
                                                                        if (bCheck)\r
@@ -2245,7 +2249,7 @@ void CGitStatusListCtrl::OnContextMenuGroup(CWnd * /*pWnd*/, CPoint point)
                                                                }\r
                                                        }\r
                                                }\r
-#endif\r
+\r
                                        }\r
                                        GetStatisticsString();\r
                                        NotifyCheck();\r
@@ -4248,7 +4252,7 @@ void CGitStatusListCtrl::StartDiff(int fileindex)
 \r
        CTGitPath file1=*(CTGitPath*)GetItemData(fileindex);\r
        CTGitPath file2;\r
-       if(file1.m_Action & CTGitPath::LOGACTIONS_REPLACED)\r
+       if(file1.m_Action & (CTGitPath::LOGACTIONS_REPLACED|CTGitPath::LOGACTIONS_COPY))\r
        {\r
                file2.SetFromGit(file1.GetGitOldPathString());\r
        }else\r
@@ -4526,11 +4530,11 @@ void CGitStatusListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
                                {\r
                                        crText = m_Colors.GetColor(CColors::Conflict);\r
 \r
-                               }else if(entry->m_Action & CTGitPath::LOGACTIONS_MODIFIED)\r
+                               }else if(entry->m_Action & (CTGitPath::LOGACTIONS_MODIFIED))\r
                                {\r
                                        crText = m_Colors.GetColor(CColors::Modified);\r
 \r
-                               }else if(entry->m_Action & CTGitPath::LOGACTIONS_ADDED)\r
+                               }else if(entry->m_Action & (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY))\r
                                {\r
                                        crText = m_Colors.GetColor(CColors::Added);\r
                                }\r
index cf230ab..13d5733 100644 (file)
@@ -55,8 +55,8 @@
                \r
 #define SVNSLC_SHOWUNVERSIONED CTGitPath::LOGACTIONS_UNVER\r
 #define SVNSLC_SHOWNORMAL              0x000000000\r
-#define SVNSLC_SHOWMODIFIED            CTGitPath::LOGACTIONS_MODIFIED\r
-#define SVNSLC_SHOWADDED               CTGitPath::LOGACTIONS_ADDED\r
+#define SVNSLC_SHOWMODIFIED            (CTGitPath::LOGACTIONS_MODIFIED)\r
+#define SVNSLC_SHOWADDED               (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY)\r
 #define SVNSLC_SHOWREMOVED             CTGitPath::LOGACTIONS_DELETED\r
 #define SVNSLC_SHOWCONFLICTED  CTGitPath::LOGACTIONS_UNMERGED\r
 #define SVNSLC_SHOWMISSING             0x00000000\r
index fceb025..a3ddc54 100644 (file)
@@ -102,6 +102,9 @@ int CTGitPath::ParserAction(BYTE action)
                m_Action|= LOGACTIONS_DELETED;\r
        if(action == 'H')\r
                m_Action|= LOGACTIONS_CACHE;\r
+       if(action == 'C' )\r
+               m_Action|= LOGACTIONS_COPY;\r
+\r
        return m_Action;\r
 }\r
 void CTGitPath::SetFromGit(const char* pPath)\r
@@ -1052,6 +1055,7 @@ int CTGitPathList::ParserFromLog(BYTE_VECTOR &log)
                                        sec++;\r
                                        g_Git.StringAppend(&file1,&log[sec],CP_OEMCP);\r
                                }\r
+                               pos=sec;\r
 \r
                        }else\r
                        {\r
@@ -1861,21 +1865,35 @@ CTGitPath * CTGitPathList::LookForGitPath(CString path)
        }\r
        return NULL;\r
 }\r
-\r
-CString CTGitPath::GetActionName()\r
+CString CTGitPath::GetActionName(int action)\r
 {\r
-       if(m_Action  & CTGitPath::LOGACTIONS_ADDED)\r
+       if(action  & CTGitPath::LOGACTIONS_ADDED)\r
                return _T("Added");\r
-       if(m_Action  & CTGitPath::LOGACTIONS_DELETED)\r
+       if(action  & CTGitPath::LOGACTIONS_DELETED)\r
                return _T("Deleted");\r
-       if(m_Action  & CTGitPath::LOGACTIONS_UNMERGED)\r
+       if(action  & CTGitPath::LOGACTIONS_UNMERGED)\r
                return _T("Conflict");\r
-       if(m_Action  & CTGitPath::LOGACTIONS_MODIFIED)\r
+       if(action  & CTGitPath::LOGACTIONS_MODIFIED)\r
                return _T("Modified");\r
-       if(m_Action  & CTGitPath::LOGACTIONS_REPLACED)\r
+       if(action  & CTGitPath::LOGACTIONS_REPLACED)\r
                return _T("Rename");\r
+       if(action  & CTGitPath::LOGACTIONS_COPY)\r
+               return _T("Copy");\r
+       if(action & CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+               return _T("Edit");\r
+       if(action & CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+               return _T("Squash");\r
+       if(action & CTGitPath::LOGACTIONS_REBASE_PICK)\r
+               return _T("Pick");\r
+       if(action & CTGitPath::LOGACTIONS_REBASE_SKIP)\r
+               return _T("Skip");\r
+\r
        return _T("Unknown");\r
 }\r
+CString CTGitPath::GetActionName()\r
+{\r
+       return GetActionName(m_Action);\r
+}\r
 \r
 int CTGitPathList::GetAction()\r
 {\r
index 01df547..cbb9256 100644 (file)
@@ -17,6 +17,7 @@ public:
                LOGACTIONS_DELETED      = 0x00000008,\r
                LOGACTIONS_UNMERGED = 0x00000010,\r
                LOGACTIONS_CACHE        = 0x00000020,\r
+               LOGACTIONS_COPY         = 0x00000040,\r
                LOGACTIONS_UNVER        = 0x80000000,\r
                LOGACTIONS_IGNORE       = 0x40000000,\r
                //LOGACTIONS_CONFLICT = 0x20000000,\r
@@ -24,6 +25,17 @@ public:
                // For log filter only\r
                LOGACTIONS_HIDE         = 0x20000000,\r
                LOGACTIONS_GRAY         = 0x10000000,\r
+\r
+               // For Rebase only\r
+               LOGACTIONS_REBASE_CURRENT = 0x08000000,\r
+               LOGACTIONS_REBASE_PICK    = 0x04000000,\r
+               LOGACTIONS_REBASE_SQUASH  = 0x02000000,\r
+               LOGACTIONS_REBASE_EDIT    = 0x01000000,\r
+               LOGACTIONS_REBASE_DONE    = 0x00800000,\r
+               LOGACTIONS_REBASE_SKIP    = 0x00400000,\r
+               LOGACTIONS_REBASE_MASK    = 0x0FC00000,\r
+               LOGACTIONS_REBASE_MODE_MASK=0x07C00000,\r
+\r
        };\r
 \r
        CString m_StatAdd;\r
@@ -32,6 +44,7 @@ public:
        bool    m_Checked;\r
        int     ParserAction(BYTE action);\r
        CString GetActionName();\r
+       static CString GetActionName(int action);\r
        /**\r
         * Set the path as an UTF8 string with forward slashes\r
         */\r
index 2d98442..c68f02f 100644 (file)
Binary files a/src/Resources/TortoiseProcENG.rc and b/src/Resources/TortoiseProcENG.rc differ
index fdd886b..705e3d5 100644 (file)
@@ -40,6 +40,17 @@ CString GetCacheMutexName();
 \r
 CString GetCacheID();\r
 \r
+\r
+typedef enum git_node_kind_t\r
+{\r
+       git_node_none,\r
+       git_node_file,\r
+       git_node_dir,\r
+       git_node_unknown,\r
+\r
+}git_node_kind;\r
+\r
+\r
 /**\r
  * \ingroup TSVNCache\r
  * A structure passed as a request from the shell (or other client) to the external cache\r
@@ -61,8 +72,8 @@ struct TSVNCacheRequest
 struct TSVNCacheResponse\r
 {\r
        git_wc_status2_t m_status;\r
-//     svn_wc_entry_t m_entry;\r
-//     svn_node_kind_t m_kind;\r
+       git_wc_entry_t m_entry;\r
+       git_node_kind_t m_kind;\r
        char m_url[INTERNET_MAX_URL_LENGTH+1];\r
        char m_owner[255];              ///< owner of the lock\r
        char m_author[255];\r
index 53fa719..3edd90b 100644 (file)
@@ -25,8 +25,8 @@
 \r
 CCachedDirectory::CCachedDirectory(void)\r
 {\r
-       m_entriesFileTime = 0;\r
-       m_propsFileTime = 0;\r
+       m_indexFileTime = 0;\r
+//     m_propsFileTime = 0;\r
        m_currentStatusFetchingPathTicks = 0;\r
        m_bCurrentFullStatusValid = false;\r
        m_currentFullStatus = m_mostImportantFileStatus = git_wc_status_none;\r
@@ -42,8 +42,8 @@ CCachedDirectory::CCachedDirectory(const CTGitPath& directoryPath)
        ATLASSERT(directoryPath.IsDirectory() || !PathFileExists(directoryPath.GetWinPath()));\r
 \r
        m_directoryPath = directoryPath;\r
-       m_entriesFileTime = 0;\r
-       m_propsFileTime = 0;\r
+       m_indexFileTime = 0;\r
+//     m_propsFileTime = 0;\r
        m_currentStatusFetchingPathTicks = 0;\r
        m_bCurrentFullStatusValid = false;\r
        m_currentFullStatus = m_mostImportantFileStatus = git_wc_status_none;\r
@@ -88,8 +88,8 @@ BOOL CCachedDirectory::SaveToDisk(FILE * pFile)
                        WRITEVALUETOFILE(status);\r
                }\r
        }\r
-       WRITEVALUETOFILE(m_entriesFileTime);\r
-       WRITEVALUETOFILE(m_propsFileTime);\r
+       WRITEVALUETOFILE(m_indexFileTime);\r
+//     WRITEVALUETOFILE(m_propsFileTime);\r
        value = m_directoryPath.GetWinPathString().GetLength();\r
        WRITEVALUETOFILE(value);\r
        if (value)\r
@@ -156,8 +156,8 @@ BOOL CCachedDirectory::LoadFromDisk(FILE * pFile)
                                m_childDirectories[CTGitPath(sPath)] = status;\r
                        }\r
                }\r
-               LOADVALUEFROMFILE(m_entriesFileTime);\r
-               LOADVALUEFROMFILE(m_propsFileTime);\r
+               LOADVALUEFROMFILE(m_indexFileTime);\r
+//             LOADVALUEFROMFILE(m_propsFileTime);\r
                LOADVALUEFROMFILE(value);\r
                if (value > MAX_PATH)\r
                        return false;\r
@@ -195,43 +195,48 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
        {\r
                bRequestForSelf = true;\r
        }\r
-\r
+//OutputDebugStringA("GetStatusForMember: ");OutputDebugStringW(path.GetWinPathString());OutputDebugStringA("\r\n");\r
        // In all most circumstances, we ask for the status of a member of this directory.\r
        ATLASSERT(m_directoryPath.IsEquivalentToWithoutCase(path.GetContainingDirectory()) || bRequestForSelf);\r
 \r
-       // Check if the entries file has been changed\r
-       CTGitPath entriesFilePath(m_directoryPath);\r
-       CTGitPath propsDirPath(m_directoryPath);\r
+       CString sProjectRoot;\r
+       const BOOL bIsVersionedPath = m_directoryPath.HasAdminDir(&sProjectRoot);\r
+\r
+       // Check if the index file has been changed\r
+       CTGitPath indexFilePath(bIsVersionedPath ? sProjectRoot : m_directoryPath);\r
+//     CTGitPath propsDirPath(m_directoryPath);\r
        if (g_GitAdminDir.IsVSNETHackActive())\r
        {\r
-               entriesFilePath.AppendPathString(g_GitAdminDir.GetVSNETAdminDirName() + _T("\\entries"));\r
-               propsDirPath.AppendPathString(g_GitAdminDir.GetVSNETAdminDirName() + _T("\\dir-props"));\r
+               indexFilePath.AppendPathString(g_GitAdminDir.GetVSNETAdminDirName() + _T("\\index"));\r
+//             propsDirPath.AppendPathString(g_GitAdminDir.GetVSNETAdminDirName() + _T("\\dir-props"));\r
        }\r
        else\r
        {\r
-               entriesFilePath.AppendPathString(g_GitAdminDir.GetAdminDirName() + _T("\\entries"));\r
-               propsDirPath.AppendPathString(g_GitAdminDir.GetAdminDirName() + _T("\\dir-props"));\r
+               indexFilePath.AppendPathString(g_GitAdminDir.GetAdminDirName() + _T("\\index"));\r
+//             propsDirPath.AppendPathString(g_GitAdminDir.GetAdminDirName() + _T("\\dir-props"));\r
        }\r
-       if ( (m_entriesFileTime == entriesFilePath.GetLastWriteTime()) && ((entriesFilePath.GetLastWriteTime() == 0) || (m_propsFileTime == propsDirPath.GetLastWriteTime())) )\r
+       if ( (m_indexFileTime == indexFilePath.GetLastWriteTime()) /*&& ((indexFilePath.GetLastWriteTime() == 0) || (m_propsFileTime == propsDirPath.GetLastWriteTime()))*/ )\r
        {\r
-               m_entriesFileTime = entriesFilePath.GetLastWriteTime();\r
-               if (m_entriesFileTime)\r
-                       m_propsFileTime = propsDirPath.GetLastWriteTime();\r
+//             m_indexFileTime = indexFilePath.GetLastWriteTime();\r
+//             if (m_indexFileTime)\r
+//                     m_propsFileTime = propsDirPath.GetLastWriteTime();\r
 \r
-               if(m_entriesFileTime == 0)\r
+               //if(m_indexFileTime == 0)\r
+               // a newly created project (without commits) has no index file but we still want it to count as versioned\r
+               if(m_indexFileTime == 0 && !bIsVersionedPath)\r
                {\r
                        // We are a folder which is not in a working copy\r
                        bThisDirectoryIsUnversioned = true;\r
                        m_ownStatus.SetStatus(NULL);\r
 \r
-                       // If a user removes the .svn directory, we get here with m_entryCache\r
+                       // If a user removes the .git directory, we get here with m_entryCache\r
                        // not being empty, but still us being unversioned\r
                        if (!m_entryCache.empty())\r
                        {\r
                                m_entryCache.clear();\r
                        }\r
                        ATLASSERT(m_entryCache.empty());\r
-                       \r
+\r
                        // However, a member *DIRECTORY* might be the top of WC\r
                        // so we need to ask them to get their own status\r
                        if(!path.IsDirectory())\r
@@ -245,6 +250,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                // So mark it for crawling, and let the crawler remove it\r
                                // later\r
                                CGitStatusCache::Instance().AddFolderForCrawling(path.GetContainingDirectory());\r
+\r
                                return CStatusCacheEntry();\r
                        }\r
                        else\r
@@ -252,9 +258,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                // If we're in the special case of a directory being asked for its own status\r
                                // and this directory is unversioned, then we should just return that here\r
                                if(bRequestForSelf)\r
-                               {\r
                                        return CStatusCacheEntry();\r
-                               }\r
                        }\r
                }\r
 \r
@@ -276,7 +280,6 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                                CGitStatusCache::Instance().AddFolderForCrawling(it->first);\r
                                        }\r
                                }\r
-\r
                                return dirEntry->GetOwnStatus(bRecursive);\r
                        }\r
                }\r
@@ -341,14 +344,14 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                // we already have (to save time and make the explorer\r
                // more responsive in stress conditions).\r
                // We leave the refreshing to the crawler.\r
-               if ((!bFetch)&&(m_entriesFileTime))\r
+               if ((!bFetch)&&(m_indexFileTime))\r
                {\r
                        CGitStatusCache::Instance().AddFolderForCrawling(path.GetDirectory());\r
                        return CStatusCacheEntry();\r
                }\r
                AutoLocker lock(m_critSec);\r
-               m_entriesFileTime = entriesFilePath.GetLastWriteTime();\r
-               m_propsFileTime = propsDirPath.GetLastWriteTime();\r
+               m_indexFileTime = indexFilePath.GetLastWriteTime();\r
+//             m_propsFileTime = propsDirPath.GetLastWriteTime();\r
                m_entryCache.clear();\r
                strCacheKey = GetCacheKey(path);\r
        }\r
@@ -361,7 +364,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
 \r
        if (g_GitAdminDir.IsAdminDirPath(path.GetWinPathString()))\r
        {\r
-               // We're being asked for the status of an .SVN directory\r
+               // We're being asked for the status of an .git directory\r
                // It's not worth asking for this\r
                return CStatusCacheEntry();\r
        }\r
@@ -395,10 +398,25 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                m_currentStatusFetchingPath = m_directoryPath;\r
                                m_currentStatusFetchingPathTicks = GetTickCount();\r
                        }\r
-                       ATLTRACE(_T("svn_cli_stat for '%s' (req %s)\n"), m_directoryPath.GetWinPath(), path.GetWinPath());\r
-                       git_error_t* pErr;\r
-#if 0\r
-                        = svn_client_status4 (\r
+                       ATLTRACE(_T("git_enum_files for '%s' (req %s)\n"), m_directoryPath.GetWinPath(), path.GetWinPath());\r
+\r
+                       CString sProjectRoot;\r
+                       m_directoryPath.HasAdminDir(&sProjectRoot);\r
+                       ATLASSERT( !m_directoryPath.IsEmpty() );\r
+\r
+                       LPCSTR lpszSubPath = NULL;\r
+                       CStringA sSubPath;\r
+                       CString s = m_directoryPath.GetDirectory().GetWinPathString();\r
+                       if (s.GetLength() > sProjectRoot.GetLength())\r
+                       {\r
+                               sSubPath = CStringA(s.Right(s.GetLength() - sProjectRoot.GetLength() - 1/*otherwise it gets initial slash*/));\r
+                               lpszSubPath = sSubPath;\r
+                       }\r
+//MessageBoxA(NULL, CStringA(sProjectRoot), sSubPath, MB_OK);\r
+//OutputDebugStringA("###");OutputDebugStringW(sProjectRoot);OutputDebugStringA(" - ");OutputDebugStringA(sSubPath);OutputDebugStringA("\r\n");\r
+                       BOOL pErr = !wgEnumFiles(CStringA(sProjectRoot), lpszSubPath, WGEFF_NoRecurse|WGEFF_FullPath, &GetStatusCallback, this);\r
+\r
+                       /*git_error_t* pErr = svn_client_status4 (\r
                                NULL,\r
                                m_directoryPath.GetSVNApiPath(subPool),\r
                                &revision,\r
@@ -412,13 +430,12 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                NULL,                                                                   //changelists\r
                                CGitStatusCache::Instance().m_svnHelp.ClientContext(),\r
                                subPool\r
-                               );\r
-#endif\r
+                               );*/\r
                        {\r
                                AutoLocker pathlock(m_critSecPath);\r
                                m_currentStatusFetchingPath.Reset();\r
                        }\r
-                       ATLTRACE(_T("svn_cli_stat finished for '%s'\n"), m_directoryPath.GetWinPath(), path.GetWinPath());\r
+                       ATLTRACE(_T("git_enum_files finished for '%s'\n"), m_directoryPath.GetWinPath(), path.GetWinPath());\r
                        if(pErr)\r
                        {\r
                                // Handle an error\r
@@ -428,7 +445,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                // If we allow ourselves to fall on through, then folders will be asked\r
                                // for their own status, and will set themselves as unversioned, for the \r
                                // benefit of future requests\r
-//                             ATLTRACE("svn_cli_stat err: '%s'\n", pErr->message);\r
+//                             ATLTRACE("git_enum_files err: '%s'\n", pErr->message);\r
 //                             svn_error_clear(pErr);\r
                                // No assert here! Since we _can_ get here, an assertion is not an option!\r
                                // Reasons to get here: \r
@@ -442,7 +459,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                                }\r
                                else\r
                                {\r
-                                       ATLTRACE("svn_cli_stat error, assume none status\n");\r
+                                       ATLTRACE("git_enum_files error, assume none status\n");\r
                                        // Since we only assume a none status here due to svn_client_status()\r
                                        // returning an error, make sure that this status times out soon.\r
                                        CGitStatusCache::Instance().m_folderCrawler.BlockPath(m_directoryPath, 2000);\r
@@ -453,7 +470,7 @@ CStatusCacheEntry CCachedDirectory::GetStatusForMember(const CTGitPath& path, bo
                }\r
                else\r
                {\r
-                       ATLTRACE("Skipped SVN status for unversioned folder\n");\r
+                       ATLTRACE("Skipped git status for unversioned folder\n");\r
                }\r
        }\r
        // Now that we've refreshed our SVN status, we can see if it's \r
@@ -501,7 +518,7 @@ CCachedDirectory::AddEntry(const CTGitPath& path, const git_wc_status2_t* pGitSt
                {\r
                        if ((childDir->GetCurrentFullStatus() != git_wc_status_missing)||(pGitStatus==NULL)||(pGitStatus->text_status != git_wc_status_unversioned))\r
                                childDir->m_ownStatus.SetStatus(pGitStatus);\r
-//                     childDir->m_ownStatus.SetKind(svn_node_dir);\r
+                       childDir->m_ownStatus.SetKind(git_node_dir);\r
                }\r
        }\r
        else\r
@@ -525,6 +542,8 @@ CCachedDirectory::AddEntry(const CTGitPath& path, const git_wc_status2_t* pGitSt
                        entry_it = m_entryCache.insert(entry_it, std::make_pair(cachekey, CStatusCacheEntry()));\r
                }\r
                entry_it->second = CStatusCacheEntry(pGitStatus, path.GetLastWriteTime(), path.IsReadOnly(), validuntil);\r
+               // TEMP(?): git status doesn't not have "entry" that contains node type, so manually set as file\r
+               entry_it->second.SetKind(git_node_file);\r
        }\r
 }\r
 \r
@@ -543,6 +562,147 @@ CCachedDirectory::GetFullPathString(const CString& cacheKey)
        return m_directoryPath.GetWinPathString() + _T("\\") + cacheKey;\r
 }\r
 \r
+BOOL CCachedDirectory::GetStatusCallback(const struct wgFile_s *pFile, void *pUserData)\r
+{\r
+       CCachedDirectory* pThis = (CCachedDirectory*)pUserData;\r
+\r
+       const char *path = pFile->sFileName;\r
+\r
+       if (path == NULL)\r
+               return FALSE;\r
+\r
+       git_wc_status2_t _status;\r
+       git_wc_status2_t *status = &_status;\r
+\r
+       if ((pFile->nFlags & WGFF_Directory) && pFile->nStatus == WGFS_Unknown)\r
+               status->prop_status = status->text_status = git_wc_status_incomplete;\r
+       else\r
+               status->prop_status = status->text_status = GitStatusFromWingit(pFile->nStatus);\r
+//if (pFile->nStatus > WGFS_Normal) {CStringA s; s.Format("==>%s %d\r\n",pFile->sFileName,pFile->nStatus); OutputDebugStringA(s);}\r
+       CTGitPath svnPath;\r
+\r
+//     if(status->entry)\r
+       {\r
+               //if ((status->text_status != git_wc_status_none)&&(status->text_status != git_wc_status_missing))\r
+                       svnPath.SetFromGit(path, pFile->nFlags & WGFF_Directory);\r
+               /*else\r
+                       svnPath.SetFromGit(path);*/\r
+\r
+               if (pFile->nFlags & WGFF_Directory)\r
+               {\r
+                       if ( !svnPath.IsEquivalentToWithoutCase(pThis->m_directoryPath) )\r
+                       {\r
+                               if (pThis->m_bRecursive)\r
+                               {\r
+                                       // Add any versioned directory, which is not our 'self' entry, to the list for having its status updated\r
+//OutputDebugStringA("AddFolderCrawl: ");OutputDebugStringW(svnPath.GetWinPathString());OutputDebugStringA("\r\n");\r
+                                       CGitStatusCache::Instance().AddFolderForCrawling(svnPath);\r
+                               }\r
+\r
+                               // Make sure we know about this child directory\r
+                               // This initial status value is likely to be overwritten from below at some point\r
+                               git_wc_status_kind s = GitStatus::GetMoreImportant(status->text_status, status->prop_status);\r
+                               CCachedDirectory * cdir = CGitStatusCache::Instance().GetDirectoryCacheEntryNoCreate(svnPath);\r
+                               if (cdir)\r
+                               {\r
+                                       // This child directory is already in our cache!\r
+                                       // So ask this dir about its recursive status\r
+                                       git_wc_status_kind st = GitStatus::GetMoreImportant(s, cdir->GetCurrentFullStatus());\r
+                                       AutoLocker lock(pThis->m_critSec);\r
+                                       pThis->m_childDirectories[svnPath] = st;\r
+                               }\r
+                               else\r
+                               {\r
+                                       // the child directory is not in the cache. Create a new entry for it in the cache which is\r
+                                       // initially 'unversioned'. But we added that directory to the crawling list above, which\r
+                                       // means the cache will be updated soon.\r
+                                       CGitStatusCache::Instance().GetDirectoryCacheEntry(svnPath);\r
+                                       AutoLocker lock(pThis->m_critSec);\r
+                                       pThis->m_childDirectories[svnPath] = s;\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // Keep track of the most important status of all the files in this directory\r
+                       // Don't include subdirectories in this figure, because they need to provide their \r
+                       // own 'most important' value\r
+                       pThis->m_mostImportantFileStatus = GitStatus::GetMoreImportant(pThis->m_mostImportantFileStatus, status->text_status);\r
+                       pThis->m_mostImportantFileStatus = GitStatus::GetMoreImportant(pThis->m_mostImportantFileStatus, status->prop_status);\r
+                       if (((status->text_status == git_wc_status_unversioned)||(status->text_status == git_wc_status_none))\r
+                               &&(CGitStatusCache::Instance().IsUnversionedAsModified()))\r
+                       {\r
+                               // treat unversioned files as modified\r
+                               if (pThis->m_mostImportantFileStatus != git_wc_status_added)\r
+                                       pThis->m_mostImportantFileStatus = GitStatus::GetMoreImportant(pThis->m_mostImportantFileStatus, git_wc_status_modified);\r
+                       }\r
+               }\r
+       }\r
+#if 0\r
+       else\r
+       {\r
+               svnPath.SetFromGit(path);\r
+               // Subversion returns no 'entry' field for versioned folders if they're\r
+               // part of another working copy (nested layouts).\r
+               // So we have to make sure that such an 'unversioned' folder really\r
+               // is unversioned.\r
+               if (((status->text_status == git_wc_status_unversioned)||(status->text_status == git_wc_status_missing))&&(!svnPath.IsEquivalentToWithoutCase(pThis->m_directoryPath))&&(svnPath.IsDirectory()))\r
+               {\r
+                       if (svnPath.HasAdminDir())\r
+                       {\r
+                               CGitStatusCache::Instance().AddFolderForCrawling(svnPath);\r
+                               // Mark the directory as 'versioned' (status 'normal' for now).\r
+                               // This initial value will be overwritten from below some time later\r
+                               {\r
+                                       AutoLocker lock(pThis->m_critSec);\r
+                                       pThis->m_childDirectories[svnPath] = git_wc_status_normal;\r
+                               }\r
+                               // Make sure the entry is also in the cache\r
+                               CGitStatusCache::Instance().GetDirectoryCacheEntry(svnPath);\r
+                               // also mark the status in the status object as normal\r
+                               status->text_status = git_wc_status_normal;\r
+                       }\r
+               }\r
+               else if (status->text_status == git_wc_status_external)\r
+               {\r
+                       CGitStatusCache::Instance().AddFolderForCrawling(svnPath);\r
+                       // Mark the directory as 'versioned' (status 'normal' for now).\r
+                       // This initial value will be overwritten from below some time later\r
+                       {\r
+                               AutoLocker lock(pThis->m_critSec);\r
+                               pThis->m_childDirectories[svnPath] = git_wc_status_normal;\r
+                       }\r
+                       // we have added a directory to the child-directory list of this\r
+                       // directory. We now must make sure that this directory also has\r
+                       // an entry in the cache.\r
+                       CGitStatusCache::Instance().GetDirectoryCacheEntry(svnPath);\r
+                       // also mark the status in the status object as normal\r
+                       status->text_status = git_wc_status_normal;\r
+               }\r
+               else\r
+               {\r
+                       if (svnPath.IsDirectory())\r
+                       {\r
+                               AutoLocker lock(pThis->m_critSec);\r
+                               pThis->m_childDirectories[svnPath] = GitStatus::GetMoreImportant(status->text_status, status->prop_status);\r
+                       }\r
+                       else if ((CGitStatusCache::Instance().IsUnversionedAsModified())&&(status->text_status != git_wc_status_missing))\r
+                       {\r
+                               // make this unversioned item change the most important status of this\r
+                               // folder to modified if it doesn't already have another status\r
+                               if (pThis->m_mostImportantFileStatus != git_wc_status_added)\r
+                                       pThis->m_mostImportantFileStatus = GitStatus::GetMoreImportant(pThis->m_mostImportantFileStatus, git_wc_status_modified);\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+\r
+       pThis->AddEntry(svnPath, status);\r
+\r
+       return FALSE;\r
+}\r
+\r
+#if 0\r
 git_error_t * CCachedDirectory::GetStatusCallback(void *baton, const char *path, git_wc_status2_t *status)\r
 {\r
        CCachedDirectory* pThis = (CCachedDirectory*)baton;\r
@@ -552,7 +712,6 @@ git_error_t * CCachedDirectory::GetStatusCallback(void *baton, const char *path,
                \r
        CTGitPath svnPath;\r
 \r
-#if 0\r
        if(status->entry)\r
        {\r
                if ((status->text_status != git_wc_status_none)&&(status->text_status != git_wc_status_missing))\r
@@ -665,11 +824,12 @@ git_error_t * CCachedDirectory::GetStatusCallback(void *baton, const char *path,
                        }\r
                }\r
        }\r
-#endif\r
+\r
        pThis->AddEntry(svnPath, status);\r
 \r
        return 0;\r
 }\r
+#endif\r
 \r
 bool \r
 CCachedDirectory::IsOwnStatusValid() const\r
index 987c0d0..4d32ec0 100644 (file)
@@ -48,7 +48,8 @@ public:
        /// Get the current full status of this folder\r
        git_wc_status_kind GetCurrentFullStatus() {return m_currentFullStatus;}\r
 private:\r
-       static git_error_t* GetStatusCallback(void *baton, const char *path, git_wc_status2_t *status);\r
+//     static git_error_t* GetStatusCallback(void *baton, const char *path, git_wc_status2_t *status);\r
+       static BOOL GetStatusCallback(const struct wgFile_s *pFile, void *pUserData);\r
        void AddEntry(const CTGitPath& path, const git_wc_status2_t* pGitStatus, DWORD validuntil = 0);\r
        CString GetCacheKey(const CTGitPath& path);\r
        CString GetFullPathString(const CString& cacheKey);\r
@@ -76,10 +77,10 @@ private:
        typedef std::map<CTGitPath, git_wc_status_kind>  ChildDirStatus;\r
        ChildDirStatus m_childDirectories;\r
 \r
-       // The timestamp of the .SVN\entries file.  For an unversioned directory, this will be zero\r
-       __int64 m_entriesFileTime;\r
+       // The timestamp of the .git\index file.  For an unversioned directory, this will be zero\r
+       __int64 m_indexFileTime;\r
        // The timestamp of the .SVN\props dir.  For an unversioned directory, this will be zero\r
-       __int64 m_propsFileTime;\r
+//     __int64 m_propsFileTime;\r
        \r
        // The path of the directory with this object looks after\r
        CTGitPath       m_directoryPath;\r
index bab47be..ca92ee8 100644 (file)
@@ -240,23 +240,25 @@ void CFolderCrawler::WorkerThread()
                                // don't crawl paths that are excluded\r
                                if (!CGitStatusCache::Instance().IsPathAllowed(workingPath))\r
                                        continue;\r
-                               // check if the changed path is inside an .svn folder\r
-                               if ((workingPath.HasAdminDir()&&workingPath.IsDirectory())||workingPath.IsAdminDir())\r
+                               // check if the changed path is inside an .git folder\r
+                               if ((workingPath.HasAdminDir()&&workingPath.IsDirectory()) || workingPath.IsAdminDir())\r
                                {\r
-                                       // we don't crawl for paths changed in a tmp folder inside an .svn folder.\r
+                                       // we don't crawl for paths changed in a tmp folder inside an .git folder.\r
                                        // Because we also get notifications for those even if we just ask for the status!\r
                                        // And changes there don't affect the file status at all, so it's safe\r
                                        // to ignore notifications on those paths.\r
                                        if (workingPath.IsAdminDir())\r
                                        {\r
-                                               CString lowerpath = workingPath.GetWinPathString();\r
+                                               // TODO: add git specific filters here. is there really any change besides index file in .git\r
+                                               //       that is relevant for overlays?\r
+                                               /*CString lowerpath = workingPath.GetWinPathString();\r
                                                lowerpath.MakeLower();\r
                                                if (lowerpath.Find(_T("\\tmp\\"))>0)\r
                                                        continue;\r
                                                if (lowerpath.Find(_T("\\tmp")) == (lowerpath.GetLength()-4))\r
                                                        continue;\r
                                                if (lowerpath.Find(_T("\\log"))>0)\r
-                                                       continue;\r
+                                                       continue;*/\r
                                                // Here's a little problem:\r
                                                // the lock file is also created for fetching the status\r
                                                // and not just when committing.\r
index 5109a22..4b15ae5 100644 (file)
@@ -48,7 +48,7 @@ void CGitStatusCache::Create()
        TCHAR path2[MAX_PATH];\r
        if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)==S_OK)\r
        {\r
-               _tcscat_s(path, MAX_PATH, _T("\\TSVNCache"));\r
+               _tcscat_s(path, MAX_PATH, _T("\\TGitCache"));\r
                if (!PathIsDirectory(path))\r
                {\r
                        if (CreateDirectory(path, NULL)==0)\r
@@ -148,7 +148,7 @@ bool CGitStatusCache::SaveCache()
        TCHAR path[MAX_PATH];           //MAX_PATH ok here.\r
        if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)==S_OK)\r
        {\r
-               _tcscat_s(path, MAX_PATH, _T("\\TSVNCache"));\r
+               _tcscat_s(path, MAX_PATH, _T("\\TGitCache"));\r
                if (!PathIsDirectory(path))\r
                        CreateDirectory(path, NULL);\r
                _tcscat_s(path, MAX_PATH, _T("\\cache"));\r
index 8e7b424..5bedb4e 100644 (file)
@@ -27,7 +27,7 @@ DWORD cachetimeout = (DWORD)CRegStdWORD(_T("Software\\TortoiseGit\\Cachetimeout"
 CStatusCacheEntry::CStatusCacheEntry()\r
        : m_bSet(false)\r
        , m_bSVNEntryFieldSet(false)\r
-//     , m_kind(svn_node_unknown)\r
+       , m_kind(git_node_unknown)\r
        , m_bReadOnly(false)\r
        , m_highestPriorityLocalStatus(git_wc_status_none)\r
 {\r
@@ -37,7 +37,7 @@ CStatusCacheEntry::CStatusCacheEntry()
 CStatusCacheEntry::CStatusCacheEntry(const git_wc_status2_t* pGitStatus, __int64 lastWriteTime, bool bReadOnly, DWORD validuntil /* = 0*/)\r
        : m_bSet(false)\r
        , m_bSVNEntryFieldSet(false)\r
-//     , m_kind(svn_node_unknown)\r
+       , m_kind(git_node_unknown)\r
        , m_bReadOnly(false)\r
        , m_highestPriorityLocalStatus(git_wc_status_none)\r
 {\r
@@ -61,21 +61,21 @@ bool CStatusCacheEntry::SaveToDisk(FILE * pFile)
        WRITEVALUETOFILE(m_lastWriteTime);\r
        WRITEVALUETOFILE(m_bSet);\r
        WRITEVALUETOFILE(m_bSVNEntryFieldSet);\r
-       WRITEVALUETOFILE(m_commitRevision);\r
+       CStringA srev(m_commitRevision); WRITESTRINGTOFILE(srev);\r
        WRITESTRINGTOFILE(m_sUrl);\r
        WRITESTRINGTOFILE(m_sOwner);\r
        WRITESTRINGTOFILE(m_sAuthor);\r
-//     WRITEVALUETOFILE(m_kind);\r
+       WRITEVALUETOFILE(m_kind);\r
        WRITEVALUETOFILE(m_bReadOnly);\r
        WRITESTRINGTOFILE(m_sPresentProps);\r
 \r
        // now save the status struct (without the entry field, because we don't use that)      WRITEVALUETOFILE(m_GitStatus.copied);\r
 //     WRITEVALUETOFILE(m_GitStatus.locked);\r
-//     WRITEVALUETOFILE(m_GitStatus.prop_status);\r
+       WRITEVALUETOFILE(m_GitStatus.prop_status);\r
 //     WRITEVALUETOFILE(m_GitStatus.repos_prop_status);\r
 //     WRITEVALUETOFILE(m_GitStatus.repos_text_status);\r
 //     WRITEVALUETOFILE(m_GitStatus.switched);\r
-//     WRITEVALUETOFILE(m_GitStatus.text_status);\r
+       WRITEVALUETOFILE(m_GitStatus.text_status);\r
        return true;\r
 }\r
 \r
@@ -92,7 +92,19 @@ bool CStatusCacheEntry::LoadFromDisk(FILE * pFile)
                LOADVALUEFROMFILE(m_lastWriteTime);\r
                LOADVALUEFROMFILE(m_bSet);\r
                LOADVALUEFROMFILE(m_bSVNEntryFieldSet);\r
-               LOADVALUEFROMFILE(m_commitRevision);\r
+               LOADVALUEFROMFILE(value);\r
+               if (value != 0)\r
+               {\r
+                       CStringA s;\r
+                       if (fread(s.GetBuffer(value+1), sizeof(char), value, pFile)!=value)\r
+                       {\r
+                               s.ReleaseBuffer(0);\r
+                               m_commitRevision.Empty();\r
+                               return false;\r
+                       }\r
+                       s.ReleaseBuffer(value);\r
+                       m_commitRevision = s;\r
+               }\r
                LOADVALUEFROMFILE(value);\r
                if (value != 0)\r
                {\r
@@ -125,7 +137,7 @@ bool CStatusCacheEntry::LoadFromDisk(FILE * pFile)
                        }\r
                        m_sAuthor.ReleaseBuffer(value);\r
                }\r
-//             LOADVALUEFROMFILE(m_kind);\r
+               LOADVALUEFROMFILE(m_kind);\r
                LOADVALUEFROMFILE(m_bReadOnly);\r
                LOADVALUEFROMFILE(value);\r
                if (value != 0)\r
@@ -140,11 +152,11 @@ bool CStatusCacheEntry::LoadFromDisk(FILE * pFile)
                SecureZeroMemory(&m_GitStatus, sizeof(m_GitStatus));\r
 //             LOADVALUEFROMFILE(m_GitStatus.copied);\r
 //             LOADVALUEFROMFILE(m_GitStatus.locked);\r
-//             LOADVALUEFROMFILE(m_GitStatus.prop_status);\r
+               LOADVALUEFROMFILE(m_GitStatus.prop_status);\r
 //             LOADVALUEFROMFILE(m_GitStatus.repos_prop_status);\r
 //             LOADVALUEFROMFILE(m_GitStatus.repos_text_status);\r
 //             LOADVALUEFROMFILE(m_GitStatus.switched);\r
-//             LOADVALUEFROMFILE(m_GitStatus.text_status);\r
+               LOADVALUEFROMFILE(m_GitStatus.text_status);\r
 //             m_GitStatus.entry = NULL;\r
                m_discardAtTime = GetTickCount()+cachetimeout;\r
        }\r
@@ -167,8 +179,7 @@ void CStatusCacheEntry::SetStatus(const git_wc_status2_t* pGitStatus)
                m_GitStatus = *pGitStatus;\r
 \r
                // Currently we don't deep-copy the whole entry value, but we do take a few members\r
-#if 0\r
-        if(pGitStatus->entry != NULL)\r
+/*        if(pGitStatus->entry != NULL)\r
                {\r
                        m_sUrl = pGitStatus->entry->url;\r
                        m_commitRevision = pGitStatus->entry->cmt_rev;\r
@@ -179,14 +190,13 @@ void CStatusCacheEntry::SetStatus(const git_wc_status2_t* pGitStatus)
                        if (pGitStatus->entry->present_props)\r
                                m_sPresentProps = pGitStatus->entry->present_props;\r
                }\r
-               else\r
+               else*/\r
                {\r
                        m_sUrl.Empty();\r
-                       m_commitRevision = 0;\r
+                       m_commitRevision = GIT_INVALID_REVNUM;\r
                        m_bSVNEntryFieldSet = false;\r
                }\r
-               m_GitStatus.entry = NULL;\r
-#endif\r
+//             m_GitStatus.entry = NULL;\r
        }\r
        m_discardAtTime = GetTickCount()+cachetimeout;\r
        m_bSet = true;\r
@@ -219,7 +229,7 @@ void CStatusCacheEntry::BuildCacheResponse(TSVNCacheResponse& response, DWORD& r
        if(m_bSVNEntryFieldSet)\r
        {\r
                response.m_status = m_GitStatus;\r
-//             response.m_entry.cmt_rev = m_commitRevision;\r
+               wcscpy_s(response.m_entry.cmt_rev, 41, m_commitRevision.GetString());\r
 \r
                // There is no point trying to set these pointers here, because this is not \r
                // the process which will be using the data.\r
@@ -228,7 +238,7 @@ void CStatusCacheEntry::BuildCacheResponse(TSVNCacheResponse& response, DWORD& r
 //             response.m_status.entry = NULL;\r
 //             response.m_entry.url = NULL;\r
 \r
-//             response.m_kind = m_kind;\r
+               response.m_kind = m_kind;\r
                response.m_readonly = m_bReadOnly;\r
 \r
                if (m_sPresentProps.Find("svn:needs-lock")>=0)\r
index 7610722..f453087 100644 (file)
@@ -22,7 +22,7 @@ struct TSVNCacheResponse;
 #define CACHETIMEOUT   0x7FFFFFFF\r
 extern DWORD cachetimeout;\r
 \r
-#include "GitStatus.h"\r
+#include "CacheInterface.h"\r
 \r
 /**\r
  * \ingroup TSVNCache\r
@@ -39,14 +39,14 @@ public:
        bool DoesFileTimeMatch(__int64 testTime) const;\r
        bool ForceStatus(git_wc_status_kind forcedStatus);\r
        git_wc_status_kind GetEffectiveStatus() const { return m_highestPriorityLocalStatus; }\r
-       bool IsKindKnown() const { return true;/*((m_kind != git_node_none)&&(m_kind != git_node_unknown));*/ }\r
+       bool IsKindKnown() const { return ((m_kind != git_node_none)&&(m_kind != git_node_unknown)); }\r
        void SetStatus(const git_wc_status2_t* pGitStatus);\r
        bool HasBeenSet() const;\r
        void Invalidate();\r
-       bool IsDirectory() const {return true; /*((m_kind == git_node_dir)&&(m_highestPriorityLocalStatus != git_wc_status_ignored));*/}\r
+       bool IsDirectory() const { return ((m_kind == git_node_dir)&&(m_highestPriorityLocalStatus != git_wc_status_ignored)); }\r
        bool SaveToDisk(FILE * pFile);\r
        bool LoadFromDisk(FILE * pFile);\r
-//     void SetKind(git_node_kind_t kind) {m_kind = kind;}\r
+       void SetKind(git_node_kind_t kind) {m_kind = kind;}\r
 private:\r
        void SetAsUnversioned();\r
 \r
@@ -56,7 +56,7 @@ private:
        git_wc_status2_t        m_GitStatus;\r
        __int64                         m_lastWriteTime;\r
        bool                            m_bSet;\r
-//     git_node_kind_t         m_kind;\r
+       git_node_kind_t         m_kind;\r
        bool                            m_bReadOnly;\r
 \r
        // Values copied from the 'entries' structure\r
@@ -67,5 +67,5 @@ private:
        CStringA                        m_sPresentProps;\r
        git_revnum_t            m_commitRevision;\r
 \r
-//     friend class CGitStatusCache;\r
+       friend class CGitStatusCache;\r
 };\r
index 2b13785..a6f49c8 100644 (file)
@@ -44,7 +44,7 @@
 \r
 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")\r
 \r
-CCrashReport crasher("tortoisegit-bug@googlegroups.com", "Crash Report for TSVNCache " APP_X64_STRING " : " STRPRODUCTVER, TRUE);// crash\r
+CCrashReport crasher("tortoisegit-bug@googlegroups.com", "Crash Report for TGitCache " APP_X64_STRING " : " STRPRODUCTVER, TRUE);// crash\r
 \r
 DWORD WINAPI           InstanceThread(LPVOID); \r
 DWORD WINAPI           PipeThread(LPVOID);\r
@@ -122,7 +122,7 @@ void DebugOutputLastError()
        }\r
 \r
        // Display the string.\r
-       OutputDebugStringA("TSVNCache GetLastError(): ");\r
+       OutputDebugStringA("TGitCache GetLastError(): ");\r
        OutputDebugString((LPCTSTR)lpMsgBuf);\r
        OutputDebugStringA("\n");\r
 \r
@@ -136,8 +136,8 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*
 \r
        if (hReloadProtection == 0 || GetLastError() == ERROR_ALREADY_EXISTS)\r
        {\r
-               // An instance of TSVNCache is already running\r
-               ATLTRACE("TSVNCache ignoring restart\n");\r
+               // An instance of TGitCache is already running\r
+               ATLTRACE("TGitCache ignoring restart\n");\r
                return 0;\r
        }\r
 \r
index 08dc76a..c1c4d98 100644 (file)
@@ -75,7 +75,7 @@
                                AdditionalDependencies="Crypt32.lib"\r
                                OutputFile="$(OutDir)/TGitCache.exe"\r
                                LinkIncremental="2"\r
-                               AdditionalLibraryDirectories="../../ext/wingit"\r
+                               AdditionalLibraryDirectories=""\r
                                IgnoreDefaultLibraryNames="libc"\r
                                GenerateDebugInformation="true"\r
                                ProgramDatabaseFile="$(OutDir)/TGitCache.pdb"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="Crypt32.lib wingit.lib"\r
+                               AdditionalDependencies="Crypt32.lib"\r
                                OutputFile="$(OutDir)/TGitCache.exe"\r
                                LinkIncremental="1"\r
-                               AdditionalLibraryDirectories="../../ext/wingit"\r
-                               DelayLoadDLLs="wingit.dll"\r
+                               AdditionalLibraryDirectories=""\r
+                               DelayLoadDLLs=""\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                OptimizeReferences="2"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Utils\PathUtils.h"\r
+                               RelativePath="..\Git\GitAdminDir.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Utils\registry.h"\r
+                               RelativePath="..\Git\GitStatus.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\resource.h"\r
+                               RelativePath=".\GitStatusCache.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Utils\RWSection.h"\r
+                               RelativePath="..\Utils\PathUtils.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\TortoiseShell\ShellCache.h"\r
+                               RelativePath="..\Utils\registry.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\ShellUpdater.h"\r
+                               RelativePath=".\resource.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\StatusCacheEntry.h"\r
+                               RelativePath="..\Utils\RWSection.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\stdafx.h"\r
+                               RelativePath="..\TortoiseShell\ShellCache.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Svn\SVNAdminDir.h"\r
+                               RelativePath=".\ShellUpdater.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\SVN\SVNGlobal.h"\r
+                               RelativePath=".\StatusCacheEntry.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Svn\SVNHelpers.h"\r
+                               RelativePath=".\stdafx.h"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Svn\SVNStatus.h"\r
+                               RelativePath="..\Git\TGitPath.h"\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Svn\TSVNPath.h"\r
-                               >\r
-                       </File>\r
-                       <File\r
                                RelativePath="..\Utils\UnicodeUtils.h"\r
                                >\r
                        </File>\r
index 3a51403..4a00c9e 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="gb2312"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="9.00"\r
+       Version="9,00"\r
        Name="TortoiseGitBlame"\r
        ProjectGUID="{62507C2F-9290-4342-910F-BFC44DF99B01}"\r
        RootNamespace="TortoiseGitBlame"\r
@@ -74,9 +74,9 @@
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
                                LinkIncremental="2"\r
-                               AdditionalLibraryDirectories="../../ext/wingit"\r
+                               AdditionalLibraryDirectories=""\r
                                IgnoreDefaultLibraryNames="LIBCMTD"\r
-                               DelayLoadDLLs="wingit.dll"\r
+                               DelayLoadDLLs=""\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                TargetMachine="1"\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
-                               LinkIncremental="2"\r
-                               IgnoreDefaultLibraryNames="LIBCMTD"\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories=""\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                TargetMachine="17"\r
index 2f9531a..3a173e6 100644 (file)
@@ -231,7 +231,7 @@ out everything for now, leaving these enabled as they are would make the install
             </Component>\r
 \r
             <Component Id="C__wingit" Guid="$(var.GuidGitLib)" Win64="$(var.Win64YesNo)">\r
-              <File Id="F__wingit" ShortName="WINGIT.DLL" Name="wingit.dll" DiskId="1" Source="..\..\ext\wingit\wingit.dll" KeyPath="yes" />\r
+              <File Id="F__wingit" ShortName="IGIT.EXE" Name="igit.exe" DiskId="1" Source="..\..\ext\igit.exe" KeyPath="yes" />\r
             </Component>\r
             \r
             <Component Id="C__TortoiseSVN" Guid="$(var.GuidTortoiseSVN)" Win64="$(var.Win64YesNo)">\r
@@ -241,8 +241,7 @@ out everything for now, leaving these enabled as they are would make the install
 -->\r
                          <File Id="F__TortoisePlink" ShortName="TORTPLI.EXE" Name="TortoisePlink.exe" DiskId="1" Source="..\..\bin\$(var.ReleasePath)\bin\TortoisePlink.exe" />\r
 \r
-<!--              <File Id="F__TSVNCache" ShortName="TGITCACH.EXE" Name="TGitCache.exe" DiskId="1" Source="..\..\bin\$(var.ReleasePath)\bin\TGitCache.exe" />\r
--->\r
+              <File Id="F__TSVNCache" ShortName="TGITCACH.EXE" Name="TGitCache.exe" DiskId="1" Source="..\..\bin\$(var.ReleasePath)\bin\TGitCache.exe" />\r
               <File Id="F__TSVNAutolist" ShortName="AUTOLIST.TXT" Name="autolist.txt" DiskId="1" Source="include\autolist.txt" />\r
               <File Id="F__websiteurl" ShortName="WEBSITE.URL" Name="Website.url" Source="include\Website.url" DiskId="1" />\r
 <!--\r
index da3db21..f886b4c 100644 (file)
@@ -49,6 +49,7 @@
 #include "SettingsCommand.h"\r
 #include "ConflictEditorCommand.h"\r
 #include "CleanupCommand.h"\r
+#include "RebaseCommand.h"\r
 \r
 #if 0\r
 \r
@@ -141,6 +142,7 @@ typedef enum
        cmdRebuildIconCache,\r
        cmdRelocate,\r
        cmdRemove,\r
+       cmdRebase,\r
        cmdRename,\r
        cmdRepoBrowser,\r
        cmdRepoCreate,\r
@@ -206,6 +208,7 @@ static const struct CommandInfo
        {       cmdRebuildIconCache,_T("rebuildiconcache")      },\r
        {       cmdRelocate,            _T("relocate")                  },\r
        {       cmdRemove,                      _T("remove")                    },\r
+       {       cmdRebase,                      _T("rebase")                    },\r
        {       cmdRename,                      _T("rename")                    },\r
        {       cmdRepoBrowser,         _T("repobrowser")               },\r
        {       cmdRepoCreate,          _T("repocreate")                },\r
@@ -301,6 +304,8 @@ Command * CommandServer::GetCommand(const CString& sCmd)
                return new ConflictEditorCommand;\r
        case cmdCleanup:\r
                return new CleanupCommand;\r
+       case cmdRebase:\r
+               return new RebaseCommand;\r
 #if 0\r
 \r
        case cmdCat:\r
diff --git a/src/TortoiseProc/Commands/RebaseCommand.cpp b/src/TortoiseProc/Commands/RebaseCommand.cpp
new file mode 100644 (file)
index 0000000..d517af1
--- /dev/null
@@ -0,0 +1,40 @@
+// TortoiseSVN - a Windows shell extension for easy version control\r
+\r
+// Copyright (C) 2007-2008 - TortoiseSVN\r
+\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+// GNU General Public License for more details.\r
+\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software Foundation,\r
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+//\r
+#include "StdAfx.h"\r
+#include "RebaseCommand.h"\r
+\r
+#include "MessageBox.h"\r
+//#include "SVNProgressDlg.h"\r
+//#include "ProgressDlg.h"\r
+#include "RebaseDlg.h"\r
+#include "InputLogDlg.h"\r
+#include "Git.h"\r
+#include "DirFileEnum.h"\r
+#include "ShellUpdater.h"\r
+\r
+bool RebaseCommand::Execute()\r
+{\r
+       bool bRet =false;\r
+       CRebaseDlg dlg;\r
+       if(dlg.DoModal() == IDOK)\r
+       {\r
+               bRet=true;\r
+       }\r
+       return bRet;\r
+}\r
diff --git a/src/TortoiseProc/Commands/RebaseCommand.h b/src/TortoiseProc/Commands/RebaseCommand.h
new file mode 100644 (file)
index 0000000..8733e78
--- /dev/null
@@ -0,0 +1,35 @@
+// TortoiseSVN - a Windows shell extension for easy version control\r
+\r
+// Copyright (C) 2007 - TortoiseSVN\r
+\r
+// This program is free software; you can redistribute it and/or\r
+// modify it under the terms of the GNU General Public License\r
+// as published by the Free Software Foundation; either version 2\r
+// of the License, or (at your option) any later version.\r
+\r
+// This program is distributed in the hope that it will be useful,\r
+// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+// GNU General Public License for more details.\r
+\r
+// You should have received a copy of the GNU General Public License\r
+// along with this program; if not, write to the Free Software Foundation,\r
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+//\r
+#pragma once\r
+#include "Command.h"\r
+\r
+/**\r
+ * \ingroup TortoiseProc\r
+ * Renames files and folders.\r
+ */\r
+class RebaseCommand : public Command\r
+{\r
+public:\r
+       /**\r
+        * Executes the command.\r
+        */\r
+       virtual bool                    Execute();\r
+};\r
+\r
+\r
index 024ea20..8b06ab6 100644 (file)
@@ -32,6 +32,7 @@
 #include "Hooks.h"\r
 #include "CommonResource.h"\r
 #include "UnicodeUtils.h"\r
+#include "ProgressDlg.h"\r
 \r
 #ifdef _DEBUG\r
 #define new DEBUG_NEW\r
@@ -475,11 +476,14 @@ void CCommitDlg::OnOK()
                        amend=_T("--amend");\r
                }\r
                cmd.Format(_T("git.exe commit %s -F \"%s\""),amend, tempfile);\r
-               g_Git.Run(cmd,&out,CP_OEMCP);\r
+               \r
+               CProgressDlg progress;\r
+               progress.m_GitCmd=cmd;\r
+               progress.m_bShowCommand = FALSE;        // don't show the commit command\r
+               progress.m_PreText = out;                       // show any output already generated in log window\r
+               progress.DoModal();\r
        \r
                CFile::Remove(tempfile);\r
-\r
-               CMessageBox::Show(this->m_hWnd, out, _T("Commit Finish"), MB_OK | MB_ICONINFORMATION);\r
        }else\r
                CMessageBox::Show(this->m_hWnd, _T("Nothing Commit"), _T("Commit Finish"), MB_OK | MB_ICONINFORMATION);\r
 #if 0\r
index 428e3a9..0bbf7fd 100644 (file)
@@ -263,7 +263,7 @@ UINT CFileDiffDlg::DiffThread()
                        cmd.Format(_T("git.exe diff -r -R --raw -C -M --numstat -z %s"),m_rev1.m_CommitHash);\r
        }else\r
        {\r
-               cmd.Format(_T("git.exe diff-tree -r --raw -C -M --numstat -z %s %s"),rev1,m_rev2.m_CommitHash);\r
+               cmd.Format(_T("git.exe diff-tree -r --raw -C -M --numstat -z %s %s"),m_rev2.m_CommitHash,rev1);\r
        }\r
 \r
        BYTE_VECTOR out;\r
index d85f2c3..553e9f7 100644 (file)
@@ -43,7 +43,7 @@ int CGitDiff::DiffNull(CTGitPath *pPath, git_revnum_t &rev1)
                                pPath->GetBaseFilename(),\r
                                rev1.Left(6),\r
                                pPath->GetFileExtension());\r
-               cmd.Format(_T("git.exe cat-file -p %s:%s"),rev1,pPath->GetGitPathString());\r
+               cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev1,pPath->GetGitPathString());\r
                                g_Git.RunLogFile(cmd,file1);\r
        }else\r
        {\r
@@ -80,7 +80,7 @@ int CGitDiff::Diff(CTGitPath * pPath,CTGitPath * pPath2, git_revnum_t & rev1, gi
                                rev1.Left(6),\r
                                pPath->GetFileExtension());\r
                title1 = pPath->GetFileOrDirectoryName()+_T(":")+rev1.Left(6);\r
-               cmd.Format(_T("git.exe cat-file -p %s:%s"),rev1,pPath->GetGitPathString());\r
+               cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev1,pPath->GetGitPathString());\r
                                g_Git.RunLogFile(cmd,file1);\r
        }else\r
        {\r
@@ -99,7 +99,7 @@ int CGitDiff::Diff(CTGitPath * pPath,CTGitPath * pPath2, git_revnum_t & rev1, gi
                                rev2.Left(6),\r
                                pPath2->GetFileExtension());\r
                title2 = pPath2->GetFileOrDirectoryName()+_T(":")+rev2.Left(6);\r
-               cmd.Format(_T("git.exe cat-file -p %s:%s"),rev2,pPath2->GetGitPathString());\r
+               cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),rev2,pPath2->GetGitPathString());\r
                g_Git.RunLogFile(cmd,file2);\r
        }else\r
        {\r
index 82caa0c..a167e0a 100644 (file)
@@ -129,6 +129,7 @@ int CLogCache::SaveOneItem(GitRev &Rev,ULONGLONG offset)
                ar<<header.m_Magic;\r
                ar<<header.m_Version;\r
                ar<<Rev.m_Files[i].GetGitPathString();\r
+               ar<<Rev.m_Files[i].GetGitOldPathString();\r
                ar<<Rev.m_Files[i].m_Action;\r
                ar<<Rev.m_Files[i].m_Stage;\r
                ar<<Rev.m_Files[i].m_StatAdd;\r
@@ -177,7 +178,7 @@ int CLogCache::LoadOneItem(GitRev &Rev,ULONGLONG offset)
        for(int i=0;i<header.m_FileCount;i++)\r
        {\r
                CTGitPath path;\r
-               CString file;\r
+               CString file,oldfile;\r
                path.Reset();\r
                SLogCacheRevFileHeader header;\r
 \r
@@ -187,7 +188,8 @@ int CLogCache::LoadOneItem(GitRev &Rev,ULONGLONG offset)
                if( this->CheckHeader(header) )\r
                        return -1;\r
                ar>>file;\r
-               path.SetFromGit(file);\r
+               ar>>oldfile;\r
+               path.SetFromGit(file,&oldfile);\r
 \r
                ar>>path.m_Action;\r
                ar>>path.m_Stage;\r
index cf35607..213363f 100644 (file)
@@ -6,6 +6,10 @@ class CGitLogListBase;
 class CGitLogList : public CGitLogListBase\r
 {\r
        DECLARE_DYNAMIC(CGitLogList)\r
+protected:\r
+       \r
+       void SetSelectedAction(int action);\r
+\r
 public:\r
        void ContextMenuAction(int cmd,int FirstSelect, int LastSelect);\r
 };
\ No newline at end of file
index 34833c5..0b3d003 100644 (file)
@@ -59,7 +59,6 @@ void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect)
 \r
        theApp.DoWaitCursor(1);\r
        bool bOpenWith = false;\r
-\r
        switch (cmd)\r
                {\r
                        case ID_GNUDIFF1:\r
@@ -177,6 +176,18 @@ void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect)
                        ReloadHashMap();\r
                        Invalidate();\r
                        break;\r
+               case ID_REBASE_PICK:\r
+                       SetSelectedAction(CTGitPath::LOGACTIONS_REBASE_PICK);\r
+                       break;\r
+               case ID_REBASE_EDIT:\r
+                       SetSelectedAction(CTGitPath::LOGACTIONS_REBASE_EDIT);\r
+                       break;\r
+               case ID_REBASE_SQUASH:\r
+                       SetSelectedAction(CTGitPath::LOGACTIONS_REBASE_SQUASH);\r
+                       break;\r
+               case ID_REBASE_SKIP:\r
+                       SetSelectedAction(CTGitPath::LOGACTIONS_REBASE_SKIP);\r
+                       break;\r
                default:\r
                        //CMessageBox::Show(NULL,_T("Have not implemented"),_T("TortoiseGit"),MB_OK);\r
                        break;\r
@@ -502,4 +513,20 @@ void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect)
                } // switch (cmd)\r
 \r
                theApp.DoWaitCursor(-1);\r
+}\r
+\r
+void CGitLogList::SetSelectedAction(int action)\r
+{\r
+       POSITION pos = GetFirstSelectedItemPosition();\r
+       int index;\r
+       while(pos)\r
+       {\r
+               index = GetNextSelectedItem(pos);\r
+               ((GitRev*)m_arShownList[index])->m_Action = action;\r
+               CRect rect;\r
+               this->GetItemRect(index,&rect,LVIR_BOUNDS);\r
+               this->InvalidateRect(rect);\r
+\r
+       }\r
+\r
 }
\ No newline at end of file
index e36c23a..3bc63a3 100644 (file)
@@ -90,6 +90,9 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        m_LoadingThread = NULL;\r
 \r
        m_bExitThread=FALSE;\r
+       m_IsOldFirst = FALSE;\r
+       m_IsRebaseReplaceGraph = FALSE;\r
+\r
 \r
        for(int i=0;i<Lanes::COLORS_NUM;i++)\r
        {\r
@@ -108,6 +111,12 @@ CGitLogListBase::CGitLogListBase():CHintListCtrl()
        // get relative time display setting from registry\r
        DWORD regRelativeTimes = CRegDWORD(_T("Software\\TortoiseGit\\RelativeTimes"), FALSE);\r
        m_bRelativeTimes = (regRelativeTimes != 0);\r
+       m_ContextMenuMask = 0xFFFFFFFFFFFFFFFF;\r
+\r
+       m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_PICK);\r
+       m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_SQUASH);\r
+       m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_EDIT);\r
+       m_ContextMenuMask &= ~GetContextMenuBit(ID_REBASE_SKIP);\r
 }\r
 \r
 CGitLogListBase::~CGitLogListBase()\r
@@ -173,6 +182,14 @@ void CGitLogListBase::InsertGitColumn()
                DeleteColumn(c--);\r
        temp.LoadString(IDS_LOG_GRAPH);\r
 \r
+       if(m_IsRebaseReplaceGraph)\r
+       {\r
+               temp=_T("Rebase");\r
+       }\r
+       else\r
+       {\r
+               temp.LoadString(IDS_LOG_GRAPH);\r
+       }\r
        InsertColumn(this->LOGLIST_GRAPH, temp);\r
        \r
 #if 0  \r
@@ -288,6 +305,8 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect)
        rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;\r
        GetItem(&rItem);\r
 \r
+       GitRev* pLogEntry = (GitRev*)m_arShownList.GetAt(Index);\r
+\r
        if (m_Theme.IsAppThemed() && m_bVista)\r
        {\r
                m_Theme.Open(m_hWnd, L"Explorer");\r
@@ -341,6 +360,11 @@ void CGitLogListBase::FillBackGround(HDC hdc, int Index,CRect &rect)
                        //if (pLogEntry->bCopiedSelf)\r
                        //      brush = ::CreateSolidBrush(::GetSysColor(COLOR_MENU));\r
                        //else\r
+                       if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+                               brush = ::CreateSolidBrush(RGB(156,156,156));\r
+                       else if(pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+                               brush = ::CreateSolidBrush(RGB(200,200,128));\r
+                       else \r
                                brush = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));\r
                }\r
                if (brush == NULL)\r
@@ -688,6 +712,22 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                        if (data->bCopies)\r
                                                crText = m_Colors.GetColor(CColors::Modified);\r
 #endif\r
+                                       if (data->m_Action& (CTGitPath::LOGACTIONS_REBASE_DONE| CTGitPath::LOGACTIONS_REBASE_SKIP) ) \r
+                                               crText = RGB(128,128,128);\r
+\r
+                                       if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+                                               pLVCD->clrTextBk = RGB(156,156,156);\r
+                                       else if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+                                               pLVCD->clrTextBk  = RGB(200,200,128);\r
+                                       else \r
+                                               pLVCD->clrTextBk  = ::GetSysColor(COLOR_WINDOW);\r
+\r
+                                       if(data->m_Action&CTGitPath::LOGACTIONS_REBASE_CURRENT)\r
+                                       {\r
+                                               SelectObject(pLVCD->nmcd.hdc, m_boldFont);\r
+                                               *pResult = CDRF_NOTIFYSUBITEMDRAW | CDRF_NEWFONT;\r
+                                       }\r
+\r
 //                                     if ((data->childStackDepth)||(m_mergedRevs.find(data->Rev) != m_mergedRevs.end()))\r
 //                                             crText = GetSysColor(COLOR_GRAYTEXT);\r
 //                                     if (data->Rev == m_wcRev)\r
@@ -718,7 +758,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
 \r
                        if (pLVCD->iSubItem == LOGLIST_GRAPH)\r
                        {\r
-                               if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec)\r
+                               if (m_arShownList.GetCount() > (INT_PTR)pLVCD->nmcd.dwItemSpec && (!this->m_IsRebaseReplaceGraph) )\r
                                {\r
                                        CRect rect;\r
                                        GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, rect);\r
@@ -790,7 +830,7 @@ void CGitLogListBase::OnNMCustomdrawLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                                        ::DrawIconEx(pLVCD->nmcd.hdc, rect.left + ICONITEMBORDER, rect.top, m_hModifiedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
                                nIcons++;\r
 \r
-                               if (pLogEntry->m_Action & CTGitPath::LOGACTIONS_ADDED)\r
+                               if (pLogEntry->m_Action & (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY) )\r
                                        ::DrawIconEx(pLVCD->nmcd.hdc, rect.left+nIcons*iconwidth + ICONITEMBORDER, rect.top, m_hAddedIcon, iconwidth, iconheight, 0, NULL, DI_NORMAL);\r
                                nIcons++;\r
 \r
@@ -840,7 +880,14 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)
                pLogEntry = reinterpret_cast<GitRev*>(m_arShownList.GetAt(pItem->iItem));\r
 \r
        CString temp;\r
-       temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem);\r
+       if(m_IsOldFirst)\r
+       {\r
+               temp.Format(_T("%d"),pItem->iItem+1);\r
+\r
+       }else\r
+       {\r
+               temp.Format(_T("%d"),m_arShownList.GetCount()-pItem->iItem);\r
+       }\r
            \r
        // Which column?\r
        switch (pItem->iSubItem)\r
@@ -848,6 +895,13 @@ void CGitLogListBase::OnLvnGetdispinfoLoglist(NMHDR *pNMHDR, LRESULT *pResult)
        case this->LOGLIST_GRAPH:       //Graphic\r
                if (pLogEntry)\r
                {\r
+                       if(this->m_IsRebaseReplaceGraph)\r
+                       {\r
+                               CTGitPath path;\r
+                               path.m_Action=pLogEntry->m_Action&CTGitPath::LOGACTIONS_REBASE_MODE_MASK;\r
+\r
+                               lstrcpyn(pItem->pszText,path.GetActionName(), pItem->cchTextMax);\r
+                       }\r
                }\r
                break;\r
        case this->LOGLIST_ACTION: //action -- no text in the column\r
@@ -966,6 +1020,23 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
        CIconMenu popup;\r
        if (popup.CreatePopupMenu())\r
        {\r
+\r
+               if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_PICK))\r
+                       popup.AppendMenuIcon(ID_REBASE_PICK,   _T("Pick"),   IDI_OPEN);\r
+\r
+               if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SQUASH))\r
+                       popup.AppendMenuIcon(ID_REBASE_SQUASH, _T("Squash"), IDI_OPEN);\r
+\r
+               if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_EDIT))\r
+                       popup.AppendMenuIcon(ID_REBASE_EDIT,   _T("Edit"),   IDI_OPEN);\r
+\r
+               if(m_ContextMenuMask&GetContextMenuBit(ID_REBASE_SKIP))\r
+                       popup.AppendMenuIcon(ID_REBASE_SKIP,   _T("SKIP"),   IDI_OPEN);\r
+               \r
+               if(m_ContextMenuMask&(GetContextMenuBit(ID_REBASE_SKIP)|GetContextMenuBit(ID_REBASE_EDIT)|\r
+                             GetContextMenuBit(ID_REBASE_SQUASH)|GetContextMenuBit(ID_REBASE_PICK)))\r
+                       popup.AppendMenu(MF_SEPARATOR, NULL);\r
+\r
                if (GetSelectedCount() == 1)\r
                {\r
 #if 0\r
@@ -990,7 +1061,8 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        {\r
                                if (m_hasWC)\r
                                {\r
-                                       popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
+                                       if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARE))\r
+                                               popup.AppendMenuIcon(ID_COMPARE, IDS_LOG_POPUP_COMPARE, IDI_DIFF);\r
                                        // TODO:\r
                                        // TortoiseMerge could be improved to take a /blame switch\r
                                        // and then not 'cat' the files from a unified diff but\r
@@ -999,8 +1071,11 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                                        // this feature is commented out.\r
                                        //popup.AppendMenu(ID_BLAMECOMPARE, IDS_LOG_POPUP_BLAMECOMPARE, IDI_BLAME);\r
                                }\r
-                               popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
-                               popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF1))\r
+                                       popup.AppendMenuIcon(ID_GNUDIFF1, IDS_LOG_POPUP_GNUDIFF_CH, IDI_DIFF);\r
+\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_COMPAREWITHPREVIOUS))\r
+                                       popup.AppendMenuIcon(ID_COMPAREWITHPREVIOUS, IDS_LOG_POPUP_COMPAREWITHPREVIOUS, IDI_DIFF);\r
                                //popup.AppendMenuIcon(ID_BLAMEWITHPREVIOUS, IDS_LOG_POPUP_BLAMEWITHPREVIOUS, IDI_BLAME);\r
                                popup.AppendMenu(MF_SEPARATOR, NULL);\r
                        }\r
@@ -1028,12 +1103,24 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        \r
                        CString str;\r
                        str.Format(_T("Reset %s to this"),g_Git.GetCurrentBranch());\r
-                       popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\r
-                       popup.AppendMenuIcon(ID_SWITCHTOREV, _T("Switch/Checkout to this") , IDI_SWITCH);\r
-                       popup.AppendMenuIcon(ID_CREATE_BRANCH, _T("Create Branch at this version") , IDI_COPY);\r
-                       popup.AppendMenuIcon(ID_CREATE_TAG, _T("Create Tag at this version"), IDI_COPY);\r
-                       popup.AppendMenuIcon(ID_CHERRY_PICK, _T("Cherry Pick this version"), IDI_EXPORT);\r
-                       popup.AppendMenuIcon(ID_EXPORT, _T("Export this version"), IDI_EXPORT);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_RESET))\r
+                               popup.AppendMenuIcon(ID_RESET,str,IDI_REVERT);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_SWITCHTOREV))\r
+                               popup.AppendMenuIcon(ID_SWITCHTOREV, _T("Switch/Checkout to this") , IDI_SWITCH);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_BRANCH))\r
+                               popup.AppendMenuIcon(ID_CREATE_BRANCH, _T("Create Branch at this version") , IDI_COPY);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_CREATE_TAG))\r
+                               popup.AppendMenuIcon(ID_CREATE_TAG, _T("Create Tag at this version"), IDI_COPY);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_CHERRY_PICK))\r
+                               popup.AppendMenuIcon(ID_CHERRY_PICK, _T("Cherry Pick this version"), IDI_EXPORT);\r
+\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_EXPORT))\r
+                               popup.AppendMenuIcon(ID_EXPORT, _T("Export this version"), IDI_EXPORT); \r
                        \r
 \r
                        popup.AppendMenu(MF_SEPARATOR, NULL);\r
@@ -1043,12 +1130,14 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                        bool bAddSeparator = false;\r
                        if (IsSelectionContinuous() || (GetSelectedCount() == 2))\r
                        {\r
-                               popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_COMPARETWO))\r
+                                       popup.AppendMenuIcon(ID_COMPARETWO, IDS_LOG_POPUP_COMPARETWO, IDI_DIFF);\r
                        }\r
                        if (GetSelectedCount() == 2)\r
                        {\r
                                //popup.AppendMenuIcon(ID_BLAMETWO, IDS_LOG_POPUP_BLAMEREVS, IDI_BLAME);\r
-                               popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);\r
+                               if(m_ContextMenuMask&GetContextMenuBit(ID_GNUDIFF2))\r
+                                       popup.AppendMenuIcon(ID_GNUDIFF2, IDS_LOG_POPUP_GNUDIFF, IDI_DIFF);\r
                                bAddSeparator = true;\r
                        }\r
                        if (m_hasWC)\r
@@ -1077,13 +1166,17 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point)
                \r
                if (GetSelectedCount() == 1)\r
                {\r
-                       popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash"));\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_COPYHASH))\r
+                               popup.AppendMenuIcon(ID_COPYHASH, _T("Copy Commit Hash"));\r
                }\r
                if (GetSelectedCount() != 0)\r
                {\r
-                       popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
+                       if(m_ContextMenuMask&GetContextMenuBit(ID_COPYCLIPBOARD))\r
+                               popup.AppendMenuIcon(ID_COPYCLIPBOARD, IDS_LOG_POPUP_COPYTOCLIPBOARD);\r
                }\r
-               popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
+\r
+               if(m_ContextMenuMask&GetContextMenuBit(ID_FINDENTRY))\r
+                       popup.AppendMenuIcon(ID_FINDENTRY, IDS_LOG_POPUP_FIND);\r
 \r
                int cmd = popup.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN | TPM_NONOTIFY, point.x, point.y, this, 0);\r
 //             DialogEnableWindow(IDOK, FALSE);\r
@@ -1301,12 +1394,12 @@ void CGitLogListBase::OnLvnOdfinditemLoglist(NMHDR *pNMHDR, LRESULT *pResult)
        *pResult = -1;\r
 }\r
 \r
-int CGitLogListBase::FillGitLog(CTGitPath *path,int info)\r
+int CGitLogListBase::FillGitLog(CTGitPath *path,int info,CString *from,CString *to)\r
 {\r
        ClearText();\r
 \r
        this->m_logEntries.ClearAll();\r
-       this->m_logEntries.ParserFromLog(path,-1,info);\r
+       this->m_logEntries.ParserFromLog(path,-1,info,from,to);\r
 \r
        //this->m_logEntries.ParserFromLog();\r
        SetItemCountEx(this->m_logEntries.size());\r
@@ -1315,8 +1408,16 @@ int CGitLogListBase::FillGitLog(CTGitPath *path,int info)
 \r
        for(unsigned int i=0;i<m_logEntries.size();i++)\r
        {\r
-               m_logEntries[i].m_IsFull=TRUE;\r
-               this->m_arShownList.Add(&m_logEntries[i]);\r
+               if(m_IsOldFirst)\r
+               {\r
+                       m_logEntries[m_logEntries.size()-i-1].m_IsFull=TRUE;\r
+                       this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]);\r
+               \r
+               }else\r
+               {\r
+                       m_logEntries[i].m_IsFull=TRUE;\r
+                       this->m_arShownList.Add(&m_logEntries[i]);\r
+               }\r
        }\r
 \r
     if(path)\r
@@ -1357,8 +1458,16 @@ int CGitLogListBase::FillGitShortLog()
        this->m_arShownList.RemoveAll();\r
 \r
        for(unsigned int i=0;i<m_logEntries.size();i++)\r
-               this->m_arShownList.Add(&m_logEntries[i]);\r
+       {\r
+               if(this->m_IsOldFirst)\r
+               {\r
+                       this->m_arShownList.Add(&m_logEntries[m_logEntries.size()-1-i]);\r
 \r
+               }else\r
+               {\r
+                       this->m_arShownList.Add(&m_logEntries[i]);\r
+               }\r
+       }\r
        return 0;\r
 }\r
 \r
@@ -1937,7 +2046,13 @@ void CGitLogListBase::RemoveFilter()
 \r
        for (DWORD i=0; i<m_logEntries.size(); ++i)\r
        {\r
-               m_arShownList.Add(&m_logEntries[i]);\r
+               if(this->m_IsOldFirst)\r
+               {\r
+                       m_arShownList.Add(&m_logEntries[m_logEntries.size()-i-1]);\r
+               }else\r
+               {\r
+                       m_arShownList.Add(&m_logEntries[i]);\r
+               }\r
        }\r
 //     InterlockedExchange(&m_bNoDispUpdates, FALSE);\r
        DeleteAllItems();\r
index 6cfead5..659c881 100644 (file)
@@ -66,10 +66,16 @@ public:
        virtual ~CGitLogListBase();\r
        volatile LONG           m_bNoDispUpdates;\r
        BOOL m_IsIDReplaceAction;\r
+       BOOL m_IsOldFirst;\r
+       BOOL m_IsRebaseReplaceGraph;\r
+\r
+\r
        BOOL m_bStrictStopped;\r
        BOOL m_bShowBugtraqColumn;\r
        BOOL m_bSearchIndex;\r
        BOOL m_bCancelled;\r
+       unsigned __int64 m_ContextMenuMask;\r
+\r
        bool                            m_hasWC;\r
        GitRev                          m_wcRev;\r
        volatile LONG           m_bThreadRunning;\r
@@ -127,15 +133,20 @@ public:
        ID_CREATE_BRANCH,\r
        ID_CREATE_TAG,\r
        ID_SWITCHTOREV,\r
-       ID_RESET\r
+       ID_RESET,\r
+       ID_REBASE_PICK,\r
+       ID_REBASE_EDIT,\r
+       ID_REBASE_SQUASH,\r
+       ID_REBASE_SKIP,\r
        };\r
+       inline unsigned __int64 GetContextMenuBit(int i){ return ((unsigned __int64 )0x1)<<i ;}\r
        void InsertGitColumn();\r
        void ResizeAllListCtrlCols();\r
        void CopySelectionToClipBoard(bool hashonly=FALSE);\r
        void DiffSelectedRevWithPrevious();\r
        bool IsSelectionContinuous();\r
        int  FillGitShortLog();\r
-       int  FillGitLog(CTGitPath *path,int infomask=CGit::     LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE);\r
+       int  FillGitLog(CTGitPath *path,int infomask=CGit::     LOG_INFO_STAT| CGit::LOG_INFO_FILESTATE,CString *from=NULL,CString *to=NULL);\r
 \r
        inline int ShownCountWithStopped() const { return (int)m_arShownList.GetCount() + (m_bStrictStopped ? 1 : 0); }\r
        int FetchLogAsync(void * data=NULL);\r
index 08ff2f7..1b265d2 100644 (file)
@@ -104,12 +104,12 @@ int CLogDataVector::FetchFullInfo(int i)
        return at(i).SafeFetchFullInfo(&g_Git);
 }
 //CLogDataVector Class
-int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask)
+int CLogDataVector::ParserFromLog(CTGitPath *path ,int count ,int infomask,CString *from,CString *to)
 {
        BYTE_VECTOR log;
        GitRev rev;
        CString emptyhash;
-       g_Git.GetLog(log,emptyhash,path,count,infomask);
+       g_Git.GetLog(log,emptyhash,path,count,infomask,from,to);
 
        CString begin;
        begin.Format(_T("#<%c>"),LOG_REV_ITEM_BEGIN);
index 6658bd4..a96aeba 100644 (file)
@@ -58,7 +58,8 @@ public:
                m_FirstFreeLane=0;\r
        }\r
        void ClearAll();\r
-       int  ParserFromLog(CTGitPath *path =NULL,int count = -1,int infomask=CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE);\r
+       int  ParserFromLog(CTGitPath *path =NULL,int count = -1,int infomask=CGit::LOG_INFO_STAT|CGit::LOG_INFO_FILESTATE,\r
+                                                                                        CString *from=NULL,CString *to=NULL);\r
        int  ParserShortLog(CTGitPath *path ,CString &hash,int count=-1 ,int mask=CGit::LOG_INFO_ONLY_HASH );\r
        int FetchFullInfo(int i);\r
 //     void AddFullInfo(\r
index b7e8514..83dfd50 100644 (file)
@@ -11,7 +11,7 @@
 IMPLEMENT_DYNAMIC(CProgressDlg, CResizableStandAloneDialog)\r
 \r
 CProgressDlg::CProgressDlg(CWnd* pParent /*=NULL*/)\r
-       : CResizableStandAloneDialog(CProgressDlg::IDD, pParent)\r
+       : CResizableStandAloneDialog(CProgressDlg::IDD, pParent), m_bShowCommand(true)\r
 {\r
 \r
 }\r
@@ -50,7 +50,16 @@ BOOL CProgressDlg::OnInitDialog()
 \r
        m_Animate.Open(IDR_DOWNLOAD);\r
        \r
-       m_Log.SetWindowTextW(this->m_GitCmd+_T("\r\n\r\n"));\r
+       CString InitialText;\r
+       if ( !m_PreText.IsEmpty() )\r
+       {\r
+               InitialText = m_PreText + _T("\r\n");\r
+       }\r
+       if (m_bShowCommand)\r
+       {\r
+               InitialText += m_GitCmd+_T("\r\n\r\n");\r
+       }\r
+       m_Log.SetWindowTextW(InitialText);\r
        m_CurrentWork.SetWindowTextW(_T(""));\r
 \r
        m_pThread = AfxBeginThread(ProgressThreadEntry, this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);\r
index e2c0f0d..5a94665 100644 (file)
@@ -25,6 +25,8 @@ public:
        CWinThread*                             m_pThread;      \r
        volatile LONG                   m_bThreadRunning;\r
        DWORD                     m_GitStatus;\r
+       BOOL              m_bShowCommand;       // whether to display the command in the log window (default true)\r
+       CString           m_PreText;            // optional text to show in log window before running command\r
 protected:\r
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support\r
        static UINT ProgressThreadEntry(LPVOID pVoid);\r
diff --git a/src/TortoiseProc/RebaseDlg.cpp b/src/TortoiseProc/RebaseDlg.cpp
new file mode 100644 (file)
index 0000000..cab8be1
--- /dev/null
@@ -0,0 +1,1107 @@
+// RebaseDlg.cpp : implementation file\r
+//\r
+\r
+#include "stdafx.h"\r
+#include "TortoiseProc.h"\r
+#include "RebaseDlg.h"\r
+#include "AppUtils.h"\r
+#include "MessageBox.h"\r
+#include "UnicodeUtils.h"\r
+// CRebaseDlg dialog\r
+\r
+IMPLEMENT_DYNAMIC(CRebaseDlg, CResizableStandAloneDialog)\r
+\r
+CRebaseDlg::CRebaseDlg(CWnd* pParent /*=NULL*/)\r
+       : CResizableStandAloneDialog(CRebaseDlg::IDD, pParent)\r
+    , m_bPickAll(FALSE)\r
+    , m_bSquashAll(FALSE)\r
+    , m_bEditAll(FALSE)\r
+{\r
+       m_RebaseStage=CHOOSE_BRANCH;\r
+       m_CurrentRebaseIndex=-1;\r
+       m_bThreadRunning =FALSE;\r
+}\r
+\r
+CRebaseDlg::~CRebaseDlg()\r
+{\r
+}\r
+\r
+void CRebaseDlg::DoDataExchange(CDataExchange* pDX)\r
+{\r
+    CDialog::DoDataExchange(pDX);\r
+    DDX_Control(pDX, IDC_REBASE_PROGRESS, m_ProgressBar);\r
+    DDX_Control(pDX, IDC_STATUS_STATIC, m_CtrlStatusText);\r
+    DDX_Check(pDX, IDC_PICK_ALL, m_bPickAll);\r
+    DDX_Check(pDX, IDC_SQUASH_ALL, m_bSquashAll);\r
+    DDX_Check(pDX, IDC_EDIT_ALL, m_bEditAll);\r
+       DDX_Control(pDX, IDC_REBASE_SPLIT, m_wndSplitter);\r
+       DDX_Control(pDX,IDC_COMMIT_LIST,m_CommitList);\r
+       DDX_Control(pDX,IDC_REBASE_COMBOXEX_BRANCH, this->m_BranchCtrl);\r
+       DDX_Control(pDX,IDC_REBASE_COMBOXEX_UPSTREAM,   this->m_UpstreamCtrl);\r
+\r
+}\r
+\r
+\r
+BEGIN_MESSAGE_MAP(CRebaseDlg, CResizableStandAloneDialog)\r
+    ON_BN_CLICKED(IDC_PICK_ALL, &CRebaseDlg::OnBnClickedPickAll)\r
+    ON_BN_CLICKED(IDC_SQUASH_ALL, &CRebaseDlg::OnBnClickedSquashAll)\r
+    ON_BN_CLICKED(IDC_EDIT_ALL, &CRebaseDlg::OnBnClickedEditAll)\r
+    ON_BN_CLICKED(IDC_REBASE_SPLIT, &CRebaseDlg::OnBnClickedRebaseSplit)\r
+       ON_BN_CLICKED(IDC_REBASE_CONTINUE,OnBnClickedContinue)\r
+       ON_BN_CLICKED(IDC_REBASE_ABORT,  OnBnClickedAbort)\r
+       ON_WM_SIZE()\r
+       ON_CBN_SELCHANGE(IDC_REBASE_COMBOXEX_BRANCH,   &CRebaseDlg::OnCbnSelchangeBranch)\r
+       ON_CBN_SELCHANGE(IDC_REBASE_COMBOXEX_UPSTREAM, &CRebaseDlg::OnCbnSelchangeUpstream)\r
+       ON_MESSAGE(MSG_REBASE_UPDATE_UI, OnRebaseUpdateUI)\r
+END_MESSAGE_MAP()\r
+\r
+void CRebaseDlg::AddRebaseAnchor()\r
+{\r
+       AddAnchor(IDC_REBASE_TAB,TOP_LEFT,BOTTOM_RIGHT);\r
+       AddAnchor(IDC_COMMIT_LIST,TOP_LEFT, TOP_RIGHT);\r
+       AddAnchor(IDC_REBASE_SPLIT,TOP_LEFT, TOP_RIGHT);\r
+       AddAnchor(IDC_STATUS_STATIC, BOTTOM_LEFT,BOTTOM_RIGHT);\r
+       AddAnchor(IDC_REBASE_CONTINUE,BOTTOM_RIGHT);\r
+       AddAnchor(IDC_REBASE_ABORT, BOTTOM_RIGHT);\r
+       AddAnchor(IDC_REBASE_PROGRESS,BOTTOM_LEFT, BOTTOM_RIGHT);\r
+       AddAnchor(IDC_PICK_ALL,TOP_LEFT);\r
+       AddAnchor(IDC_SQUASH_ALL,TOP_LEFT);\r
+       AddAnchor(IDC_EDIT_ALL,TOP_LEFT);       \r
+       AddAnchor(IDC_REBASE_COMBOXEX_UPSTREAM,TOP_LEFT);\r
+       AddAnchor(IDC_REBASE_COMBOXEX_BRANCH,TOP_LEFT);\r
+       AddAnchor(IDC_REBASE_STATIC_UPSTREAM,TOP_LEFT);\r
+       AddAnchor(IDC_REBASE_STATIC_BRANCH,TOP_LEFT);\r
+       \r
+}\r
+\r
+BOOL CRebaseDlg::OnInitDialog()\r
+{\r
+       CResizableStandAloneDialog::OnInitDialog();\r
+\r
+       CRect rectDummy;\r
+       //IDC_REBASE_DUMY_TAB\r
+       \r
+       GetClientRect(m_DlgOrigRect);\r
+       m_CommitList.GetClientRect(m_CommitListOrigRect);\r
+\r
+       CWnd *pwnd=this->GetDlgItem(IDC_REBASE_DUMY_TAB);\r
+       pwnd->GetWindowRect(&rectDummy);\r
+\r
+       rectDummy.top-=20;\r
+       rectDummy.bottom-=20;\r
+\r
+       rectDummy.left-=5;\r
+       rectDummy.right-=5;\r
+       \r
+       if (!m_ctrlTabCtrl.Create(CMFCTabCtrl::STYLE_FLAT, rectDummy, this, IDC_REBASE_TAB))\r
+       {\r
+               TRACE0("Failed to create output tab window\n");\r
+               return FALSE;      // fail to create\r
+       }\r
+       m_ctrlTabCtrl.SetResizeMode(CMFCTabCtrl::RESIZE_NO);\r
+       // Create output panes:\r
+       //const DWORD dwStyle = LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;\r
+       DWORD dwStyle =LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP |LVS_SINGLESEL |WS_CHILD | WS_VISIBLE;\r
+\r
+       if (! this->m_FileListCtrl.Create(dwStyle,rectDummy,&this->m_ctrlTabCtrl,0) )\r
+       {\r
+               TRACE0("Failed to create output windows\n");\r
+               return FALSE;      // fail to create\r
+       }\r
+\r
+       if( ! this->m_LogMessageCtrl.Create(_T("Scintilla"),_T("source"),0,rectDummy,&m_ctrlTabCtrl,0,0) )\r
+       {\r
+               TRACE0("Failed to create log message control");\r
+               return FALSE;\r
+       }\r
+       m_LogMessageCtrl.Init(0);\r
+\r
+       dwStyle = LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;\r
+\r
+       if (!m_wndOutputRebase.Create(_T("Scintilla"),_T("source"),0,rectDummy, &m_ctrlTabCtrl, 0,0) )\r
+       {\r
+               TRACE0("Failed to create output windows\n");\r
+               return -1;      // fail to create\r
+       }\r
+       m_wndOutputRebase.Init(0);\r
+       m_wndOutputRebase.Call(SCI_SETREADONLY, TRUE);\r
+       \r
+       m_tooltips.Create(this);\r
+\r
+       m_FileListCtrl.Init(SVNSLC_COLEXT | SVNSLC_COLSTATUS |IDS_STATUSLIST_COLADD|IDS_STATUSLIST_COLDEL , _T("RebaseDlg"),(SVNSLC_POPALL ^ SVNSLC_POPCOMMIT),false);\r
+\r
+       m_ctrlTabCtrl.AddTab(&m_FileListCtrl,_T("Conflict File"));\r
+       m_ctrlTabCtrl.AddTab(&m_LogMessageCtrl,_T("Commit Message"),1);\r
+       m_ctrlTabCtrl.AddTab(&m_wndOutputRebase,_T("Log"),2);\r
+       AddRebaseAnchor();\r
+\r
+\r
+       EnableSaveRestore(_T("RebaseDlg"));\r
+\r
+       DWORD yPos = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\RebaseDlgSizer"));\r
+       RECT rcDlg, rcLogMsg, rcFileList;\r
+       GetClientRect(&rcDlg);\r
+       m_CommitList.GetWindowRect(&rcLogMsg);\r
+       ScreenToClient(&rcLogMsg);\r
+       this->m_ctrlTabCtrl.GetWindowRect(&rcFileList);\r
+       ScreenToClient(&rcFileList);\r
+       if (yPos)\r
+       {\r
+               RECT rectSplitter;\r
+               m_wndSplitter.GetWindowRect(&rectSplitter);\r
+               ScreenToClient(&rectSplitter);\r
+               int delta = yPos - rectSplitter.top;\r
+               if ((rcLogMsg.bottom + delta > rcLogMsg.top)&&(rcLogMsg.bottom + delta < rcFileList.bottom - 30))\r
+               {\r
+                       m_wndSplitter.SetWindowPos(NULL, 0, yPos, 0, 0, SWP_NOSIZE);\r
+                       DoSize(delta);\r
+               }\r
+       }\r
+\r
+       if( this->m_RebaseStage == CHOOSE_BRANCH)\r
+       {\r
+               this->LoadBranchInfo();\r
+\r
+       }else\r
+       {\r
+               this->m_BranchCtrl.EnableWindow(FALSE);\r
+               this->m_UpstreamCtrl.EnableWindow(FALSE);\r
+       }\r
+\r
+       m_CommitList.m_IsIDReplaceAction = TRUE;\r
+//     m_CommitList.m_IsOldFirst = TRUE;\r
+       m_CommitList.m_IsRebaseReplaceGraph = TRUE;\r
+\r
+       m_CommitList.DeleteAllItems();\r
+       m_CommitList.InsertGitColumn();\r
+\r
+       FetchLogList();\r
+       SetContinueButtonText();\r
+       this->SetControlEnable();\r
+\r
+       m_CommitList.m_ContextMenuMask &= ~(m_CommitList.GetContextMenuBit(CGitLogListBase::ID_CHERRY_PICK)|\r
+                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_SWITCHTOREV)|\r
+                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_RESET)|\r
+                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REVERTREV)|\r
+                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REVERTTOREV));\r
+\r
+       return TRUE;\r
+}\r
+// CRebaseDlg message handlers\r
+\r
+void CRebaseDlg::OnBnClickedPickAll()\r
+{\r
+    // TODO: Add your control notification handler code here\r
+       this->UpdateData();\r
+       if(this->m_bPickAll)\r
+               this->SetAllRebaseAction(CTGitPath::LOGACTIONS_REBASE_PICK);\r
+\r
+       this->m_bEditAll=FALSE;\r
+       this->m_bSquashAll=FALSE;\r
+       this->UpdateData(FALSE);\r
+       \r
+}\r
+\r
+void CRebaseDlg::OnBnClickedSquashAll()\r
+{\r
+    // TODO: Add your control notification handler code here\r
+       this->UpdateData();\r
+       if(this->m_bSquashAll)\r
+               this->SetAllRebaseAction(CTGitPath::LOGACTIONS_REBASE_SQUASH);\r
+\r
+       this->m_bEditAll=FALSE;\r
+       this->m_bPickAll=FALSE;\r
+       this->UpdateData(FALSE);\r
+\r
+}\r
+\r
+void CRebaseDlg::OnBnClickedEditAll()\r
+{\r
+    // TODO: Add your control notification handler code here\r
+       this->UpdateData();\r
+       if( this->m_bEditAll )\r
+               this->SetAllRebaseAction(CTGitPath::LOGACTIONS_REBASE_EDIT);\r
+\r
+       this->m_bPickAll=FALSE;\r
+       this->m_bSquashAll=FALSE;\r
+       this->UpdateData(FALSE);\r
+\r
+}\r
+\r
+void CRebaseDlg::SetAllRebaseAction(int action)\r
+{\r
+       for(int i=0;i<this->m_CommitList.m_logEntries.size();i++)\r
+       {\r
+               m_CommitList.m_logEntries[i].m_Action=action;\r
+       }\r
+       m_CommitList.Invalidate();\r
+}\r
+\r
+void CRebaseDlg::OnBnClickedRebaseSplit()\r
+{\r
+       this->UpdateData();\r
+    // TODO: Add your control notification handler code here\r
+}\r
+\r
+LRESULT CRebaseDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+       switch (message) {\r
+       case WM_NOTIFY:\r
+               if (wParam == IDC_REBASE_SPLIT)\r
+               { \r
+                       SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;\r
+                       DoSize(pHdr->delta);\r
+               }\r
+               break;\r
+       }\r
+\r
+       return __super::DefWindowProc(message, wParam, lParam);\r
+}\r
+\r
+void CRebaseDlg::DoSize(int delta)\r
+{\r
+       \r
+       this->RemoveAllAnchors();\r
+\r
+       CSplitterControl::ChangeHeight(GetDlgItem(IDC_COMMIT_LIST), delta, CW_TOPALIGN);\r
+       //CSplitterControl::ChangeHeight(GetDlgItem(), delta, CW_TOPALIGN);\r
+       CSplitterControl::ChangeHeight(GetDlgItem(IDC_REBASE_TAB), -delta, CW_BOTTOMALIGN);\r
+       //CSplitterControl::ChangeHeight(GetDlgItem(), -delta, CW_BOTTOMALIGN);\r
+       CSplitterControl::ChangePos(GetDlgItem(IDC_SQUASH_ALL),0,delta);\r
+       CSplitterControl::ChangePos(GetDlgItem(IDC_PICK_ALL),0,delta);\r
+       CSplitterControl::ChangePos(GetDlgItem(IDC_EDIT_ALL),0,delta);\r
+       \r
+       this->AddRebaseAnchor();\r
+       // adjust the minimum size of the dialog to prevent the resizing from\r
+       // moving the list control too far down.\r
+       CRect rcLogMsg;\r
+       m_CommitList.GetClientRect(rcLogMsg);\r
+       SetMinTrackSize(CSize(m_DlgOrigRect.Width(), m_DlgOrigRect.Height()-m_CommitListOrigRect.Height()+rcLogMsg.Height()));\r
+\r
+       SetSplitterRange();\r
+//     m_CommitList.Invalidate();\r
+\r
+//     GetDlgItem(IDC_LOGMESSAGE)->Invalidate();\r
+\r
+       this->m_ctrlTabCtrl.Invalidate();\r
+       this->m_CommitList.Invalidate();\r
+       this->m_FileListCtrl.Invalidate();\r
+       this->m_LogMessageCtrl.Invalidate();\r
+\r
+}\r
+\r
+void CRebaseDlg::SetSplitterRange()\r
+{\r
+       if ((m_CommitList)&&(m_ctrlTabCtrl))\r
+       {\r
+               CRect rcTop;\r
+               m_CommitList.GetWindowRect(rcTop);\r
+               ScreenToClient(rcTop);\r
+               CRect rcMiddle;\r
+               m_ctrlTabCtrl.GetWindowRect(rcMiddle);\r
+               ScreenToClient(rcMiddle);\r
+               if (rcMiddle.Height() && rcMiddle.Width())\r
+                       m_wndSplitter.SetRange(rcTop.top+60, rcMiddle.bottom-80);\r
+       }\r
+}\r
+\r
+void CRebaseDlg::OnSize(UINT nType,int cx, int cy)\r
+{\r
+        // first, let the resizing take place\r
+    __super::OnSize(nType, cx, cy);\r
+\r
+    //set range\r
+    SetSplitterRange();\r
+}\r
+\r
+void CRebaseDlg::SaveSplitterPos()\r
+{\r
+       if (!IsIconic())\r
+       {\r
+               CRegDWORD regPos = CRegDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\RebaseDlgSizer"));\r
+               RECT rectSplitter;\r
+               m_wndSplitter.GetWindowRect(&rectSplitter);\r
+               ScreenToClient(&rectSplitter);\r
+               regPos = rectSplitter.top;\r
+       }\r
+}\r
+\r
+void CRebaseDlg::LoadBranchInfo()\r
+{\r
+       m_BranchCtrl.SetMaxHistoryItems(0x7FFFFFFF);\r
+       m_UpstreamCtrl.SetMaxHistoryItems(0x7FFFFFFF);\r
+\r
+       STRING_VECTOR list;\r
+       list.clear();\r
+       int current;\r
+       g_Git.GetBranchList(list,&current,CGit::BRANCH_ALL);\r
+       m_BranchCtrl.AddString(list);\r
+       m_UpstreamCtrl.AddString(list);\r
+\r
+       m_BranchCtrl.SetCurSel(current);\r
+\r
+       AddBranchToolTips(&m_BranchCtrl);\r
+       AddBranchToolTips(&m_UpstreamCtrl);\r
+\r
+}\r
+\r
+void CRebaseDlg::OnCbnSelchangeBranch()\r
+{\r
+       FetchLogList();\r
+}\r
+\r
+void CRebaseDlg::OnCbnSelchangeUpstream()\r
+{\r
+       FetchLogList();\r
+}\r
+\r
+void CRebaseDlg::FetchLogList()\r
+{\r
+       m_CommitList.Clear();\r
+       this->m_CommitList.FillGitLog(NULL,0,&m_UpstreamCtrl.GetString(),&m_BranchCtrl.GetString());\r
+       if( m_CommitList.GetItemCount() == 0 )\r
+               m_CommitList.ShowText(_T("Nothing Rebase"));\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
+               {\r
+                       m_CommitList.Clear();\r
+                       m_CommitList.ShowText(_T("Nothing Rebase"));\r
+               }\r
+       }\r
+#endif\r
+\r
+       m_tooltips.Pop();\r
+       AddBranchToolTips(&this->m_BranchCtrl);\r
+       AddBranchToolTips(&this->m_UpstreamCtrl);\r
+       \r
+       for(int i=0;i<m_CommitList.m_logEntries.size();i++)\r
+       {\r
+               m_CommitList.m_logEntries[i].m_Action = CTGitPath::LOGACTIONS_REBASE_PICK;\r
+       }\r
+       \r
+       m_CommitList.Invalidate();\r
+\r
+       if(m_CommitList.m_IsOldFirst)\r
+               this->m_CurrentRebaseIndex = -1;\r
+       else\r
+               this->m_CurrentRebaseIndex = m_CommitList.m_logEntries.size();\r
+       \r
+}\r
+\r
+void CRebaseDlg::AddBranchToolTips(CHistoryCombo *pBranch)\r
+{\r
+       if(pBranch)\r
+       {\r
+               CString text=pBranch->GetString();\r
+               CString tooltip;\r
+               BYTE_VECTOR data;\r
+               g_Git.GetLog(data,text,NULL,1,0);\r
+               GitRev rev;\r
+               rev.ParserFromLog(data);\r
+               tooltip.Format(_T("CommitHash:%s\nCommit by: %s  %s\n <b>%s</b> \n %s"),\r
+                       rev.m_CommitHash,\r
+                       rev.m_AuthorName,\r
+                       CAppUtils::FormatDateAndTime(rev.m_AuthorDate,DATE_LONGDATE),\r
+                       rev.m_Subject,\r
+                       rev.m_Body);\r
+\r
+               pBranch->DisableTooltip();\r
+               this->m_tooltips.AddTool(pBranch->GetComboBoxCtrl(),tooltip);\r
+       }\r
+}\r
+\r
+BOOL CRebaseDlg::PreTranslateMessage(MSG*pMsg)\r
+{\r
+       m_tooltips.RelayEvent(pMsg);\r
+       return CResizableStandAloneDialog::PreTranslateMessage(pMsg);\r
+}\r
+int CRebaseDlg::CheckRebaseCondition()\r
+{\r
+       this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+\r
+       if( !g_Git.CheckCleanWorkTree()  )\r
+       {\r
+               CMessageBox::Show(NULL,_T("Rebase Need Clean Working Tree"),_T("TortoiseGit"),MB_OK);\r
+               return -1;\r
+       }\r
+       //Todo Check $REBASE_ROOT\r
+       //Todo Check $DOTEST\r
+\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
+       //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(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 ||\r
+       //              echo "detached HEAD" > "$DOTEST"/head-name\r
+\r
+       cmd.Format(_T("git.exe update-ref ORIG_HEAD HEAD"));\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+       {\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
+       cmd.Format(_T("git.exe rev-parse %s"),this->m_UpstreamCtrl.GetString());\r
+       if(g_Git.Run(cmd,&this->m_OrigUpstreamHash,CP_UTF8))\r
+       {\r
+               this->AddLogString(m_OrigUpstreamHash);\r
+               return -1;\r
+       }\r
+\r
+       cmd.Format(_T("git.exe rev-parse %s"),this->m_BranchCtrl.GetString());\r
+       if(g_Git.Run(cmd,&this->m_OrigBranchHash,CP_UTF8))\r
+       {\r
+               this->AddLogString(m_OrigBranchHash);\r
+               return -1;\r
+       }\r
+\r
+       this->AddLogString(_T("Start Rebase\r\n"));\r
+       return 0;\r
+}\r
+int  CRebaseDlg::VerifyNoConflict()\r
+{\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
+               CMessageBox::Show(NULL,_T("There are conflict file, you should mark it resolve"),_T("TortoiseGit"),MB_OK);\r
+               return -1;\r
+       }\r
+       return 0;\r
+\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
+       if( m_RebaseStage == REBASE_FINISH )\r
+       {\r
+               CString cmd,out;\r
+               cmd.Format(_T("git branch -f %s"),this->m_BranchCtrl.GetString());\r
+               if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               {\r
+                       AddLogString(out);\r
+                       return ;\r
+               }\r
+               cmd.Format(_T("git reset --hard %s"),this->m_OrigUpstreamHash);\r
+               if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               {\r
+                       AddLogString(out);\r
+                       return ;\r
+               }\r
+               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
+               if(this->CheckNextCommitIsSquash())\r
+               {//next commit is not squash;\r
+                       m_RebaseStage = REBASE_SQUASH_EDIT;\r
+                       this->OnRebaseUpdateUI(0,0);\r
+                       this->UpdateCurrentStatus();\r
+                       return ;\r
+\r
+               }\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
+               CString out =_T("");\r
+               CString cmd;\r
+               cmd.Format(_T("git.exe commit -C %s"), curRev->m_CommitHash);\r
+\r
+               if(g_Git.Run(cmd,&out,CP_UTF8))\r
+               {\r
+                       if(!g_Git.CheckCleanWorkTree())\r
+                       {\r
+                               CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               AddLogString(out);\r
+               this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+               if( curRev->m_Action & CTGitPath::LOGACTIONS_REBASE_EDIT)\r
+               {\r
+                       m_RebaseStage=REBASE_EDIT;\r
+                       this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_MESSAGE);\r
+                       this->UpdateCurrentStatus();\r
+                       return;\r
+               }\r
+               else\r
+               {\r
+                       m_RebaseStage=REBASE_CONTINUE;\r
+                       curRev->m_Action|=CTGitPath::LOGACTIONS_REBASE_DONE;\r
+                       this->UpdateCurrentStatus();\r
+               }\r
+               \r
+       }\r
+\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
+       \r
+               str=this->m_LogMessageCtrl.GetText();\r
+               if(str.Trim().IsEmpty())\r
+               {\r
+                       CMessageBox::Show(NULL,_T("Commit Message Is Empty"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+                               return;\r
+               }\r
+\r
+               CString tempfile=::GetTempFile();\r
+               CFile file(tempfile,CFile::modeReadWrite|CFile::modeCreate );\r
+               CStringA log=CUnicodeUtils::GetUTF8( str);\r
+               file.Write(log,log.GetLength());\r
+               //file.WriteString(m_sLogMessage);\r
+               file.Close();\r
+       \r
+               CString out,cmd;\r
+               \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
+                       if(!g_Git.CheckCleanWorkTree())\r
+                       {\r
+                               CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK|MB_ICONERROR);\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               CFile::Remove(tempfile);\r
+               AddLogString(out);\r
+               this->m_ctrlTabCtrl.SetActiveTab(REBASE_TAB_LOG);\r
+               m_RebaseStage=REBASE_CONTINUE;\r
+               curRev->m_Action|=CTGitPath::LOGACTIONS_REBASE_DONE;\r
+               this->UpdateCurrentStatus();\r
+       }\r
+\r
+\r
+       InterlockedExchange(&m_bThreadRunning, TRUE);\r
+       SetControlEnable();\r
+       \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::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
+               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
+       switch(this->m_RebaseStage)\r
+       {\r
+       case CHOOSE_BRANCH:\r
+       case CHOOSE_COMMIT_PICK_MODE:\r
+               Text = _T("Start");\r
+               break;\r
+\r
+       case REBASE_START:\r
+       case REBASE_CONTINUE:\r
+       case REBASE_SQUASH_CONFLICT:\r
+               Text = _T("Continue");\r
+               break;\r
+\r
+       case REBASE_CONFLICT:\r
+               Text = _T("Commit");\r
+               break;\r
+       case REBASE_EDIT:\r
+               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
+               break;\r
+       }\r
+       this->GetDlgItem(IDC_REBASE_CONTINUE)->SetWindowText(Text);\r
+}\r
+\r
+void CRebaseDlg::SetControlEnable()\r
+{\r
+       switch(this->m_RebaseStage)\r
+       {\r
+       case CHOOSE_BRANCH:\r
+       case CHOOSE_COMMIT_PICK_MODE:\r
+               \r
+               this->GetDlgItem(IDC_PICK_ALL)->EnableWindow(TRUE);\r
+               this->GetDlgItem(IDC_EDIT_ALL)->EnableWindow(TRUE);\r
+               this->GetDlgItem(IDC_SQUASH_ALL)->EnableWindow(TRUE);\r
+               this->GetDlgItem(IDC_REBASE_COMBOXEX_BRANCH)->EnableWindow(TRUE);\r
+               this->GetDlgItem(IDC_REBASE_COMBOXEX_UPSTREAM)->EnableWindow(TRUE);\r
+               //this->m_CommitList.m_IsEnableRebaseMenu=TRUE;\r
+               this->m_CommitList.m_ContextMenuMask |= m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_PICK)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_SQUASH)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_EDIT)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_SKIP);\r
+               break;\r
+\r
+       case REBASE_START:\r
+       case REBASE_CONTINUE:\r
+       case REBASE_ABORT:\r
+       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
+               this->GetDlgItem(IDC_REBASE_COMBOXEX_BRANCH)->EnableWindow(FALSE);\r
+               this->GetDlgItem(IDC_REBASE_COMBOXEX_UPSTREAM)->EnableWindow(FALSE);\r
+               //this->m_CommitList.m_IsEnableRebaseMenu=FALSE;\r
+               this->m_CommitList.m_ContextMenuMask &= ~(m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_PICK)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_SQUASH)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_EDIT)|\r
+                                                                                               m_CommitList.GetContextMenuBit(CGitLogListBase::ID_REBASE_SKIP));\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
+       else\r
+               index = m_CommitList.GetItemCount()-m_CurrentRebaseIndex;\r
+\r
+       m_ProgressBar.SetRange(1,m_CommitList.GetItemCount());\r
+       m_ProgressBar.SetPos(index);\r
+\r
+       if(m_CurrentRebaseIndex>0 && m_CurrentRebaseIndex< m_CommitList.GetItemCount())\r
+       {\r
+               CString text;\r
+               text.Format(_T("Rebasing...(%d/%d)"),index,m_CommitList.GetItemCount());\r
+               m_CtrlStatusText.SetWindowText(text);\r
+\r
+       }\r
+\r
+       GitRev *prevRev=NULL, *curRev=NULL;\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
+       for(int i=0;i<m_CommitList.m_arShownList.GetSize();i++)\r
+       {\r
+               prevRev=(GitRev*)m_CommitList.m_arShownList[i];\r
+               if(prevRev->m_Action & CTGitPath::LOGACTIONS_REBASE_CURRENT)\r
+               {       \r
+                       prevRev->m_Action &= ~ CTGitPath::LOGACTIONS_REBASE_CURRENT;\r
+                       m_CommitList.GetItemRect(i,&rect,LVIR_BOUNDS);\r
+                       m_CommitList.InvalidateRect(rect);\r
+               }\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
+{\r
+       if( m_CurrentRebaseIndex < 0)\r
+       {\r
+               if(m_CommitList.m_IsOldFirst)\r
+                       m_RebaseStage = CRebaseDlg::REBASE_START;\r
+               else\r
+                       m_RebaseStage = CRebaseDlg::REBASE_FINISH;\r
+       }\r
+\r
+       if( m_CurrentRebaseIndex == m_CommitList.m_arShownList.GetSize())\r
+       {\r
+               if(m_CommitList.m_IsOldFirst)\r
+                       m_RebaseStage = CRebaseDlg::REBASE_FINISH;\r
+               else\r
+                       m_RebaseStage = CRebaseDlg::REBASE_START;\r
+       }\r
+\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::GetCurrentCommitID()\r
+{\r
+       if(m_CommitList.m_IsOldFirst)\r
+       {\r
+               return this->m_CurrentRebaseIndex+1;\r
+\r
+       }else\r
+       {\r
+               return m_CommitList.GetItemCount()-m_CurrentRebaseIndex;\r
+       }\r
+}\r
+\r
+int CRebaseDlg::DoRebase()\r
+{      \r
+       CString cmd,out;\r
+       if(m_CurrentRebaseIndex <0)\r
+               return 0;\r
+       if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() )\r
+               return 0;\r
+\r
+       GitRev *pRev = (GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+       int mode=pRev->m_Action & CTGitPath::LOGACTIONS_REBASE_MODE_MASK;\r
+       CString nocommit;\r
+\r
+       if( mode== CTGitPath::LOGACTIONS_REBASE_SKIP)\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
+       if(mode == CTGitPath::LOGACTIONS_REBASE_SQUASH)\r
+               nocommit=_T(" --no-commit ");\r
+\r
+       CString log;\r
+       log.Format(_T("%s %d:%s"),CTGitPath::GetActionName(mode),this->GetCurrentCommitID(),pRev->m_CommitHash);\r
+       AddLogString(log);\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
+                       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
+               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
+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
+               }else 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
+               }else\r
+                       break;\r
+               this->PostMessage(MSG_REBASE_UPDATE_UI);\r
+               //this->UpdateCurrentStatus();\r
+       }\r
+\r
+       InterlockedExchange(&m_bThreadRunning, FALSE);\r
+       this->PostMessage(MSG_REBASE_UPDATE_UI);\r
+       return ret;\r
+}\r
+\r
+void CRebaseDlg::ListConflictFile()\r
+{\r
+       this->m_FileListCtrl.Clear();   \r
+       CTGitPathList list;\r
+       CTGitPath path;\r
+       list.AddPath(path);\r
+\r
+       this->m_FileListCtrl.GetStatus(list,true);\r
+       this->m_FileListCtrl.Show(CTGitPath::LOGACTIONS_UNMERGED|CTGitPath::LOGACTIONS_MODIFIED,CTGitPath::LOGACTIONS_UNMERGED);\r
+       if( this->m_FileListCtrl.GetItemCount() == 0 )\r
+       {\r
+               \r
+       }\r
+}\r
+\r
+LRESULT CRebaseDlg::OnRebaseUpdateUI(WPARAM,LPARAM)\r
+{\r
+       UpdateCurrentStatus();\r
+       if(m_CurrentRebaseIndex <0)\r
+               return 0;\r
+       if(m_CurrentRebaseIndex >= m_CommitList.GetItemCount() )\r
+               return 0;\r
+       GitRev *curRev=(GitRev*)m_CommitList.m_arShownList[m_CurrentRebaseIndex];\r
+       \r
+       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
+               break;\r
+       case REBASE_EDIT:\r
+               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
+       return 0;\r
+}\r
+void CRebaseDlg::OnCancel()\r
+{\r
+       OnBnClickedAbort();\r
+}\r
+void CRebaseDlg::OnBnClickedAbort()\r
+{\r
+       CString cmd,out;\r
+       if(m_OrigUpstreamHash.IsEmpty())\r
+       {\r
+               this->OnCancel();\r
+       }\r
+       if(CMessageBox::Show(NULL,_T("Are you sure abort rebase"),_T("TortoiseGit"),MB_YESNO) != IDYES)\r
+               return;\r
+\r
+       cmd.Format(_T("git.exe reset --hard  %s"),this->m_OrigUpstreamHash.Left(40));\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+       {\r
+               AddLogString(out);\r
+               return ;\r
+       }\r
+       \r
+       cmd.Format(_T("git checkout -f %s"),this->m_BranchCtrl.GetString());\r
+       if(g_Git.Run(cmd,&out,CP_UTF8))\r
+       {\r
+               AddLogString(out);\r
+               return ;\r
+       }\r
+       \r
+       __super::OnCancel();\r
+}\r
diff --git a/src/TortoiseProc/RebaseDlg.h b/src/TortoiseProc/RebaseDlg.h
new file mode 100644 (file)
index 0000000..fbd6b6f
--- /dev/null
@@ -0,0 +1,129 @@
+#pragma once\r
+#include "afxcmn.h"\r
+#include "afxwin.h"\r
+#include "StandAloneDlg.h"\r
+#include "GitStatusListCtrl.h"\r
+#include "SciEdit.h"\r
+#include "SplitterControl.h"\r
+#include "HistoryCombo.h"\r
+#include "Balloon.h"\r
+#include "GitLogList.h"\r
+// CRebaseDlg dialog\r
+#define IDC_REBASE_TAB 0x1000000\r
+\r
+#define REBASE_TAB_CONFLICT  0\r
+#define REBASE_TAB_MESSAGE   1\r
+#define REBASE_TAB_LOG          2\r
+\r
+#define MSG_REBASE_UPDATE_UI   (WM_USER+151)\r
+\r
+class CRebaseDlg : public CResizableStandAloneDialog\r
+{\r
+       DECLARE_DYNAMIC(CRebaseDlg)\r
+\r
+public:\r
+       CRebaseDlg(CWnd* pParent = NULL);   // standard constructor\r
+       virtual ~CRebaseDlg();\r
+\r
+// Dialog Data\r
+       enum { IDD = IDD_REBASE };\r
+\r
+       enum REBASE_STAGE\r
+       {\r
+               CHOOSE_BRANCH,\r
+               CHOOSE_COMMIT_PICK_MODE,\r
+               REBASE_START,\r
+               REBASE_CONTINUE,\r
+               REBASE_ABORT,\r
+               REBASE_FINISH,\r
+               REBASE_CONFLICT,\r
+               REBASE_EDIT,\r
+               REBASE_SQUASH_EDIT,\r
+               REBASE_SQUASH_CONFLICT,\r
+       };\r
+\r
+protected:\r
+       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support\r
+       virtual BOOL OnInitDialog();\r
+       DECLARE_MESSAGE_MAP()\r
+       virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);\r
+       LRESULT OnRebaseUpdateUI(WPARAM wParam, LPARAM lParam);\r
+       void DoSize(int delta);\r
+       void AddRebaseAnchor();\r
+       void RemoveAnchor();\r
+\r
+       void SetSplitterRange();\r
+       void SaveSplitterPos();\r
+       \r
+       void LoadBranchInfo();\r
+       void FetchLogList();\r
+       void SetAllRebaseAction(int action);\r
+       void OnCancel();\r
+\r
+       CRect                           m_DlgOrigRect;\r
+       CRect                           m_CommitListOrigRect;\r
+       BOOL PreTranslateMessage(MSG* pMsg);\r
+\r
+       CSciEdit m_wndOutputRebase;\r
+       void SetContinueButtonText();\r
+       void SetControlEnable();\r
+       void UpdateProgress();\r
+       void UpdateCurrentStatus();\r
+       void ListConflictFile();\r
+       int  DoRebase();\r
+       volatile LONG           m_bThreadRunning;\r
+       int  RebaseThread();\r
+       static UINT RebaseThreadEntry(LPVOID pVoid){return ((CRebaseDlg *)pVoid)->RebaseThread();};\r
+       BOOL IsEnd();\r
+\r
+       CString m_OrigBranchHash;\r
+       CString m_OrigUpstreamHash;\r
+\r
+       int VerifyNoConflict();\r
+       CString GetRebaseModeName(int rebasemode);\r
+\r
+       CString m_SquashMessage;\r
+\r
+       int CheckNextCommitIsSquash();\r
+       int GetCurrentCommitID();\r
+\r
+public:\r
+   \r
+    afx_msg void OnBnClickedPickAll();\r
+    afx_msg void OnBnClickedSquashAll();\r
+    afx_msg void OnBnClickedEditAll();\r
+    afx_msg void OnBnClickedRebaseSplit();\r
+       afx_msg void OnSize(UINT nType, int cx, int cy);\r
+       afx_msg void OnCbnSelchangeBranch();\r
+       afx_msg void OnCbnSelchangeUpstream();\r
+       afx_msg void OnBnClickedContinue();\r
+       afx_msg void OnBnClickedAbort();\r
+\r
+    CProgressCtrl m_ProgressBar;\r
+    CStatic m_CtrlStatusText;\r
+       CBalloon                        m_tooltips;\r
+\r
+    BOOL m_bPickAll;\r
+    BOOL m_bSquashAll;\r
+    BOOL m_bEditAll;\r
+\r
+       CSplitterControl        m_wndSplitter;\r
+       CMFCTabCtrl m_ctrlTabCtrl;\r
+       CGitStatusListCtrl m_FileListCtrl;\r
+       CSciEdit                   m_LogMessageCtrl;\r
+       \r
+       CGitLogList                m_CommitList;\r
+\r
+       CHistoryCombo m_BranchCtrl;\r
+       CHistoryCombo m_UpstreamCtrl;\r
+\r
+       REBASE_STAGE       m_RebaseStage;\r
+\r
+       void AddBranchToolTips(CHistoryCombo *pBranch);\r
+       void AddLogString(CString str);\r
+       int      StartRebase();\r
+       int  CheckRebaseCondition();\r
+       int  m_CurrentRebaseIndex;\r
+       int  StateAction();\r
+       int  GoNext();\r
+};\r
index d1df39c..93091b8 100644 (file)
 IMPLEMENT_DYNAMIC(CSetLookAndFeelPage, ISettingsPropPage)\r
 CSetLookAndFeelPage::CSetLookAndFeelPage()\r
        : ISettingsPropPage(CSetLookAndFeelPage::IDD)\r
-       , m_bGetLockTop(FALSE)\r
        , m_bBlock(false)\r
 {\r
-       m_regTopmenu = CRegDWORD(_T("Software\\TortoiseGit\\ContextMenuEntries"), MENUCHECKOUT | MENUUPDATE | MENUCOMMIT);\r
+       m_regTopmenu = CRegDWORD(_T("Software\\TortoiseGit\\ContextMenuEntries"), MENUCLONE | MENUPUSH | MENUPULL | MENUCOMMIT);\r
        m_regTopmenuhigh = CRegDWORD(_T("Software\\TortoiseGit\\ContextMenuEntrieshigh"), 0);\r
 \r
        m_topmenu = unsigned __int64(DWORD(m_regTopmenuhigh))<<32;\r
        m_topmenu |= unsigned __int64(DWORD(m_regTopmenu));\r
 \r
-       m_regGetLockTop = CRegDWORD(_T("Software\\TortoiseGit\\GetLockTop"), TRUE);\r
-       m_bGetLockTop = m_regGetLockTop;\r
-\r
        m_regNoContextPaths = CRegString(_T("Software\\TortoiseGit\\NoContextPaths"), _T(""));\r
        m_sNoContextPaths = m_regNoContextPaths;\r
        m_sNoContextPaths.Replace(_T("\n"), _T("\r\n"));\r
@@ -54,7 +50,6 @@ void CSetLookAndFeelPage::DoDataExchange(CDataExchange* pDX)
 {\r
        ISettingsPropPage::DoDataExchange(pDX);\r
        DDX_Control(pDX, IDC_MENULIST, m_cMenuList);\r
-       DDX_Check(pDX, IDC_GETLOCKTOP, m_bGetLockTop);\r
        DDX_Text(pDX, IDC_NOCONTEXTPATHS, m_sNoContextPaths);\r
 }\r
 \r
@@ -91,40 +86,43 @@ BOOL CSetLookAndFeelPage::OnInitDialog()
        m_imgList.Create(16, 16, ILC_COLOR16 | ILC_MASK, 4, 1);\r
 \r
        m_bBlock = true;\r
-       InsertItem(IDS_MENUCHECKOUT, IDI_CHECKOUT, MENUCHECKOUT);\r
-       InsertItem(IDS_MENUUPDATE, IDI_UPDATE, MENUUPDATE);\r
+       InsertItem(IDS_MENUCLONE, IDI_CLONE, MENUCLONE);\r
+//     InsertItem(IDS_MENUUPDATE, IDI_UPDATE, MENUUPDATE);\r
+       InsertItem(IDS_MENUPULL, IDI_PULL, MENUPULL);\r
+       InsertItem(IDS_MENUFETCH, IDI_PULL, MENUFETCH);\r
+       InsertItem(IDS_MENUPUSH, IDI_PUSH, MENUPUSH);\r
        InsertItem(IDS_MENUCOMMIT, IDI_COMMIT, MENUCOMMIT);\r
        InsertItem(IDS_MENUDIFF, IDI_DIFF, MENUDIFF);\r
        InsertItem(IDS_MENUPREVDIFF, IDI_DIFF, MENUPREVDIFF);\r
-       InsertItem(IDS_MENUURLDIFF, IDI_DIFF, MENUURLDIFF);\r
+//     InsertItem(IDS_MENUURLDIFF, IDI_DIFF, MENUURLDIFF);\r
        InsertItem(IDS_MENULOG, IDI_LOG, MENULOG);\r
-       InsertItem(IDS_MENUREPOBROWSE, IDI_REPOBROWSE, MENUREPOBROWSE);\r
+//     InsertItem(IDS_MENUREPOBROWSE, IDI_REPOBROWSE, MENUREPOBROWSE);\r
        InsertItem(IDS_MENUSHOWCHANGED, IDI_SHOWCHANGED, MENUSHOWCHANGED);\r
-       InsertItem(IDS_MENUREVISIONGRAPH, IDI_REVISIONGRAPH, MENUREVISIONGRAPH);\r
+//     InsertItem(IDS_MENUREVISIONGRAPH, IDI_REVISIONGRAPH, MENUREVISIONGRAPH);\r
        InsertItem(IDS_MENUCONFLICT, IDI_CONFLICT, MENUCONFLICTEDITOR);\r
-       InsertItem(IDS_MENURESOLVE, IDI_RESOLVE, MENURESOLVE);\r
-       InsertItem(IDS_MENUUPDATEEXT, IDI_UPDATE, MENUUPDATEEXT);\r
+//     InsertItem(IDS_MENURESOLVE, IDI_RESOLVE, MENURESOLVE);\r
+//     InsertItem(IDS_MENUUPDATEEXT, IDI_UPDATE, MENUUPDATEEXT);\r
        InsertItem(IDS_MENURENAME, IDI_RENAME, MENURENAME);\r
        InsertItem(IDS_MENUREMOVE, IDI_DELETE, MENUREMOVE);\r
        InsertItem(IDS_MENUREVERT, IDI_REVERT, MENUREVERT);\r
        InsertItem(IDS_MENUDELUNVERSIONED, IDI_DELUNVERSIONED, MENUDELUNVERSIONED);\r
        InsertItem(IDS_MENUCLEANUP, IDI_CLEANUP, MENUCLEANUP);\r
-       InsertItem(IDS_MENU_LOCK, IDI_LOCK, MENULOCK);\r
-       InsertItem(IDS_MENU_UNLOCK, IDI_UNLOCK, MENUUNLOCK);\r
+//     InsertItem(IDS_MENU_LOCK, IDI_LOCK, MENULOCK);\r
+//     InsertItem(IDS_MENU_UNLOCK, IDI_UNLOCK, MENUUNLOCK);\r
        InsertItem(IDS_MENUBRANCH, IDI_COPY, MENUCOPY);\r
        InsertItem(IDS_MENUSWITCH, IDI_SWITCH, MENUSWITCH);\r
        InsertItem(IDS_MENUMERGE, IDI_MERGE, MENUMERGE);\r
        InsertItem(IDS_MENUEXPORT, IDI_EXPORT, MENUEXPORT);\r
-       InsertItem(IDS_MENURELOCATE, IDI_RELOCATE, MENURELOCATE);\r
+//     InsertItem(IDS_MENURELOCATE, IDI_RELOCATE, MENURELOCATE);\r
        InsertItem(IDS_MENUCREATEREPOS, IDI_CREATEREPOS, MENUCREATEREPOS);\r
        InsertItem(IDS_MENUADD, IDI_ADD, MENUADD);\r
-       InsertItem(IDS_MENUIMPORT, IDI_IMPORT, MENUIMPORT);\r
+//     InsertItem(IDS_MENUIMPORT, IDI_IMPORT, MENUIMPORT);\r
        InsertItem(IDS_MENUBLAME, IDI_BLAME, MENUBLAME);\r
        InsertItem(IDS_MENUIGNORE, IDI_IGNORE, MENUIGNORE);\r
        InsertItem(IDS_MENUCREATEPATCH, IDI_CREATEPATCH, MENUCREATEPATCH);\r
        InsertItem(IDS_MENUAPPLYPATCH, IDI_PATCH, MENUAPPLYPATCH);\r
        InsertItem(IDS_MENUPROPERTIES, IDI_PROPERTIES, MENUPROPERTIES);\r
-       InsertItem(IDS_MENUCLIPPASTE, IDI_CLIPPASTE, MENUCLIPPASTE);\r
+//     InsertItem(IDS_MENUCLIPPASTE, IDI_CLIPPASTE, MENUCLIPPASTE);\r
        m_bBlock = false;\r
 \r
        m_cMenuList.SetImageList(&m_imgList, LVSIL_SMALL);\r
@@ -153,7 +151,6 @@ BOOL CSetLookAndFeelPage::OnApply()
        UpdateData();\r
     Store ((DWORD)(m_topmenu & 0xFFFFFFFF),    m_regTopmenu);\r
     Store ((DWORD)(m_topmenu >> 32), m_regTopmenuhigh);\r
-    Store (m_bGetLockTop, m_regGetLockTop);\r
 \r
        m_sNoContextPaths.Replace(_T("\r"), _T(""));\r
        if (m_sNoContextPaths.Right(1).Compare(_T("\n"))!=0)\r
@@ -188,40 +185,42 @@ void CSetLookAndFeelPage::OnLvnItemchangedMenulist(NMHDR * /*pNMHDR*/, LRESULT *
        {\r
                int i=0;\r
                m_topmenu = 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCHECKOUT : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUUPDATE : 0;\r
+               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCLONE : 0;\r
+               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUPULL : 0;\r
+               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUFETCH : 0;\r
+               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUPUSH : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCOMMIT : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUDIFF : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUPREVDIFF : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUURLDIFF : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUURLDIFF : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENULOG : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREPOBROWSE : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREPOBROWSE : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUSHOWCHANGED : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREVISIONGRAPH : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREVISIONGRAPH : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCONFLICTEDITOR : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENURESOLVE : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUUPDATEEXT : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENURESOLVE : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUUPDATEEXT : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENURENAME : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREMOVE : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUREVERT : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUDELUNVERSIONED : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCLEANUP : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENULOCK : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUUNLOCK : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENULOCK : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUUNLOCK : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCOPY : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUSWITCH : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUMERGE : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUEXPORT : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENURELOCATE : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENURELOCATE : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCREATEREPOS : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUADD : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUIMPORT : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUIMPORT : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUBLAME : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUIGNORE : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCREATEPATCH : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUAPPLYPATCH : 0;\r
                m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUPROPERTIES : 0;\r
-               m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCLIPPASTE : 0;\r
+//             m_topmenu |= m_cMenuList.GetCheck(i++) ? MENUCLIPPASTE : 0;\r
        }\r
        *pResult = 0;\r
 }\r
index 258827e..022f625 100644 (file)
@@ -65,9 +65,6 @@ private:
        unsigned __int64        m_topmenu;\r
        bool                            m_bBlock;\r
        \r
-       CRegDWORD                       m_regGetLockTop;\r
-       BOOL                            m_bGetLockTop;\r
-\r
        CString                         m_sNoContextPaths;\r
        CRegString                      m_regNoContextPaths;\r
 };\r
index c729d20..e56b962 100644 (file)
@@ -116,6 +116,7 @@ BEGIN_MESSAGE_MAP(CSetOverlayPage, ISettingsPropPage)
        ON_EN_CHANGE(IDC_INCLUDEPATHS, OnChange)\r
        ON_BN_CLICKED(IDC_CACHEDEFAULT, &CSetOverlayPage::OnChange)\r
        ON_BN_CLICKED(IDC_CACHESHELL, &CSetOverlayPage::OnChange)\r
+       ON_BN_CLICKED(IDC_CACHESHELL2, &CSetOverlayPage::OnChange)\r
        ON_BN_CLICKED(IDC_CACHENONE, &CSetOverlayPage::OnChange)\r
        ON_BN_CLICKED(IDC_UNVERSIONEDASMODIFIED, &CSetOverlayPage::OnChange)\r
        ON_BN_CLICKED(IDC_SHOWEXCLUDEDASNORMAL, &CSetOverlayPage::OnChange)\r
@@ -139,6 +140,9 @@ BOOL CSetOverlayPage::OnInitDialog()
        case 2:\r
                CheckRadioButton(IDC_CACHEDEFAULT, IDC_CACHENONE, IDC_CACHESHELL);\r
                break;\r
+       case 3:\r
+               CheckRadioButton(IDC_CACHEDEFAULT, IDC_CACHENONE, IDC_CACHESHELL2);\r
+               break;\r
        }\r
        GetDlgItem(IDC_UNVERSIONEDASMODIFIED)->EnableWindow(m_dwCacheType == 1);\r
        GetDlgItem(IDC_FLOPPY)->EnableWindow(m_bRemovable);\r
@@ -149,6 +153,7 @@ BOOL CSetOverlayPage::OnInitDialog()
        m_tooltips.AddTool(IDC_INCLUDEPATHS, IDS_SETTINGS_INCLUDELIST_TT);\r
        m_tooltips.AddTool(IDC_CACHEDEFAULT, IDS_SETTINGS_CACHEDEFAULT_TT);\r
        m_tooltips.AddTool(IDC_CACHESHELL, IDS_SETTINGS_CACHESHELL_TT);\r
+       m_tooltips.AddTool(IDC_CACHESHELL2, IDS_SETTINGS_CACHESHELL_TT);//TODO: separate tooltip text\r
        m_tooltips.AddTool(IDC_CACHENONE, IDS_SETTINGS_CACHENONE_TT);\r
        m_tooltips.AddTool(IDC_UNVERSIONEDASMODIFIED, IDS_SETTINGS_UNVERSIONEDASMODIFIED_TT);\r
        m_tooltips.AddTool(IDC_SHOWEXCLUDEDASNORMAL, IDS_SETTINGS_SHOWEXCLUDEDASNORMAL_TT);\r
@@ -177,6 +182,9 @@ void CSetOverlayPage::OnChange()
        case IDC_CACHESHELL:\r
                m_dwCacheType = 2;\r
                break;\r
+       case IDC_CACHESHELL2:\r
+               m_dwCacheType = 3;\r
+               break;\r
        case IDC_CACHENONE:\r
                m_dwCacheType = 0;\r
                break;\r
index 7991c0f..dae2a4d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="9.00"\r
+       Version="9,00"\r
        Name="TortoiseProc"\r
        ProjectGUID="{50797F06-39C5-4802-8E2B-7B7A4EF03214}"\r
        RootNamespace="TortoiseProc"\r
@@ -77,9 +77,9 @@
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
                                LinkIncremental="2"\r
-                               AdditionalLibraryDirectories="../../ext/wingit"\r
+                               AdditionalLibraryDirectories=""\r
                                IgnoreDefaultLibraryNames="libcd.lib;libc;shell32;LIBCMTD;"\r
-                               DelayLoadDLLs="gdiplus.dll;wingit.dll"\r
+                               DelayLoadDLLs="gdiplus.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                RandomizedBaseAddress="1"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Debug|x64"\r
-                       OutputDirectory="..\..\bin\Debug64\bin"\r
-                       IntermediateDirectory="..\..\obj\TortoiseProc\Debug64"\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="..\..\bin\$(ConfigurationName)\bin"\r
+                       IntermediateDirectory="..\..\obj\TortoiseProc\$(ConfigurationName)"\r
                        ConfigurationType="1"\r
                        UseOfMFC="2"\r
-                       UseOfATL="0"\r
                        CharacterSet="1"\r
+                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               PreprocessorDefinitions="_DEBUG"\r
+                               PreprocessorDefinitions="NDEBUG"\r
                                MkTypLibCompatible="false"\r
-                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="0"\r
+                               Optimization="1"\r
+                               InlineFunctionExpansion="1"\r
+                               FavorSizeOrSpeed="2"\r
                                AdditionalIncludeDirectories="..\TortoiseProc;..\Resources;&quot;$InputDir&quot;;../../ext/ResizableLib;../Git;&quot;../../ext/apr-util/include&quot;;&quot;../../ext/apr-util/xml/expat/lib&quot;;../../ext/Subversion/subversion/include;../../ext/Subversion/subversion/libsvn_client;../../ext/apr/include;../../ext/boost;..\Utils;..\SVN;..\..\ext\ResizableLib;..\crashrpt;&quot;..\..\ext\libintl\libintl3-win32\inc&quot;;..\..\ext\hunspell;..\..\ext\scintilla\include;..\Utils\TreePropSheet;..\Utils\ColourPickerXP;..\Utils\NewMenu;..\Utils\MiscUI;..\LogCache;&quot;../../ext/cyrus-sasl/include&quot;;../../../common/openssl/inc32;.\RevisionGraph;..\TortoiseShell"\r
-                               PreprocessorDefinitions="WIN64;_WINDOWS;_DEBUG;SVN_DEBUG;ENABLE_NLS;THESAURUS"\r
-                               MinimalRebuild="true"\r
+                               PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;THESAURUS"\r
+                               StringPooling="true"\r
+                               MinimalRebuild="false"\r
                                ExceptionHandling="2"\r
-                               RuntimeLibrary="3"\r
+                               RuntimeLibrary="2"\r
+                               BufferSecurityCheck="false"\r
                                TreatWChar_tAsBuiltInType="true"\r
                                ForceConformanceInForLoopScope="true"\r
                                RuntimeTypeInfo="true"\r
                                UsePrecompiledHeader="2"\r
                                WarningLevel="4"\r
                                DebugInformationFormat="3"\r
+                               DisableSpecificWarnings="4996,4018"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
-                               PreprocessorDefinitions="_DEBUG"\r
+                               PreprocessorDefinitions="NDEBUG"\r
                                Culture="1033"\r
                                AdditionalIncludeDirectories="&quot;$(IntDir)&quot;;..\TortoiseShell"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
-                               LinkIncremental="2"\r
+                               LinkIncremental="1"\r
+                               AdditionalLibraryDirectories="../../ext/wingit"\r
                                IgnoreDefaultLibraryNames="libcd.lib;libc;shell32;LIBCMT"\r
                                DelayLoadDLLs="gdiplus.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               OptimizeForWindows98="0"\r
                                RandomizedBaseAddress="1"\r
                                DataExecutionPrevention="0"\r
-                               TargetMachine="17"\r
+                               TargetMachine="1"\r
+                               Profile="true"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Release|Win32"\r
-                       OutputDirectory="..\..\bin\$(ConfigurationName)\bin"\r
-                       IntermediateDirectory="..\..\obj\TortoiseProc\$(ConfigurationName)"\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="..\..\bin\Debug64\bin"\r
+                       IntermediateDirectory="..\..\obj\TortoiseProc\Debug64"\r
                        ConfigurationType="1"\r
                        UseOfMFC="2"\r
+                       UseOfATL="0"\r
                        CharacterSet="1"\r
-                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               PreprocessorDefinitions="NDEBUG"\r
+                               PreprocessorDefinitions="_DEBUG"\r
                                MkTypLibCompatible="false"\r
+                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="1"\r
-                               InlineFunctionExpansion="1"\r
-                               FavorSizeOrSpeed="2"\r
+                               Optimization="0"\r
                                AdditionalIncludeDirectories="..\TortoiseProc;..\Resources;&quot;$InputDir&quot;;../../ext/ResizableLib;../Git;&quot;../../ext/apr-util/include&quot;;&quot;../../ext/apr-util/xml/expat/lib&quot;;../../ext/Subversion/subversion/include;../../ext/Subversion/subversion/libsvn_client;../../ext/apr/include;../../ext/boost;..\Utils;..\SVN;..\..\ext\ResizableLib;..\crashrpt;&quot;..\..\ext\libintl\libintl3-win32\inc&quot;;..\..\ext\hunspell;..\..\ext\scintilla\include;..\Utils\TreePropSheet;..\Utils\ColourPickerXP;..\Utils\NewMenu;..\Utils\MiscUI;..\LogCache;&quot;../../ext/cyrus-sasl/include&quot;;../../../common/openssl/inc32;.\RevisionGraph;..\TortoiseShell"\r
-                               PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;THESAURUS"\r
-                               StringPooling="true"\r
-                               MinimalRebuild="false"\r
+                               PreprocessorDefinitions="WIN64;_WINDOWS;_DEBUG;SVN_DEBUG;ENABLE_NLS;THESAURUS"\r
+                               MinimalRebuild="true"\r
                                ExceptionHandling="2"\r
-                               RuntimeLibrary="2"\r
-                               BufferSecurityCheck="false"\r
+                               RuntimeLibrary="3"\r
                                TreatWChar_tAsBuiltInType="true"\r
                                ForceConformanceInForLoopScope="true"\r
                                RuntimeTypeInfo="true"\r
                                UsePrecompiledHeader="2"\r
                                WarningLevel="4"\r
                                DebugInformationFormat="3"\r
-                               DisableSpecificWarnings="4996,4018"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
-                               PreprocessorDefinitions="NDEBUG"\r
+                               PreprocessorDefinitions="_DEBUG"\r
                                Culture="1033"\r
                                AdditionalIncludeDirectories="&quot;$(IntDir)&quot;;..\TortoiseShell"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
-                               LinkIncremental="1"\r
-                               AdditionalLibraryDirectories="../../ext/wingit"\r
+                               LinkIncremental="2"\r
                                IgnoreDefaultLibraryNames="libcd.lib;libc;shell32;LIBCMT"\r
                                DelayLoadDLLs="gdiplus.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               OptimizeReferences="2"\r
-                               EnableCOMDATFolding="2"\r
-                               OptimizeForWindows98="0"\r
                                RandomizedBaseAddress="1"\r
                                DataExecutionPrevention="0"\r
-                               TargetMachine="1"\r
-                               Profile="true"\r
+                               TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\RebaseDlg.cpp"\r
-                               >\r
-                       </File>\r
-                       <File\r
-                               RelativePath=".\RebaseDlg.h"\r
-                               >\r
-                       </File>\r
-                       <File\r
                                RelativePath="..\TortoiseShell\resource.h"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\explorer.ico"\r
+                               RelativePath=".\explorer.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\explorer.ico"\r
+                               RelativePath="..\Resources\explorer.ico"\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\newfolder.ico"\r
+                               RelativePath=".\newfolder.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\newfolder.ico"\r
+                               RelativePath="..\Resources\newfolder.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\open.ico"\r
+                               RelativePath=".\open.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\open.ico"\r
+                               RelativePath="..\Resources\open.ico"\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\save.ico"\r
+                               RelativePath=".\save.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\save.ico"\r
+                               RelativePath="..\Resources\save.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\saveas.ico"\r
+                               RelativePath=".\saveas.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\saveas.ico"\r
+                               RelativePath="..\Resources\saveas.ico"\r
                                >\r
                        </File>\r
                        <File\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath="..\Resources\up.ico"\r
+                               RelativePath=".\up.ico"\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\up.ico"\r
+                               RelativePath="..\Resources\up.ico"\r
                                >\r
                        </File>\r
                        <File\r
                                </File>\r
                        </Filter>\r
                        <Filter\r
-                               Name="merge"\r
-                               >\r
-                               <File\r
-                                       RelativePath=".\Commands\MergeCommand.cpp"\r
-                                       >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath=".\Commands\MergeCommand.h"\r
-                                       >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath=".\MergeDlg.cpp"\r
-                                       >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath=".\MergeDlg.h"\r
-                                       >\r
-                               </File>\r
-                       </Filter>\r
-                       <Filter\r
                                Name="Export"\r
                                >\r
                                <File\r
                                        >\r
                                </File>\r
                        </Filter>\r
+                       <Filter\r
+                               Name="Rebase"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Commands\RebaseCommand.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Commands\RebaseCommand.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\RebaseDlg.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\RebaseDlg.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="merge"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\Commands\MergeCommand.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\Commands\MergeCommand.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\MergeDlg.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\MergeDlg.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
                </Filter>\r
                <Filter\r
                        Name="Utility Dialogs"\r
                                />\r
                        </FileConfiguration>\r
                        <FileConfiguration\r
-                               Name="Debug|x64"\r
+                               Name="Release|Win32"\r
                                >\r
                                <Tool\r
                                        Name="VCCLCompilerTool"\r
                                />\r
                        </FileConfiguration>\r
                        <FileConfiguration\r
-                               Name="Release|Win32"\r
+                               Name="Debug|x64"\r
                                >\r
                                <Tool\r
                                        Name="VCCLCompilerTool"\r
                />\r
                <Global\r
                        Name="RESOURCE_FILE"\r
-                       Value="\build\x64\TortoiseGit\src\Resources\TortoiseProcENG.rc"\r
+                       Value="\\geo\msdev\TortoiseGit\src\Resources\TortoiseProcENG.rc"\r
                />\r
        </Globals>\r
 </VisualStudioProject>\r
index 901a880..fbaea28 100644 (file)
@@ -8,7 +8,7 @@
 #define LOG_DATA_MAGIC         0x99aa00FF\r
 #define LOG_DATA_ITEM_MAGIC 0x0F8899CC\r
 #define LOG_DATA_FILE_MAGIC 0x19999FFF\r
-#define LOG_INDEX_VERSION 0x1\r
+#define LOG_INDEX_VERSION   0x3 \r
 \r
 struct SLogCacheIndexHeader \r
 {\r
index 3dbd7b3..9fe6ebd 100644 (file)
Binary files a/src/TortoiseProc/resource.h and b/src/TortoiseProc/resource.h differ
index 287e40e..6140362 100644 (file)
@@ -24,7 +24,7 @@
 #include "UnicodeUtils.h"\r
 #include "GitStatus.h"\r
 #include "PathUtils.h"\r
-//#include "..\TSVNCache\CacheInterface.h"\r
+#include "..\TGitCache\CacheInterface.h"\r
 \r
 \r
 const static int ColumnFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;\r
@@ -342,15 +342,15 @@ void CShellExt::GetColumnStatus(const TCHAR * path, BOOL bIsDir)
        case ShellCache::exe:\r
                {\r
                        SecureZeroMemory(&itemStatus, sizeof(itemStatus));\r
-                       if(m_remoteCacheLink.GetStatusFromRemoteCache(CTSVNPath(path), &itemStatus, true))\r
+                       if(m_remoteCacheLink.GetStatusFromRemoteCache(CTGitPath(path), &itemStatus, true))\r
                        {\r
-                               filestatus = SVNStatus::GetMoreImportant(itemStatus.m_status.text_status, itemStatus.m_status.prop_status);\r
+                               filestatus = GitStatus::GetMoreImportant(itemStatus.m_status.text_status, itemStatus.m_status.prop_status);\r
                        }\r
                        else\r
                        {\r
                                filestatus = git_wc_status_none;\r
                                columnauthor.clear();\r
-                               columnrev = 0;\r
+                               columnrev = GIT_INVALID_REVNUM;\r
                                itemurl.clear();\r
                                itemshorturl.clear();\r
                                owner.clear();\r
@@ -359,8 +359,9 @@ void CShellExt::GetColumnStatus(const TCHAR * path, BOOL bIsDir)
                }\r
                break;\r
        case ShellCache::dll:\r
+       case ShellCache::dllFull:\r
                {\r
-                       status = m_CachedStatus.GetFullStatus(CTSVNPath(path), bIsDir, TRUE);\r
+                       status = m_CachedStatus.GetFullStatus(CTGitPath(path), bIsDir, TRUE);\r
                        filestatus = status->status;\r
                }\r
                break;\r
@@ -372,7 +373,7 @@ void CShellExt::GetColumnStatus(const TCHAR * path, BOOL bIsDir)
                        else\r
                                filestatus = git_wc_status_none;\r
                        columnauthor.clear();\r
-                       columnrev = 0;\r
+                       columnrev = GIT_INVALID_REVNUM;\r
                        itemurl.clear();\r
                        itemshorturl.clear();\r
                        owner.clear();\r
@@ -422,7 +423,7 @@ void CShellExt::GetColumnStatus(const TCHAR * path, BOOL bIsDir)
                        // Note: this will strip too much if such a folder is *below* the repository\r
                        // root - but it's called 'short url' and we're free to shorten it the way we\r
                        // like :)\r
-                       ptr = _tcsstr(urlComponents.lpszUrlPath, _T("/trunk"));\r
+                       /*ptr = _tcsstr(urlComponents.lpszUrlPath, _T("/trunk"));\r
                        if (ptr == NULL)\r
                                ptr = _tcsstr(urlComponents.lpszUrlPath, _T("\\trunk"));\r
                        if ((ptr == NULL)||((*(ptr+6) != 0)&&(*(ptr+6) != '/')&&(*(ptr+6) != '\\')))\r
@@ -441,7 +442,7 @@ void CShellExt::GetColumnStatus(const TCHAR * path, BOOL bIsDir)
                        }\r
                        if (ptr)\r
                                itemshorturl = ptr;\r
-                       else\r
+                       else*/\r
                                itemshorturl = urlComponents.lpszUrlPath;\r
                }\r
                else \r
index c341248..d6adae9 100644 (file)
@@ -73,6 +73,9 @@ CShellExt::MenuInfo CShellExt::menuInfo[] =
        { ShellMenuShowChanged,                          &n