From da6e0f74998f305a8185422c178c4afd72d26d7f Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sun, 27 May 2012 04:30:55 +0200 Subject: [PATCH] refactored ignore file checking Signed-off-by: Sven Strickroth --- src/Git/GitIndex.cpp | 98 ++++++++++++++++++++++++++++++---------------------- src/Git/gitindex.h | 1 + 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/Git/GitIndex.cpp b/src/Git/GitIndex.cpp index 15423fe86..dd42e0570 100644 --- a/src/Git/GitIndex.cpp +++ b/src/Git/GitIndex.cpp @@ -1193,6 +1193,18 @@ bool CGitIgnoreList::IsIgnore(const CString &path,const CString &projectroot) return (ret == 1); } +int CGitIgnoreList::CheckFileAgainstIgnoreList(const CString &ignorefile, const CStringA &patha, const char * base, int &type) +{ + if (m_Map.find(ignorefile) != m_Map.end()) + { + int ret = -1; + if(m_Map[ignorefile].m_pExcludeList) + ret = git_check_excluded_1(patha, patha.GetLength(), base, &type, m_Map[ignorefile].m_pExcludeList); + if (ret == 0 || ret == 1) + return ret; + } + return -1; +} int CGitIgnoreList::CheckIgnore(const CString &path,const CString &projectroot) { __int64 time = 0; @@ -1200,9 +1212,7 @@ int CGitIgnoreList::CheckIgnore(const CString &path,const CString &projectroot) CString temp = projectroot + _T("\\") + path; temp.Replace(_T('/'), _T('\\')); - CStringA patha; - - patha = CUnicodeUtils::GetMulti(path, CP_UTF8); + CStringA patha = CUnicodeUtils::GetMulti(path, CP_UTF8); patha.Replace('\\', '/'); if(g_Git.GetFileModifyTime(temp, &time, &dir)) @@ -1210,61 +1220,65 @@ int CGitIgnoreList::CheckIgnore(const CString &path,const CString &projectroot) int type = 0; if (dir) + { type = DT_DIR; + + // strip directory name + // we do not need to check for a .ignore file inside a directory we might ignore + int i = temp.ReverseFind(_T('\\')); + if (i >= 0) + temp = temp.Left(i); + } else type = DT_REG; - while (!temp.IsEmpty()) - { - int x; - x = temp.ReverseFind(_T('\\')); - if(x < 0) - x=0; - temp=temp.Left(x); - - temp += _T("\\.gitignore"); - - char *base; + char * base = NULL; + int pos = patha.ReverseFind('/'); + base = pos >= 0 ? patha.GetBuffer() + pos + 1 : patha.GetBuffer(); - patha.Replace('\\', '/'); - int pos = patha.ReverseFind('/'); - base = pos >= 0 ? patha.GetBuffer() + pos + 1 : patha.GetBuffer(); + int ret = -1; - CAutoReadLock lock(&this->m_SharedMutex); + CAutoReadLock lock(&this->m_SharedMutex); + while (!temp.IsEmpty()) + { + CString tempOrig = temp; + temp += _T("\\.git"); - if(this->m_Map.find(temp) != m_Map.end()) + if (CGit::GitPathFileExists(temp)) { - int ret=-1; - - if(m_Map[temp].m_pExcludeList) - ret = git_check_excluded_1( patha, patha.GetLength(), base, &type, m_Map[temp].m_pExcludeList); + CString gitignore = temp; + gitignore += _T("ignore"); + if ((ret = CheckFileAgainstIgnoreList(gitignore, patha, base, type)) != -1) + break; - if(ret == 1) - return 1; - if(ret == 0) - return 0; + CString wcglobalgitignore = g_AdminDirMap.GetAdminDir(tempOrig) + _T("info\\exclude"); + ret = CheckFileAgainstIgnoreList(wcglobalgitignore, patha, base, type); + break; } - - temp = g_AdminDirMap.GetAdminDir(temp.Left(temp.GetLength() - 11)) + _T("info\\exclude"); - - if(this->m_Map.find(temp) != m_Map.end()) + else { - int ret = -1; - - if(m_Map[temp].m_pExcludeList) - ret = git_check_excluded_1(patha, patha.GetLength(), base, &type, m_Map[temp].m_pExcludeList); + temp += _T("ignore"); + if ((ret = CheckFileAgainstIgnoreList(temp, patha, base, type)) != -1) + break; + } - if(ret == 1) - return 1; - if(ret == 0) - return 0; + int found = 0; + int i; + for (i = temp.GetLength() - 1; i >= 0; i--) + { + if (temp[i] == _T('\\')) + found++; - return -1; + if (found == 2) + break; } - temp = temp.Left(temp.GetLength() - 18); + + temp = temp.Left(i); } - return -1; + patha.ReleaseBuffer(); + + return ret; } bool CGitHeadFileMap::CheckHeadUpdate(const CString &gitdir) diff --git a/src/Git/gitindex.h b/src/Git/gitindex.h index 06ac848a1..e7fe88651 100644 --- a/src/Git/gitindex.h +++ b/src/Git/gitindex.h @@ -441,6 +441,7 @@ private: int FetchIgnoreFile(const CString &gitdir, const CString &gitignore, bool isGlobal); int CheckIgnore(const CString &path,const CString &root); + int CheckFileAgainstIgnoreList(const CString &ignorefile, const CStringA &patha, const char * base, int &type); public: SharedMutex m_SharedMutex; -- 2.11.4.GIT