From f1f716e6f44d75876cdd20cf5e5c97d191cf7d3a Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Sun, 11 Jun 2017 20:52:09 +0200 Subject: [PATCH] Use git_wc_status2_t as return type in order to get rid of lots of extra pointers Signed-off-by: Sven Strickroth --- src/Git/GitFolderStatus.cpp | 15 +++-- src/Git/GitIndex.cpp | 55 +++++++++-------- src/Git/GitStatus.cpp | 120 ++++++++++++++++++-------------------- src/Git/GitStatus.h | 6 +- src/Git/gitindex.h | 6 +- src/TGitCache/CachedDirectory.cpp | 21 +++---- src/TGitCache/CachedDirectory.h | 2 +- test/UnitTests/GitIndexTest.cpp | 71 +++++++++++----------- 8 files changed, 143 insertions(+), 153 deletions(-) diff --git a/src/Git/GitFolderStatus.cpp b/src/Git/GitFolderStatus.cpp index 724f2a41e..4a38023db 100644 --- a/src/Git/GitFolderStatus.cpp +++ b/src/Git/GitFolderStatus.cpp @@ -91,20 +91,19 @@ const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepa } } // if (bIsFolder) - git_wc_status_kind status; - bool assumeValid = false; - bool skipWorktree = false; + git_wc_status2_t status = { git_wc_status_none, false, false }; int t1,t2; t2=t1=0; try { t1 = ::GetCurrentTime(); - status = m_GitStatus.GetAllStatus(filepath, g_ShellCache.GetCacheType() != ShellCache::dll, &assumeValid, &skipWorktree); + if (m_GitStatus.GetAllStatus(filepath, g_ShellCache.GetCacheType() != ShellCache::dll, status)) + status = { git_wc_status_none, false, false }; t2 = ::GetCurrentTime(); } catch ( ... ) { - status = git_wc_status_unknown; + status = { git_wc_status_none, false, false }; } CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": building cache for %s - time %d\n", filepath.GetWinPath(), t2 - t1); @@ -119,9 +118,9 @@ const FileStatusCacheEntry * GitFolderStatus::BuildCache(const CTGitPath& filepa if (ret) { - ret->status = status; - ret->assumeValid = assumeValid; - ret->skipWorktree = skipWorktree; + ret->status = status.status; + ret->assumeValid = status.assumeValid; + ret->skipWorktree = status.skipWorktree; } m_mostRecentPath = filepath; diff --git a/src/Git/GitIndex.cpp b/src/Git/GitIndex.cpp index e7b40468d..10c0e2d5d 100644 --- a/src/Git/GitIndex.cpp +++ b/src/Git/GitIndex.cpp @@ -150,15 +150,13 @@ int CGitIndexList::ReadIndex(CString dgitdir) return 0; } -int CGitIndexList::GetFileStatus(const CString& gitdir, const CString& pathorg, git_wc_status_kind* status, __int64 time, __int64 filesize, CGitHash* pHash, bool* assumeValid, bool* skipWorktree) +int CGitIndexList::GetFileStatus(const CString& gitdir, const CString& pathorg, git_wc_status2_t& status, __int64 time, __int64 filesize, CGitHash* pHash) { - ATLASSERT(status); - size_t index = SearchInSortVector(*this, pathorg, -1); if (index == NPOS) { - *status = git_wc_status_unversioned; + status.status = git_wc_status_unversioned; if (pHash) pHash->Empty(); @@ -170,30 +168,30 @@ int CGitIndexList::GetFileStatus(const CString& gitdir, const CString& pathorg, *pHash = entry.m_IndexHash; ATLASSERT(pathorg == entry.m_FileName); CAutoRepository repository; - return GetFileStatus(repository, gitdir, entry, status, time, filesize, assumeValid, skipWorktree); + return GetFileStatus(repository, gitdir, entry, status, time, filesize); } -int CGitIndexList::GetFileStatus(CAutoRepository& repository, const CString& gitdir, CGitIndex& entry, git_wc_status_kind* status, __int64 time, __int64 filesize, bool* assumeValid, bool* skipWorktree) +int CGitIndexList::GetFileStatus(CAutoRepository& repository, const CString& gitdir, CGitIndex& entry, git_wc_status2_t& status, __int64 time, __int64 filesize) { + ATLASSERT(!status.assumeValid && !status.skipWorktree); + // skip-worktree has higher priority than assume-valid if (entry.m_FlagsExtended & GIT_IDXENTRY_SKIP_WORKTREE) { - *status = git_wc_status_normal; - if (skipWorktree) - *skipWorktree = true; + status.status = git_wc_status_normal; + status.skipWorktree = true; } else if (entry.m_Flags & GIT_IDXENTRY_VALID) { - *status = git_wc_status_normal; - if (assumeValid) - *assumeValid = true; + status.status = git_wc_status_normal; + status.assumeValid = true; } else if (filesize == -1) - *status = git_wc_status_deleted; + status.status = git_wc_status_deleted; else if (filesize != entry.m_Size) - *status = git_wc_status_modified; + status.status = git_wc_status_modified; else if (time == entry.m_ModifyTime) - *status = git_wc_status_normal; + status.status = git_wc_status_normal; else if (config && filesize < m_iMaxCheckSize) { /* @@ -215,30 +213,29 @@ int CGitIndexList::GetFileStatus(CAutoRepository& repository, const CString& git if (!git_repository_hashfile(&actual, repository, fileA, GIT_OBJ_BLOB, nullptr) && !git_oid_cmp(&actual, (const git_oid*)entry.m_IndexHash.m_hash)) { entry.m_ModifyTime = time; - *status = git_wc_status_normal; + status.status = git_wc_status_normal; } else - *status = git_wc_status_modified; + status.status = git_wc_status_modified; } else - *status = git_wc_status_modified; + status.status = git_wc_status_modified; if (entry.m_Flags & GIT_IDXENTRY_STAGEMASK) - *status = git_wc_status_conflicted; + status.status = git_wc_status_conflicted; else if (entry.m_FlagsExtended & GIT_IDXENTRY_INTENT_TO_ADD) - *status = git_wc_status_added; + status.status = git_wc_status_added; return 0; } -int CGitIndexList::GetFileStatus(const CString& gitdir, CString path, git_wc_status_kind* status, - CGitHash *pHash, bool * assumeValid, bool * skipWorktree) +int CGitIndexList::GetFileStatus(const CString& gitdir, CString path, git_wc_status2_t& status, CGitHash* pHash) { + ATLASSERT(!status.assumeValid && !status.skipWorktree); + __int64 time, filesize = 0; bool isDir = false; - ATLASSERT(status); - int result; if (path.IsEmpty()) result = CGit::GetFileModifyTime(gitdir, &time, &isDir); @@ -249,14 +246,14 @@ int CGitIndexList::GetFileStatus(const CString& gitdir, CString path, git_wc_sta filesize = -1; if (!isDir) - return GetFileStatus(gitdir, path, status, time, filesize, pHash, assumeValid, skipWorktree); + return GetFileStatus(gitdir, path, status, time, filesize, pHash); if (CStringUtils::EndsWith(path, L'/')) { size_t index = SearchInSortVector(*this, path, -1); if (index == NPOS) { - *status = git_wc_status_unversioned; + status.status = git_wc_status_unversioned; if (pHash) pHash->Empty(); @@ -267,14 +264,14 @@ int CGitIndexList::GetFileStatus(const CString& gitdir, CString path, git_wc_sta *pHash = (*this)[index].m_IndexHash; if (!result) - *status = git_wc_status_normal; + status.status = git_wc_status_normal; else - *status = git_wc_status_deleted; + status.status = git_wc_status_deleted; return 0; } // we should never get here - *status = git_wc_status_unversioned; + status.status = git_wc_status_unversioned; return -1; } diff --git a/src/Git/GitStatus.cpp b/src/Git/GitStatus.cpp index ef43c6349..fbb9012c4 100644 --- a/src/Git/GitStatus.cpp +++ b/src/Git/GitStatus.cpp @@ -42,10 +42,8 @@ GitStatus::GitStatus() // static method #ifndef TGITCACHE -git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, bool bIsRecursive, bool* assumeValid, bool* skipWorktree) +int GitStatus::GetAllStatus(const CTGitPath& path, bool bIsRecursive, git_wc_status2_t& status) { - git_wc_status_kind statuskind; - BOOL err; BOOL isDir; CString sProjectRoot; @@ -53,9 +51,6 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, bool bIsRecurs if (!path.HasAdminDir(&sProjectRoot)) return git_wc_status_none; -// rev.kind = git_opt_revision_unspecified; - statuskind = git_wc_status_none; - CString sSubPath; CString s = path.GetWinPathString(); if (s.GetLength() > sProjectRoot.GetLength()) @@ -71,13 +66,12 @@ git_wc_status_kind GitStatus::GetAllStatus(const CTGitPath& path, bool bIsRecurs if(isDir) { - err = GetDirStatus(sProjectRoot, sSubPath, &statuskind, isfull, bIsRecursive, isfull); - AdjustFolderStatus(statuskind); + auto err = GetDirStatus(sProjectRoot, sSubPath, &status.status, isfull, bIsRecursive, isfull); + AdjustFolderStatus(status.status); + return err; } - else - err = GetFileStatus(sProjectRoot, sSubPath, &statuskind, isfull, isfull, assumeValid, skipWorktree); - return statuskind; + return GetFileStatus(sProjectRoot, sSubPath, status, isfull, isfull); } #endif @@ -150,7 +144,7 @@ void GitStatus::GetStatus(const CTGitPath& path, bool /*update*/ /* = false */, AdjustFolderStatus(m_status.status); } else - err = GetFileStatus(sProjectRoot, lpszSubPath, &m_status.status, isfull, !noignore, &m_status.assumeValid, &m_status.skipWorktree); + err = GetFileStatus(sProjectRoot, lpszSubPath, m_status, isfull, !noignore); // Error present if function is not under version control if (err) @@ -165,32 +159,27 @@ void GitStatus::GetStatus(const CTGitPath& path, bool /*update*/ /* = false */, typedef CComCritSecLock CAutoLocker; -int GitStatus::GetFileStatus(const CString& gitdir, CString path, git_wc_status_kind* status, BOOL IsFull, BOOL IsIgnore, bool* assumeValid, bool* skipWorktree, bool update) +int GitStatus::GetFileStatus(const CString& gitdir, CString path, git_wc_status2_t& status, BOOL IsFull, BOOL IsIgnore, bool update) { - ATLASSERT(status); + ATLASSERT(!status.assumeValid && !status.skipWorktree); path.Replace(L'\\', L'/'); - git_wc_status_kind st = git_wc_status_none; - CGitHash hash; - if (update) g_IndexFileMap.CheckAndUpdate(gitdir); auto pIndex = g_IndexFileMap.SafeGet(gitdir); - if (!pIndex || pIndex->GetFileStatus(gitdir, path, &st, &hash, assumeValid, skipWorktree)) + CGitHash hash; + if (!pIndex || pIndex->GetFileStatus(gitdir, path, status, &hash)) { // git working tree has broken index or an error occurred in GetFileStatus - *status = git_wc_status_none; + status.status = git_wc_status_none; return -1; } - if (st == git_wc_status_conflicted) - { - *status = st; + if (status.status == git_wc_status_conflicted) return 0; - } - if (st == git_wc_status_unversioned) + if (status.status == git_wc_status_unversioned) { if (IsFull) { @@ -202,33 +191,32 @@ int GitStatus::GetFileStatus(const CString& gitdir, CString path, git_wc_status_ // broken HEAD if (!treeptr) { - *status = git_wc_status_none; + status.status = git_wc_status_none; return -1; } // deleted only in index item? if (SearchInSortVector(*treeptr, path, -1) != NPOS) { - *status = git_wc_status_deleted; + status.status = git_wc_status_deleted; return 0; } } if (!IsIgnore) { - *status = git_wc_status_unversioned; + status.status = git_wc_status_unversioned; return 0; } g_IgnoreList.CheckAndUpdateIgnoreFiles(gitdir, path, false); if (g_IgnoreList.IsIgnore(path, gitdir, false)) - st = git_wc_status_ignored; + status.status = git_wc_status_ignored; - *status = st; return 0; } - if ((st == git_wc_status_normal || st == git_wc_status_modified) && IsFull) + if ((status.status == git_wc_status_normal || status.status == git_wc_status_modified) && IsFull) { if (update) g_HeadFileMap.CheckHeadAndUpdate(gitdir); @@ -238,7 +226,7 @@ int GitStatus::GetFileStatus(const CString& gitdir, CString path, git_wc_status_ // broken HEAD if (!treeptr) { - *status = git_wc_status_none; + status.status = git_wc_status_none; return -1; } @@ -246,19 +234,19 @@ int GitStatus::GetFileStatus(const CString& gitdir, CString path, git_wc_status_ size_t start = SearchInSortVector(*treeptr, path, -1); if (start == NPOS) { - *status = st = git_wc_status_added; + status.status = git_wc_status_added; CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": File miss in head tree %s", (LPCTSTR)path); return 0; } // staged and not commit - if (!assumeValid && !skipWorktree &&(*treeptr)[start].m_Hash != hash) + if (!status.assumeValid && !status.skipWorktree && (*treeptr)[start].m_Hash != hash) { - *status = st = git_wc_status_modified; + status.status = git_wc_status_modified; return 0; } } - *status = st; + return 0; } @@ -370,45 +358,51 @@ int GitStatus::EnumDirStatus(const CString& gitdir, const CString& subpath, git_ size_t pos = SearchInSortVector(*indexptr, onepath, matchLength); size_t posintree = SearchInSortVector(*treeptr, onepath, matchLength); + git_wc_status2_t status = { git_wc_status_none, false, false }; + if (pos == NPOS && posintree == NPOS) { - git_wc_status_kind filestatus = git_wc_status_unversioned; + status.status = git_wc_status_unversioned; g_IgnoreList.CheckAndUpdateIgnoreFiles(gitdir, onepath, bIsDir); if (g_IgnoreList.IsIgnore(onepath, gitdir, bIsDir)) - filestatus = git_wc_status_ignored; + status.status = git_wc_status_ignored; - callback(CombinePath(gitdir, onepath), filestatus, bIsDir, fileentry.m_LastModified, pData, false, false); + callback(CombinePath(gitdir, onepath), &status, bIsDir, fileentry.m_LastModified, pData); } else if (pos == NPOS && posintree != NPOS) /* check if file delete in index */ - callback(CombinePath(gitdir, onepath), git_wc_status_deleted, bIsDir, fileentry.m_LastModified, pData, false, false); + { + status.status = git_wc_status_deleted; + callback(CombinePath(gitdir, onepath), &status, bIsDir, fileentry.m_LastModified, pData); + } else if (pos != NPOS && posintree == NPOS) /* Check if file added */ { - git_wc_status_kind filestatus = git_wc_status_added; + status.status = git_wc_status_added; if ((*indexptr)[pos].m_Flags & GIT_IDXENTRY_STAGEMASK) - filestatus = git_wc_status_conflicted; - callback(CombinePath(gitdir, onepath), filestatus, bIsDir, fileentry.m_LastModified, pData, false, false); + status.status = git_wc_status_conflicted; + callback(CombinePath(gitdir, onepath), &status, bIsDir, fileentry.m_LastModified, pData); } else { if (bIsDir) - callback(CombinePath(gitdir, onepath), git_wc_status_normal, bIsDir, fileentry.m_LastModified, pData, false, false); + { + status.status = git_wc_status_normal; + callback(CombinePath(gitdir, onepath), &status, bIsDir, fileentry.m_LastModified, pData); + } else { auto& indexentry = (*indexptr)[pos]; if (indexentry.m_Flags & GIT_IDXENTRY_STAGEMASK) { - callback(CombinePath(gitdir, onepath), git_wc_status_conflicted, false, fileentry.m_LastModified, pData, false, false); + status.status = git_wc_status_conflicted; + callback(CombinePath(gitdir, onepath), &status, false, fileentry.m_LastModified, pData); continue; } - bool assumeValid = false; - bool skipWorktree = false; - git_wc_status_kind filestatus; - if ((*indexptr).GetFileStatus(repository, gitdir, indexentry, &filestatus, CGit::filetime_to_time_t(fileentry.m_LastModified), fileentry.m_Size, &assumeValid, &skipWorktree)) + if ((*indexptr).GetFileStatus(repository, gitdir, indexentry, status, CGit::filetime_to_time_t(fileentry.m_LastModified), fileentry.m_Size)) return -1; - if (filestatus == git_wc_status_normal && !assumeValid && !skipWorktree && (*treeptr)[posintree].m_Hash != indexentry.m_IndexHash) - filestatus = git_wc_status_modified; - callback(CombinePath(gitdir, onepath), filestatus, false, fileentry.m_LastModified, pData, assumeValid, skipWorktree); + if (status.status == git_wc_status_normal && !status.assumeValid && !status.skipWorktree && (*treeptr)[posintree].m_Hash != indexentry.m_IndexHash) + status.status = git_wc_status_modified; + callback(CombinePath(gitdir, onepath), &status, false, fileentry.m_LastModified, pData); } } }/*End of For*/ @@ -441,18 +435,17 @@ int GitStatus::EnumDirStatus(const CString& gitdir, const CString& subpath, git_ bool isDir = filename[length - 1] == L'/'; if (SearchInSortVector(filelist, filename, isDir ? length : -1) == NPOS) // do full match for filenames and only prefix-match ending with "/" for folders { - bool skipWorktree = false; - git_wc_status_kind filestatus = (!isDir || IsDirectSubmodule(entry.m_FileName, commonPrefixLength)) ? git_wc_status_deleted : git_wc_status_modified; // only report deleted submodules and files as deletedy + git_wc_status2_t status = { (!isDir || IsDirectSubmodule(entry.m_FileName, commonPrefixLength)) ? git_wc_status_deleted : git_wc_status_modified, false, false }; // only report deleted submodules and files as deletedy if ((entry.m_FlagsExtended & GIT_IDXENTRY_SKIP_WORKTREE) != 0) { - skipWorktree = true; - filestatus = git_wc_status_normal; + status.skipWorktree = true; + status.status = git_wc_status_normal; oldstring.Empty(); // without this a deleted folder which has two versioned files and only the first is skipwoktree flagged gets reported as normal if (alreadyReported.find(filename) != alreadyReported.cend()) continue; } alreadyReported.insert(filename); - callback(CombinePath(gitdir, subpath, filename), filestatus, isDir, 0, pData, false, skipWorktree); + callback(CombinePath(gitdir, subpath, filename), &status, isDir, 0, pData); } } } @@ -481,7 +474,10 @@ int GitStatus::EnumDirStatus(const CString& gitdir, const CString& subpath, git_ int length = filename.GetLength(); bool isDir = filename[length - 1] == L'/'; if (SearchInSortVector(filelist, filename, isDir ? length : -1) == NPOS) // do full match for filenames and only prefix-match ending with "/" for folders - callback(CombinePath(gitdir, subpath, filename), (!isDir || IsDirectSubmodule(entry.m_FileName, commonPrefixLength)) ? git_wc_status_deleted : git_wc_status_modified, isDir, 0, pData, false, false); + { + git_wc_status2_t status = { (!isDir || IsDirectSubmodule(entry.m_FileName, commonPrefixLength)) ? git_wc_status_deleted : git_wc_status_modified, false, false }; + callback(CombinePath(gitdir, subpath, filename), &status, isDir, 0, pData); + } } } } @@ -658,17 +654,15 @@ int GitStatus::GetDirStatus(const CString& gitdir, const CString& subpath, git_w if (!IsRecursive && indexentry.m_FileName.Find(L'/', path.GetLength()) > 0 && !IsDirectSubmodule(indexentry.m_FileName, path.GetLength())) continue; - git_wc_status_kind filestatus = git_wc_status_none; - bool assumeValid = false; - bool skipWorktree = false; - GetFileStatus(gitdir, indexentry.m_FileName, &filestatus, IsFul, IsIgnore, &assumeValid, &skipWorktree, false); - switch (filestatus) + git_wc_status2_t filestatus = { git_wc_status_none, false, false }; + GetFileStatus(gitdir, indexentry.m_FileName, filestatus, IsFul, IsIgnore, false); + switch (filestatus.status) { case git_wc_status_added: case git_wc_status_modified: case git_wc_status_deleted: //case git_wc_status_conflicted: cannot happen, we exit as soon we found a conflict in subpath - *status = GetMoreImportant(filestatus, *status); + *status = GetMoreImportant(filestatus.status, *status); AdjustFolderStatus(*status); if (mostImportantPossibleFolderStatus == *status) return 0; diff --git a/src/Git/GitStatus.h b/src/Git/GitStatus.h index df51040a6..58093c4af 100644 --- a/src/Git/GitStatus.h +++ b/src/Git/GitStatus.h @@ -48,7 +48,7 @@ typedef struct git_wc_status2_t #define MAX_STATUS_STRING_LENGTH 256 -typedef BOOL (*FILL_STATUS_CALLBACK)(const CString& path, git_wc_status_kind status, bool isDir, __int64 lastwritetime, void *pdata, bool assumeValid, bool skipWorktree); +typedef BOOL (*FILL_STATUS_CALLBACK)(const CString& path, const git_wc_status2_t* status, bool isDir, __int64 lastwritetime, void* baton); static CString CombinePath(const CString& part1, const CString& part2) { @@ -76,7 +76,7 @@ class GitStatus { public: - static int GetFileStatus(const CString& gitdir, CString path, git_wc_status_kind* status, BOOL IsFull = FALSE, BOOL isIgnore = TRUE, bool* assumeValid = nullptr, bool* skipWorktree = nullptr, bool update = true); + static int GetFileStatus(const CString& gitdir, CString path, git_wc_status2_t& status, BOOL IsFull = FALSE, BOOL isIgnore = TRUE, bool update = true); static int GetDirStatus(const CString& gitdir, const CString& path, git_wc_status_kind* status, BOOL IsFull = false, BOOL IsRecursive = false, BOOL isIgnore = true); static int EnumDirStatus(const CString& gitdir, const CString& path, git_wc_status_kind* dirstatus, FILL_STATUS_CALLBACK callback, void* pData); static int GetFileList(CString path, std::vector& list, bool& isRepoRoot); @@ -95,7 +95,7 @@ public: * If the status of the text and property part are different * then the more important status is returned. */ - static git_wc_status_kind GetAllStatus(const CTGitPath& path, bool bIsRecursive, bool* assumeValid = nullptr, bool* skipWorktree = nullptr); + static int GetAllStatus(const CTGitPath& path, bool bIsRecursive, git_wc_status2_t& status); /** * Returns the status which is more "important" of the two statuses specified. diff --git a/src/Git/gitindex.h b/src/Git/gitindex.h index 32e991a80..5322c242e 100644 --- a/src/Git/gitindex.h +++ b/src/Git/gitindex.h @@ -49,15 +49,15 @@ public: ~CGitIndexList(); int ReadIndex(CString dotgitdir); - int GetFileStatus(const CString& gitdir, CString path, git_wc_status_kind* status, CGitHash* pHash = nullptr, bool* assumeValid = nullptr, bool* skipWorktree = nullptr); - int GetFileStatus(CAutoRepository& repository, const CString& gitdir, CGitIndex& entry, git_wc_status_kind* status, __int64 time, __int64 filesize, bool* assumeValid, bool* skipWorktree); + int GetFileStatus(const CString& gitdir, CString path, git_wc_status2_t& status, CGitHash* pHash = nullptr); + int GetFileStatus(CAutoRepository& repository, const CString& gitdir, CGitIndex& entry, git_wc_status2_t& status, __int64 time, __int64 filesize); #ifdef GTEST_INCLUDE_GTEST_GTEST_H_ FRIEND_TEST(GitIndexCBasicGitWithTestRepoFixture, GetFileStatus); #endif protected: __int64 m_iMaxCheckSize; CAutoConfig config; - int GetFileStatus(const CString& gitdir, const CString& path, git_wc_status_kind* status, __int64 time, __int64 filesize, CGitHash* pHash = nullptr, bool* assumeValid = nullptr, bool* skipWorktree = nullptr); + int GetFileStatus(const CString& gitdir, const CString& path, git_wc_status2_t& status, __int64 time, __int64 filesize, CGitHash* pHash = nullptr); }; typedef std::shared_ptr SHARED_INDEX_PTR; diff --git a/src/TGitCache/CachedDirectory.cpp b/src/TGitCache/CachedDirectory.cpp index 283908677..162dbbd1d 100644 --- a/src/TGitCache/CachedDirectory.cpp +++ b/src/TGitCache/CachedDirectory.cpp @@ -370,10 +370,8 @@ int CCachedDirectory::EnumFiles(const CTGitPath& path, CString sProjectRoot, con if (!path.IsDirectory()) { - bool assumeValid = false; - bool skipWorktree = false; - git_wc_status_kind status = git_wc_status_none; - if (pStatus->GetFileStatus(sProjectRoot, sSubPath, &status, TRUE, true, &assumeValid, &skipWorktree)) + git_wc_status2_t status = { git_wc_status_none, false, false }; + if (pStatus->GetFileStatus(sProjectRoot, sSubPath, status, TRUE, true)) { // we could not get the status of a file, try whole directory after a short delay if the whole directory was not already crawled with an error if (m_currentFullStatus == git_wc_status_none) @@ -382,7 +380,7 @@ int CCachedDirectory::EnumFiles(const CTGitPath& path, CString sProjectRoot, con CGitStatusCache::Instance().AddFolderForCrawling(m_directoryPath); return 0; } - GetStatusCallback(path.GetWinPathString(), status, false, path.GetLastWriteTime(), this, assumeValid, skipWorktree); + GetStatusCallback(path.GetWinPathString(), &status, false, path.GetLastWriteTime(), this); RefreshMostImportant(false); } else @@ -470,11 +468,8 @@ CCachedDirectory::GetFullPathString(const CString& cacheKey) return fullpath; } -BOOL CCachedDirectory::GetStatusCallback(const CString& path, git_wc_status_kind status, bool isDir, __int64 lastwritetime, void* baton, bool assumeValid, bool skipWorktree) +BOOL CCachedDirectory::GetStatusCallback(const CString& path, const git_wc_status2_t* pGitStatus, bool isDir, __int64 lastwritetime, void* baton) { - git_wc_status2_t _status = { status, assumeValid, skipWorktree }; - git_wc_status2_t *status2 = &_status; - CTGitPath gitPath(path, isDir); auto pThis = reinterpret_cast(baton); @@ -488,14 +483,14 @@ BOOL CCachedDirectory::GetStatusCallback(const CString& path, git_wc_status_kind if (pThis->m_bRecursive) { // Add any versioned directory, which is not our 'self' entry, to the list for having its status updated - if (status >= git_wc_status_normal || (CGitStatusCache::Instance().IsUnversionedAsModified() && status == git_wc_status_unversioned)) + if (pGitStatus->status >= git_wc_status_normal || (CGitStatusCache::Instance().IsUnversionedAsModified() && pGitStatus->status == git_wc_status_unversioned)) CGitStatusCache::Instance().AddFolderForCrawling(gitPath); } // deleted subfolders are reported as modified whereas deleted submodules are reported as deleted - if (status == git_wc_status_deleted || status == git_wc_status_modified) + if (pGitStatus->status == git_wc_status_deleted || pGitStatus->status == git_wc_status_modified) { - pThis->SetChildStatus(gitPath.GetWinPathString(), status); + pThis->SetChildStatus(gitPath.GetWinPathString(), pGitStatus->status); return FALSE; } @@ -507,7 +502,7 @@ BOOL CCachedDirectory::GetStatusCallback(const CString& path, git_wc_status_kind } } - pThis->AddEntry(gitPath, status2, lastwritetime); + pThis->AddEntry(gitPath, pGitStatus, lastwritetime); return FALSE; } diff --git a/src/TGitCache/CachedDirectory.h b/src/TGitCache/CachedDirectory.h index 0b9fd3b12..df299589f 100644 --- a/src/TGitCache/CachedDirectory.h +++ b/src/TGitCache/CachedDirectory.h @@ -64,7 +64,7 @@ private: CStatusCacheEntry GetStatusFromCache(const CTGitPath &path, bool bRecursive); CStatusCacheEntry GetStatusFromGit(const CTGitPath &path, const CString& sProjectRoot, bool isSelf); - static BOOL GetStatusCallback(const CString& path, git_wc_status_kind status, bool isDir, __int64 lastwritetime, void* /*pUserData*/, bool assumeValid, bool skipWorktree); + static BOOL GetStatusCallback(const CString& path, const git_wc_status2_t* status, bool isDir, __int64 lastwritetime, void* baton); void AddEntry(const CTGitPath& path, const git_wc_status2_t* pGitStatus, __int64 lastwritetime); CString GetCacheKey(const CTGitPath& path); CString GetFullPathString(const CString& cacheKey); diff --git a/test/UnitTests/GitIndexTest.cpp b/test/UnitTests/GitIndexTest.cpp index 251e18a7f..687df2949 100644 --- a/test/UnitTests/GitIndexTest.cpp +++ b/test/UnitTests/GitIndexTest.cpp @@ -184,35 +184,37 @@ TEST_P(GitIndexCBasicGitWithTestRepoFixture, GetFileStatus) CGitIndexList indexList; ReadAndCheckIndex(indexList, m_Dir.GetTempDir()); - git_wc_status_kind status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"does-not-exist.txt", &status, 10, 20)); - EXPECT_EQ(git_wc_status_unversioned, status); + git_wc_status2_t status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"does-not-exist.txt", status, 10, 20)); + EXPECT_EQ(git_wc_status_unversioned, status.status); __int64 time = -1; __int64 filesize = -1; - status = git_wc_status_none; - bool skipworktree = false; + status = { git_wc_status_none, false, false }; EXPECT_EQ(-1, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"ansi.txt"), &time, nullptr, &filesize)); - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_deleted, status); + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_deleted, status.status); filesize = 42; // some arbitrary size, i.e., file exists but is changed - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_modified, status); + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_modified, status.status); CString output; EXPECT_EQ(0, m_Git.Run(L"git.exe reset --hard", &output, CP_UTF8)); EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"ansi.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_normal, status); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_normal, status.status); + EXPECT_FALSE(status.assumeValid); + EXPECT_FALSE(status.skipWorktree); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(CombinePath(m_Dir.GetTempDir(), L"ansi.txt"), L"this is testing file.")); EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"ansi.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize, nullptr, nullptr, &skipworktree)); - EXPECT_EQ(git_wc_status_modified, status); - EXPECT_FALSE(skipworktree); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_modified, status.status); + EXPECT_FALSE(status.assumeValid); + EXPECT_FALSE(status.skipWorktree); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(CombinePath(m_Dir.GetTempDir(), L"just-added.txt"), L"this is testing file.")); EXPECT_EQ(0, m_Git.Run(L"git.exe add -- just-added.txt", &output, CP_UTF8)); @@ -223,29 +225,32 @@ TEST_P(GitIndexCBasicGitWithTestRepoFixture, GetFileStatus) EXPECT_EQ(0, m_Git.Run(L"git.exe update-index --skip-worktree -- ansi.txt", &output, CP_UTF8)); EXPECT_EQ(0, indexList.ReadIndex(m_Dir.GetTempDir())); EXPECT_FALSE(indexList.m_bHasConflicts); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize, nullptr, nullptr, &skipworktree)); - EXPECT_EQ(git_wc_status_normal, status); - EXPECT_TRUE(skipworktree); - + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_normal, status.status); + EXPECT_FALSE(status.assumeValid); + EXPECT_TRUE(status.skipWorktree); + EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"just-added.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"just-added.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_normal, status); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"just-added.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_normal, status.status); EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"noted-as-added.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"noted-as-added.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_added, status); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"noted-as-added.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_added, status.status); + EXPECT_FALSE(status.assumeValid); + EXPECT_FALSE(status.skipWorktree); EXPECT_EQ(0, m_Git.Run(L"git.exe update-index --no-skip-worktree ansi.txt", &output, CP_UTF8)); Sleep(1000); EXPECT_TRUE(CStringUtils::WriteStringToTextFile(CombinePath(m_Dir.GetTempDir(), L"just-added.txt"), L"this IS testing file.")); EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"just-added.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"just-added.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_modified, status); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"just-added.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_modified, status.status); output.Empty(); EXPECT_EQ(0, m_Git.Run(L"git.exe checkout --force forconflict", &output, CP_UTF8)); @@ -260,9 +265,9 @@ TEST_P(GitIndexCBasicGitWithTestRepoFixture, GetFileStatus) EXPECT_TRUE(indexList.m_bHasConflicts); EXPECT_EQ(0, CGit::GetFileModifyTime(CombinePath(m_Dir.GetTempDir(), L"ansi.txt"), &time, nullptr, &filesize)); - status = git_wc_status_none; - EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", &status, time, filesize)); - EXPECT_EQ(git_wc_status_conflicted, status); + status = { git_wc_status_none, false, false }; + EXPECT_EQ(0, indexList.GetFileStatus(m_Dir.GetTempDir(), L"ansi.txt", status, time, filesize)); + EXPECT_EQ(git_wc_status_conflicted, status.status); } TEST(GitIndex, SearchInSortVector) -- 2.11.4.GIT