OSDN Git Service

Started implementing EnumFiles() with git.exe call
authorJohan t Hart <johanthart@gmail.com>
Sat, 7 Feb 2009 14:34:40 +0000 (15:34 +0100)
committerFrank Li <lznuaa@gmail.com>
Sun, 8 Feb 2009 07:05:07 +0000 (15:05 +0800)
src/Git/Git.cpp
src/Git/Git.h
src/TortoiseShell/ShellCache.h

index eecb872..145f47b 100644 (file)
@@ -4,6 +4,8 @@
 #include "GitRev.h"\r
 #include "registry.h"\r
 #include "GitConfig.h"\r
+#include <map>\r
+#include "UnicodeUtils.h"\r
 \r
 \r
 static LPTSTR nextpath(LPCTSTR src, LPTSTR dst, UINT maxlen)\r
@@ -125,7 +127,7 @@ BOOL wgEnumFiles_safe(const char *pszProjectPath, const char *pszSubPath, unsign
        if(g_IsWingitDllload)\r
                return wgEnumFiles(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
        else\r
-               return FALSE;\r
+               return g_Git.EnumFiles(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
 }\r
 \r
 BOOL CGit::IsVista()\r
@@ -795,3 +797,107 @@ BOOL CGit::CheckMsysGitDir()
                return true;\r
        }\r
 }\r
+\r
+\r
+class CGitCall_EnumFiles : public CGitCall\r
+{\r
+public:\r
+       CGitCall_EnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData)\r
+       :       m_pszProjectPath(pszProjectPath),\r
+               m_pszSubPath(pszSubPath),\r
+               m_nFlags(nFlags),\r
+               m_pEnumCb(pEnumCb),\r
+               m_pUserData(pUserData)\r
+       {\r
+       }\r
+\r
+       typedef std::map<CStringA,char> TStrCharMap;\r
+\r
+       const char *    m_pszProjectPath;\r
+       const char *    m_pszSubPath;\r
+       unsigned int    m_nFlags;\r
+       WGENUMFILECB *  m_pEnumCb;\r
+       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
+                       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
+               }\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
+               //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
+       }\r
+\r
+\r
+\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
+               return FALSE;\r
+       CGitCall_EnumFiles W_GitCall(pszProjectPath,pszSubPath,nFlags,pEnumCb,pUserData);\r
+       CString cmd;\r
+\r
+/*     char W_szToDir[MAX_PATH];\r
+       strncpy(W_szToDir,pszProjectPath,sizeof(W_szToDir)-1);\r
+       if(W_szToDir[strlen(W_szToDir)-1]!='\\')\r
+               strncat(W_szToDir,"\\",sizeof(W_szToDir)-1);\r
+\r
+       SetCurrentDirectoryA(W_szToDir);\r
+       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
+       W_GitCall.SetCmd(cmd);\r
+       Run(&W_GitCall);\r
+       return TRUE;\r
+}\r
index 43cdf18..632ddb3 100644 (file)
@@ -87,6 +87,8 @@ public:
        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
 \r
+       BOOL EnumFiles(const char *pszProjectPath, const char *pszSubPath, unsigned int nFlags, WGENUMFILECB *pEnumCb, void *pUserData);\r
+\r
        git_revnum_t GetHash(CString &friendname);\r
 \r
        int BuildOutputFormat(CString &format,bool IsFull=TRUE);\r
index 761202b..f40783d 100644 (file)
@@ -154,8 +154,8 @@ public:
                }\r
                //return CacheType(DWORD((cachetype)));\r
                /*TEMP: until TGitCache done*/\r
-               if(CGit::IsVista())\r
-                       return none;\r
+//             if(CGit::IsVista())\r
+//                     return none;\r
                return CacheType(DWORD((cachetype))) == exe ? dll : CacheType(DWORD((cachetype)));\r
        }\r
        DWORD BlockStatus()\r