#include "PathUtils.h"\r
#include <regex>\r
#include "git.h"\r
+#include "Globals.h"\r
+\r
#if defined(_MFC_VER)\r
//#include "MessageBox.h"\r
//#include "AppUtils.h"\r
{\r
SetFromUnknown(sUnknownPath);\r
m_Action=0;\r
+ m_Stage=0;\r
}\r
\r
int CTGitPath::ParserAction(BYTE action)\r
m_Action|= LOGACTIONS_DELETED;\r
if(action == 'U')\r
m_Action|= LOGACTIONS_UNMERGED;\r
+ if(action == 'K')\r
+ 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
m_bIsDirectory = bIsDirectory;\r
}\r
\r
+void CTGitPath::SetFromGit(const TCHAR* pPath, bool bIsDirectory)\r
+{\r
+ Reset();\r
+ if (pPath)\r
+ {\r
+ m_sFwdslashPath = pPath;\r
+ SanitizeRootPath(m_sFwdslashPath, true);\r
+ }\r
+ m_bDirectoryKnown = true;\r
+ m_bIsDirectory = bIsDirectory;\r
+}\r
+\r
void CTGitPath::SetFromGit(const CString& sPath,CString *oldpath)\r
{\r
Reset();\r
m_bExistsKnown = true;\r
}\r
\r
+CTGitPath CTGitPath::GetSubPath(CTGitPath &root)\r
+{\r
+ CTGitPath path;\r
+ \r
+ if(GetWinPathString().Left(root.GetWinPathString().GetLength()) == root.GetWinPathString())\r
+ {\r
+ CString str=GetWinPathString();\r
+ path.SetFromWin(str.Right(str.GetLength()-root.GetWinPathString().GetLength()-1));\r
+ }\r
+ return path;\r
+}\r
\r
void CTGitPath::EnsureBackslashPathSet() const\r
{\r
CString filename=GetFilename();\r
dot = filename.ReverseFind(_T('.'));\r
if(dot>0)\r
- return filename.Left(dot-1);\r
+ return filename.Left(dot);\r
else\r
return filename;\r
}\r
return m_bHasAdminDir;\r
\r
EnsureBackslashPathSet();\r
- m_bHasAdminDir = g_GitAdminDir.HasAdminDir(m_sBackslashPath, IsDirectory());\r
+ m_bHasAdminDir = g_GitAdminDir.HasAdminDir(m_sBackslashPath, IsDirectory(), &m_sProjectRoot);\r
m_bHasAdminDirKnown = true;\r
return m_bHasAdminDir;\r
}\r
\r
+bool CTGitPath::HasSubmodules() const\r
+{\r
+ return !g_GitAdminDir.GetSuperProjectRoot(GetWinPathString()).IsEmpty();\r
+}\r
+\r
+int CTGitPath::GetAdminDirMask() const\r
+{\r
+ int status = 0;\r
+ CString topdir,path;\r
+ if(!g_GitAdminDir.HasAdminDir(GetWinPathString(),&topdir))\r
+ {\r
+ return status;\r
+ }\r
+\r
+ status |= ITEMIS_INSVN|ITEMIS_FOLDERINSVN;\r
+\r
+ path=topdir;\r
+ path+=_T("\\");\r
+ path+=g_GitAdminDir.GetAdminDirName();\r
+ path+=_T("\\refs\\stash");\r
+ if( PathFileExists(path) )\r
+ status |= ITEMIS_STASH;\r
+ \r
+ path=topdir;\r
+ path+=_T("\\");\r
+ path+=g_GitAdminDir.GetAdminDirName();\r
+ path+=_T("\\svn");\r
+ if( PathFileExists(path) )\r
+ status |= ITEMIS_GITSVN;\r
+\r
+ path=topdir;\r
+ path+=_T("\\.gitmodules");\r
+ if( PathFileExists(path) )\r
+ status |= ITEMIS_SUBMODULE;\r
+\r
+ return status;\r
+}\r
+\r
+bool CTGitPath::HasStashDir() const\r
+{\r
+ CString topdir;\r
+ if(!g_GitAdminDir.HasAdminDir(GetWinPathString(),&topdir))\r
+ {\r
+ return false;\r
+ }\r
+ topdir+=_T("\\");\r
+ topdir+=g_GitAdminDir.GetAdminDirName();\r
+ topdir+=_T("\\refs\stash");\r
+ return PathFileExists(topdir);\r
+}\r
+bool CTGitPath::HasGitSVNDir() const\r
+{\r
+ CString topdir;\r
+ if(!g_GitAdminDir.HasAdminDir(GetWinPathString(),&topdir))\r
+ {\r
+ return false;\r
+ }\r
+ topdir+=_T("\\");\r
+ topdir+=g_GitAdminDir.GetAdminDirName();\r
+ topdir+=_T("\\svn");\r
+ return PathFileExists(topdir);\r
+}\r
+bool CTGitPath::HasAdminDir(CString *ProjectTopDir) const\r
+{\r
+ if (m_bHasAdminDirKnown)\r
+ {\r
+ if (ProjectTopDir)\r
+ *ProjectTopDir = m_sProjectRoot;\r
+ return m_bHasAdminDir;\r
+ }\r
+\r
+ EnsureBackslashPathSet();\r
+ m_bHasAdminDir = g_GitAdminDir.HasAdminDir(m_sBackslashPath, IsDirectory(), &m_sProjectRoot);\r
+ m_bHasAdminDirKnown = true;\r
+ if (ProjectTopDir)\r
+ *ProjectTopDir = m_sProjectRoot;\r
+ return m_bHasAdminDir;\r
+}\r
+\r
bool CTGitPath::IsAdminDir() const\r
{\r
if (m_bIsAdminDirKnown)\r
{\r
AddPath(firstEntry);\r
}\r
+int CTGitPathList::ParserFromLsFile(BYTE_VECTOR &out,bool staged)\r
+{\r
+ int pos=0;\r
+ CString one;\r
+ CTGitPath path;\r
+ CString part;\r
+ this->Clear();\r
+\r
+ while(pos>=0 && pos<out.size())\r
+ {\r
+ one.Empty();\r
+ path.Reset();\r
+\r
+ g_Git.StringAppend(&one,&out[pos],CP_ACP);\r
+ int tabstart=0;\r
+ path.m_Action=path.ParserAction(out[pos]);\r
+ one.Tokenize(_T("\t"),tabstart); \r
+\r
+ if(tabstart>=0)\r
+ path.SetFromGit(one.Right(one.GetLength()-tabstart));\r
+\r
+ tabstart=0;\r
+\r
+ part=one.Tokenize(_T(" "),tabstart); //Tag\r
+\r
+ part=one.Tokenize(_T(" "),tabstart); //Mode\r
+ \r
+ part=one.Tokenize(_T(" "),tabstart); //Hash\r
+\r
+ part=one.Tokenize(_T("\t"),tabstart); //Stage\r
+\r
+ path.m_Stage=_ttol(part);\r
+\r
+ this->AddPath(path);\r
+\r
+ pos=out.findNextString(pos);\r
+ }\r
+ return pos;\r
+}\r
int CTGitPathList::FillUnRev(int action,CTGitPathList *list)\r
{\r
int pos=0;\r
\r
if(list==NULL)\r
{\r
- cmd=_T("git.exe ls-files --exclude-standard --full-name --others");\r
+ cmd=_T("git.exe ls-files --exclude-standard --full-name --others -z");\r
cmd+=ignored;\r
\r
}\r
else\r
- { cmd.Format(_T("git.exe ls-files --exclude-standard --full-name --others %s-- \"%s\""),\r
+ { cmd.Format(_T("git.exe ls-files --exclude-standard --full-name --others -z %s-- \"%s\""),\r
ignored,\r
(*list)[i].GetWinPathString());\r
}\r
-#ifdef VECTOR_F \r
- CString out;\r
- g_Git.Run(cmd,&out);\r
\r
+ BYTE_VECTOR out;\r
+ out.clear();\r
+ g_Git.Run(cmd,&out);\r
+ \r
+ pos=0;\r
CString one;\r
- while( pos>=0 )\r
+ while( pos>=0 && pos<out.size())\r
{\r
- one=out.Tokenize(_T("\n"),pos);\r
+ one.Empty();\r
+ g_Git.StringAppend(&one,&out[pos],CP_ACP);\r
if(!one.IsEmpty())\r
{\r
//SetFromGit will clear all status\r
path.m_Action=action;\r
AddPath(path);\r
}\r
+ pos=out.findNextString(pos);\r
}\r
-#endif\r
+\r
}\r
return 0;\r
}\r
{\r
this->Clear();\r
int pos=0;\r
- BYTE *p=&log[0];\r
+ //BYTE *p=&log[0];\r
//CString one;\r
CTGitPath path;\r
m_Action=0;\r
\r
if(log[pos]==':')\r
{\r
+ bool merged=false;\r
+ if(log[pos+1] ==':')\r
+ {\r
+ merged=true;\r
+ }\r
int end=log.find(0,pos);\r
int actionstart=-1;\r
int numfile=1;\r
CString pathname2;\r
\r
if( file1>=0 )\r
- g_Git.StringAppend(&pathname1,&log[file1],CP_OEMCP);\r
+ g_Git.StringAppend(&pathname1,&log[file1],CP_ACP);\r
if( file2>=0 )\r
- g_Git.StringAppend(&pathname2,&log[file2],CP_OEMCP);\r
+ g_Git.StringAppend(&pathname2,&log[file2],CP_ACP);\r
\r
CTGitPath *GitPath=LookForGitPath(pathname1);\r
\r
if(GitPath)\r
{\r
- this->m_Action|=GitPath->ParserAction( log[actionstart] ); \r
- \r
+ GitPath->ParserAction( log[actionstart] ); \r
+ \r
+ if(merged)\r
+ {\r
+ GitPath->m_Action |= CTGitPath::LOGACTIONS_MERGED;\r
+ GitPath->m_Action &= ~CTGitPath::LOGACTIONS_FORWORD;\r
+ }\r
+ m_Action |=GitPath->m_Action;\r
+\r
}else\r
{ \r
int ac=path.ParserAction(log[actionstart] );\r
+ ac |= merged?CTGitPath::LOGACTIONS_MERGED:0; \r
\r
path.SetFromGit(pathname1,&pathname2);\r
path.m_Action=ac;\r
//action must be set after setfromgit. SetFromGit will clear all status. \r
this->m_Action|=ac;\r
+ \r
AddPath(path);\r
\r
}\r
if(log[pos] == 0) //rename\r
{\r
pos++;\r
- g_Git.StringAppend(&file2,&log[pos],CP_OEMCP);\r
+ g_Git.StringAppend(&file2,&log[pos],CP_ACP);\r
int sec=log.find(0,pos);\r
if(sec>=0)\r
{\r
sec++;\r
- g_Git.StringAppend(&file1,&log[sec],CP_OEMCP);\r
+ g_Git.StringAppend(&file1,&log[sec],CP_ACP);\r
}\r
+ pos=sec;\r
\r
}else\r
{\r
- g_Git.StringAppend(&file1,&log[pos],CP_OEMCP);\r
+ g_Git.StringAppend(&file1,&log[pos],CP_ACP);\r
}\r
path.SetFromGit(file1,&file2);\r
\r
//path.SetFromGit(pathname);\r
path.m_StatAdd=StatAdd;\r
path.m_StatDel=StatDel;\r
+ path.m_Action |= CTGitPath::LOGACTIONS_FORWORD;\r
AddPath(path);\r
}\r
\r
int searchStartPos = 0;\r
while (bEqual)\r
{\r
+ if(m_paths.empty())\r
+ break;\r
+\r
for (it = m_paths.begin(); it != m_paths.end(); ++it)\r
{\r
if (backSlashPos == 0)\r
}\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_UNMERGED)\r
+ return _T("Conflict");\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_MODIFIED)\r
+ if(action & CTGitPath::LOGACTIONS_MERGED )\r
+ return _T("Merged");\r
+\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
+\r
+ if(action & CTGitPath::LOGACTIONS_FORWORD )\r
+ return _T("Forward");\r
+\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
return m_Action;\r
}\r
+\r