From 089496e01730f3bdb42471b3b9d2b1c2d76f5fbd Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Fri, 25 Jul 2014 14:35:27 +0200 Subject: [PATCH] TGitCache: Do not hash files with file size greater than 10 MiB (fixes issue #2240) Signed-off-by: Sven Strickroth Signed-off-by: Sup Yut Sum --- src/Changelog.txt | 6 ++++++ src/Git/Git.h | 5 ++++- src/Git/GitIndex.cpp | 14 +++++++------- src/Git/gitindex.h | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Changelog.txt b/src/Changelog.txt index 6aceb4d9d..d9d4ac29a 100644 --- a/src/Changelog.txt +++ b/src/Changelog.txt @@ -23,6 +23,12 @@ Released: unreleased * Fixed issue #2234: Config file mess up if not end with LF * Fixed issue #2238: TortoiseGitMerge Default button in "Find" dialog does replace all * Fixed issue #2250: bugtraq.logregex Test incorrectly saves the order of the fields + * TGitCache now does not check the contents of files with filesize > 10 MiB any more + and falls back to checking the timestamp of the files (as if TGitCacheCheckContent + is set to "false") according the the git index. + The reason for this change is that libgit2 reads a file to memory for hashing and, + thus, locking the file and the repository for this time span. + Fixed issue #2240: TGitCache keeps crashing when I look at my folders or commit = Release 1.8.9.0 = Released: 2014-06-09 diff --git a/src/Git/Git.h b/src/Git/Git.h index 75dff2327..50c487189 100644 --- a/src/Git/Git.h +++ b/src/Git/Git.h @@ -356,7 +356,7 @@ public: return (time_t)winTime; } - int GetFileModifyTime(LPCTSTR filename, __int64 *time, bool * isDir=NULL) + int GetFileModifyTime(LPCTSTR filename, __int64* time, bool* isDir = nullptr, __int64* size = nullptr) { WIN32_FILE_ATTRIBUTE_DATA fdata; if (GetFileAttributesEx(filename, GetFileExInfoStandard, &fdata)) @@ -364,6 +364,9 @@ public: if(time) *time = filetime_to_time_t(&fdata.ftLastWriteTime); + if (size) + *size = ((__int64)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow; + if(isDir) *isDir = !!( fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); diff --git a/src/Git/GitIndex.cpp b/src/Git/GitIndex.cpp index 4e1c4fb37..296a633eb 100644 --- a/src/Git/GitIndex.cpp +++ b/src/Git/GitIndex.cpp @@ -122,7 +122,7 @@ int CGitIndexList::ReadIndex(CString dgitdir) return 0; } -int CGitIndexList::GetFileStatus(const CString &gitdir, const CString &pathorg, git_wc_status_kind *status, __int64 time, FILL_STATUS_CALLBACK callback, void *pData, CGitHash *pHash, bool * assumeValid, bool * skipWorktree) +int CGitIndexList::GetFileStatus(const CString &gitdir, const CString &pathorg, git_wc_status_kind *status, __int64 time, __int64 filesize, FILL_STATUS_CALLBACK callback, void *pData, CGitHash *pHash, bool * assumeValid, bool * skipWorktree) { if(status) { @@ -161,7 +161,7 @@ int CGitIndexList::GetFileStatus(const CString &gitdir, const CString &pathorg, { *status = git_wc_status_normal; } - else if (m_bCheckContent && repository) + else if (m_bCheckContent && repository && filesize < 10 * 1024 * 1024) { git_oid actual; CStringA fileA = CUnicodeUtils::GetMulti(pathorg, CP_UTF8); @@ -199,7 +199,7 @@ int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git FILL_STATUS_CALLBACK callback, void *pData, CGitHash *pHash, bool * assumeValid, bool * skipWorktree) { - __int64 time; + __int64 time, filesize = 0; bool isDir = false; CString path = pathParam; @@ -210,7 +210,7 @@ int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git if (path.IsEmpty()) result = g_Git.GetFileModifyTime(gitdir, &time, &isDir); else - result = g_Git.GetFileModifyTime(gitdir + _T("\\") + path, &time, &isDir); + result = g_Git.GetFileModifyTime(gitdir + _T("\\") + path, &time, &isDir, &filesize); if (result) { @@ -245,7 +245,7 @@ int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git } else { - result = g_Git.GetFileModifyTime(gitdir+_T("\\") + at(i).m_FileName, &time); + result = g_Git.GetFileModifyTime(gitdir + _T("\\") + at(i).m_FileName, &time, nullptr, &filesize); if (result) continue; @@ -254,7 +254,7 @@ int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git *assumeValid = false; if (skipWorktree) *skipWorktree = false; - GetFileStatus(gitdir, at(i).m_FileName, status, time, callback, pData, NULL, assumeValid, skipWorktree); + GetFileStatus(gitdir, at(i).m_FileName, status, time, filesize, callback, pData, NULL, assumeValid, skipWorktree); // if a file is assumed valid, we need to inform the caller, otherwise the assumevalid flag might not get to the explorer on first open of a repository if (callback && assumeValid && skipWorktree && (*assumeValid || *skipWorktree)) callback(gitdir + _T("\\") + path, *status, false, pData, *assumeValid, *skipWorktree); @@ -291,7 +291,7 @@ int CGitIndexList::GetStatus(const CString &gitdir,const CString &pathParam, git } else { - GetFileStatus(gitdir, path, status, time, callback, pData, pHash, assumeValid, skipWorktree); + GetFileStatus(gitdir, path, status, time, filesize, callback, pData, pHash, assumeValid, skipWorktree); } } return 0; diff --git a/src/Git/gitindex.h b/src/Git/gitindex.h index 66b39a832..81e7c2725 100644 --- a/src/Git/gitindex.h +++ b/src/Git/gitindex.h @@ -50,7 +50,7 @@ protected: bool m_bCheckContent; CComCriticalSection m_critRepoSec; CAutoRepository repository; - int GetFileStatus(const CString &gitdir, const CString &path, git_wc_status_kind * status, __int64 time, FILL_STATUS_CALLBACK callback = nullptr, void *pData = nullptr, CGitHash *pHash = nullptr, bool * assumeValid = nullptr, bool * skipWorktree = nullptr); + int GetFileStatus(const CString &gitdir, const CString &path, git_wc_status_kind * status, __int64 time, __int64 filesize, FILL_STATUS_CALLBACK callback = nullptr, void *pData = nullptr, CGitHash *pHash = nullptr, bool * assumeValid = nullptr, bool * skipWorktree = nullptr); int GetDirStatus(const CString &gitdir, const CString &path, git_wc_status_kind * status,__int64 time, FILL_STATUS_CALLBACK callback = nullptr, void *pData = nullptr,CGitHash *pHash = nullptr); }; -- 2.11.4.GIT